diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..8449e9d
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+apache-xml_src_files := $(call all-java-files-under,src/main/java)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := apache-xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(apache-xml_src_files)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := core
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_RESOURCE_DIRS := src/main/java
+include $(BUILD_JAVA_LIBRARY)
+
+ifeq ($(WITH_HOST_DALVIK),true)
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := apache-xml-hostdex
+    LOCAL_MODULE_TAGS := optional
+    LOCAL_SRC_FILES := $(apache-xml_src_files)
+    LOCAL_JAVACFLAGS := -encoding UTF-8
+    LOCAL_JAVA_LIBRARIES := core-hostdex
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_BUILD_HOST_DEX := true
+    LOCAL_MODULE_TAGS := optional
+    LOCAL_JAVA_RESOURCE_DIRS := src/main/java
+    include $(BUILD_HOST_JAVA_LIBRARY)
+endif
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..097bafb
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,80 @@
+   =========================================================================
+   ==  NOTICE file corresponding to section 4(d) of the Apache License,   ==
+   ==  Version 2.0, in this case for the Apache Xalan Java distribution.  ==
+   =========================================================================
+
+   Apache Xalan (Xalan XSLT processor)
+   Copyright 1999-2006 The Apache Software Foundation
+
+   Apache Xalan (Xalan serializer)
+   Copyright 1999-2006 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   =========================================================================
+   Portions of this software was originally based on the following:
+     - software copyright (c) 1999-2002, Lotus Development Corporation.,
+       http://www.lotus.com.
+     - software copyright (c) 2001-2002, Sun Microsystems.,
+       http://www.sun.com.
+     - software copyright (c) 2003, IBM Corporation., 
+       http://www.ibm.com.
+       
+   =========================================================================
+   The binary distribution package (ie. jars, samples and documentation) of
+   this product includes software developed by the following:
+       
+     - The Apache Software Foundation 
+         - Xerces Java - see LICENSE.txt 
+         - JAXP 1.3 APIs - see LICENSE.txt
+         - Bytecode Engineering Library - see LICENSE.txt
+         - Regular Expression - see LICENSE.txt
+       
+     - Scott Hudson, Frank Flannery, C. Scott Ananian 
+         - CUP Parser Generator runtime (javacup\runtime) - see LICENSE.txt 
+ 
+   ========================================================================= 
+   The source distribution package (ie. all source and tools required to build
+   Xalan Java) of this product includes software developed by the following:
+       
+     - The Apache Software Foundation
+         - Xerces Java - see LICENSE.txt 
+         - JAXP 1.3 APIs - see LICENSE.txt
+         - Bytecode Engineering Library - see LICENSE.txt
+         - Regular Expression - see LICENSE.txt
+         - Ant - see LICENSE.txt
+         - Stylebook doc tool - see LICENSE.txt    
+       
+     - Elliot Joel Berk and C. Scott Ananian 
+         - Lexical Analyzer Generator (JLex) - see LICENSE.txt
+
+   =========================================================================       
+   Apache Xerces Java
+   Copyright 1999-2006 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Portions of Apache Xerces Java in xercesImpl.jar and xml-apis.jar
+   were originally based on the following:
+     - software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
+     - software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
+     - voluntary contributions made by Paul Eng on behalf of the 
+       Apache Software Foundation that were originally developed at iClick, Inc.,
+       software copyright (c) 1999.    
+
+   =========================================================================   
+   Apache xml-commons xml-apis (redistribution of xml-apis.jar)
+
+   Apache XML Commons
+   Copyright 2001-2003,2006 The Apache Software Foundation.
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Portions of this software were originally based on the following:
+     - software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
+     - software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
+     - software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org
+
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
new file mode 100644
index 0000000..0657faa
--- /dev/null
+++ b/ThirdPartyProject.prop
@@ -0,0 +1,12 @@
+currentVersion=889881,901014
+version=889881,901014
+isNative=false
+name=apache-xml
+keywords=apache xml commons xalan xslt xpath validation
+onDevice=true
+homepage=http://xml.apache.org/xalan-j/
+xalanSvn=http://svn.apache.org/repos/asf/xalan/java/trunk
+xalanSvnRev=889881
+xmlCommonsSvn=http://svn.apache.org/repos/asf/xml/commons/trunk
+xmlCommonsSvnRef=901014
+
diff --git a/src/main/java/org/apache/xalan/Version.java b/src/main/java/org/apache/xalan/Version.java
new file mode 100644
index 0000000..23e8fbe
--- /dev/null
+++ b/src/main/java/org/apache/xalan/Version.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Version.java 577939 2007-09-20 21:45:37Z minchau $
+ */
+package org.apache.xalan;
+
+/**
+ * Administrative class to keep track of the version number of
+ * the Xalan release.
+ * <P>This class implements the upcoming standard of having
+ * org.apache.project-name.Version.getVersion() be a standard way 
+ * to get version information.  This class will replace the older 
+ * org.apache.xalan.processor.Version class.</P>
+ * <P>See also: org/apache/xalan/res/XSLTInfo.properties for 
+ * information about the version of the XSLT spec we support.</P>
+ * @xsl.usage general
+ */
+public class Version
+{
+
+  /**
+   * Get the basic version string for the current Xalan release.
+   * Version String formatted like 
+   * <CODE>"<B>Xalan</B> <B>Java</B> v.r[.dd| <B>D</B>nn]"</CODE>.
+   *
+   * Futurework: have this read version info from jar manifest.
+   *
+   * @return String denoting our current version
+   */
+  public static String getVersion()
+  {
+     return getProduct()+" "+getImplementationLanguage()+" "
+           +getMajorVersionNum()+"."+getReleaseVersionNum()+"."
+           +( (getDevelopmentVersionNum() > 0) ? 
+               ("D"+getDevelopmentVersionNum()) : (""+getMaintenanceVersionNum()));  
+  }
+
+  /**
+   * Print the processor version to the command line.
+   *
+   * @param argv command line arguments, unused.
+   */
+  public static void main(String argv[])
+  {
+    System.out.println(getVersion());
+  }
+  
+  /**
+   * Name of product: Xalan.
+   */
+  public static String getProduct()
+  {
+    return "Xalan";
+  }
+
+  /**
+   * Implementation Language: Java.
+   */
+  public static String getImplementationLanguage()
+  {
+    return "Java";
+  }
+  
+  
+  /**
+   * Major version number.
+   * Version number. This changes only when there is a
+   *          significant, externally apparent enhancement from
+   *          the previous release. 'n' represents the n'th
+   *          version.
+   *
+   *          Clients should carefully consider the implications
+   *          of new versions as external interfaces and behaviour
+   *          may have changed.
+   */
+  public static int getMajorVersionNum()
+  {
+    return 2;
+    
+  }  
+
+  /**
+   * Release Number.
+   * Release number. This changes when:
+   *            -  a new set of functionality is to be added, eg,
+   *               implementation of a new W3C specification.
+   *            -  API or behaviour change.
+   *            -  its designated as a reference release.
+   */
+  public static int getReleaseVersionNum()
+  {
+    return 7;
+  }
+  
+  /**
+   * Maintenance Drop Number.
+   * Optional identifier used to designate maintenance
+   *          drop applied to a specific release and contains
+   *          fixes for defects reported. It maintains compatibility
+   *          with the release and contains no API changes.
+   *          When missing, it designates the final and complete
+   *          development drop for a release.
+   */
+  public static int getMaintenanceVersionNum()
+  {
+    return 1;
+  }
+
+  /**
+   * Development Drop Number.
+   * Optional identifier designates development drop of
+   *          a specific release. D01 is the first development drop
+   *          of a new release.
+   *
+   *          Development drops are works in progress towards a
+   *          compeleted, final release. A specific development drop
+   *          may not completely implement all aspects of a new
+   *          feature, which may take several development drops to
+   *          complete. At the point of the final drop for the
+   *          release, the D suffix will be omitted.
+   *
+   *          Each 'D' drops can contain functional enhancements as
+   *          well as defect fixes. 'D' drops may not be as stable as
+   *          the final releases.
+   */
+  public static int getDevelopmentVersionNum()
+  { 
+    try {   
+        if ((new String("")).length() == 0)
+          return 0;
+        else  
+          return Integer.parseInt("");
+    } catch (NumberFormatException nfe) {
+           return 0;
+    }    
+  }      
+}
diff --git a/src/main/java/org/apache/xalan/Version.src b/src/main/java/org/apache/xalan/Version.src
new file mode 100644
index 0000000..f1fb77e
--- /dev/null
+++ b/src/main/java/org/apache/xalan/Version.src
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xalan;
+
+/**
+ * Administrative class to keep track of the version number of
+ * the Xalan release.
+ * <P>This class implements the upcoming standard of having
+ * org.apache.project-name.Version.getVersion() be a standard way 
+ * to get version information.  This class will replace the older 
+ * org.apache.xalan.processor.Version class.</P>
+ * <P>See also: org/apache/xalan/res/XSLTInfo.properties for 
+ * information about the version of the XSLT spec we support.</P>
+ * @xsl.usage general
+ */
+public class Version
+{
+
+  /**
+   * Get the basic version string for the current Xalan release.
+   * Version String formatted like 
+   * <CODE>"<B>Xalan</B> <B>Java</B> v.r[.dd| <B>D</B>nn]"</CODE>.
+   *
+   * Futurework: have this read version info from jar manifest.
+   *
+   * @return String denoting our current version
+   */
+  public static String getVersion()
+  {
+     return getProduct()+" "+getImplementationLanguage()+" "
+           +getMajorVersionNum()+"."+getReleaseVersionNum()+"."
+           +( (getDevelopmentVersionNum() > 0) ? 
+               ("D"+getDevelopmentVersionNum()) : (""+getMaintenanceVersionNum()));  
+  }
+
+  /**
+   * Print the processor version to the command line.
+   *
+   * @param argv command line arguments, unused.
+   */
+  public static void main(String argv[])
+  {
+    System.out.println(getVersion());
+  }
+  
+  /**
+   * Name of product: Xalan.
+   */
+  public static String getProduct()
+  {
+    return "Xalan";
+  }
+
+  /**
+   * Implementation Language: Java.
+   */
+  public static String getImplementationLanguage()
+  {
+    return "Java";
+  }
+  
+  
+  /**
+   * Major version number.
+   * Version number. This changes only when there is a
+   *          significant, externally apparent enhancement from
+   *          the previous release. 'n' represents the n'th
+   *          version.
+   *
+   *          Clients should carefully consider the implications
+   *          of new versions as external interfaces and behaviour
+   *          may have changed.
+   */
+  public static int getMajorVersionNum()
+  {
+    return @version.VERSION@;
+    
+  }  
+
+  /**
+   * Release Number.
+   * Release number. This changes when:
+   *            -  a new set of functionality is to be added, eg,
+   *               implementation of a new W3C specification.
+   *            -  API or behaviour change.
+   *            -  its designated as a reference release.
+   */
+  public static int getReleaseVersionNum()
+  {
+    return @version.RELEASE@;
+  }
+  
+  /**
+   * Maintenance Drop Number.
+   * Optional identifier used to designate maintenance
+   *          drop applied to a specific release and contains
+   *          fixes for defects reported. It maintains compatibility
+   *          with the release and contains no API changes.
+   *          When missing, it designates the final and complete
+   *          development drop for a release.
+   */
+  public static int getMaintenanceVersionNum()
+  {
+    return @version.MINOR@;
+  }
+
+  /**
+   * Development Drop Number.
+   * Optional identifier designates development drop of
+   *          a specific release. D01 is the first development drop
+   *          of a new release.
+   *
+   *          Development drops are works in progress towards a
+   *          compeleted, final release. A specific development drop
+   *          may not completely implement all aspects of a new
+   *          feature, which may take several development drops to
+   *          complete. At the point of the final drop for the
+   *          release, the D suffix will be omitted.
+   *
+   *          Each 'D' drops can contain functional enhancements as
+   *          well as defect fixes. 'D' drops may not be as stable as
+   *          the final releases.
+   */
+  public static int getDevelopmentVersionNum()
+  { 
+    try {   
+        if ((new String("@version.DEVELOPER@")).length() == 0)
+          return 0;
+        else  
+          return Integer.parseInt("@version.DEVELOPER@");
+    } catch (NumberFormatException nfe) {
+           return 0;
+    }    
+  }      
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExpressionContext.java b/src/main/java/org/apache/xalan/extensions/ExpressionContext.java
new file mode 100644
index 0000000..b40bb9a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExpressionContext.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExpressionContext.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import javax.xml.transform.ErrorListener;
+
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * An object that implements this interface can supply
+ * information about the current XPath expression context.
+ */
+public interface ExpressionContext
+{
+
+  /**
+   * Get the current context node.
+   * @return The current context node.
+   */
+  public Node getContextNode();
+
+  /**
+   * Get the current context node list.
+   * @return An iterator for the current context list, as
+   * defined in XSLT.
+   */
+  public NodeIterator getContextNodes();
+  
+  /**
+   * Get the error listener.
+   * @return The registered error listener.
+   */
+  public ErrorListener getErrorListener();
+
+  /**
+   * Get the value of a node as a number.
+   * @param n Node to be converted to a number.  May be null.
+   * @return value of n as a number.
+   */
+  public double toNumber(Node n);
+
+  /**
+   * Get the value of a node as a string.
+   * @param n Node to be converted to a string.  May be null.
+   * @return value of n as a string, or an empty string if n is null.
+   */
+  public String toString(Node n);
+
+  /**
+   * Get a variable based on it's qualified name.
+   *
+   * @param qname The qualified name of the variable.
+   *
+   * @return The evaluated value of the variable.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject getVariableOrParam(org.apache.xml.utils.QName qname)
+            throws javax.xml.transform.TransformerException;
+  
+  /**
+   * Get the XPathContext that owns this ExpressionContext.
+   * 
+   * Note: exslt:function requires the XPathContext to access
+   * the variable stack and TransformerImpl.
+   * 
+   * @return The current XPathContext.
+   * @throws javax.xml.transform.TransformerException
+   */
+  public org.apache.xpath.XPathContext getXPathContext()
+            throws javax.xml.transform.TransformerException;
+
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExpressionVisitor.java b/src/main/java/org/apache/xalan/extensions/ExpressionVisitor.java
new file mode 100644
index 0000000..cd895df
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExpressionVisitor.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExpressionVisitor.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.FuncExtFunctionAvailable;
+import org.apache.xpath.functions.Function;
+
+/**
+ * When {@link org.apache.xalan.processor.StylesheetHandler} creates 
+ * an {@link org.apache.xpath.XPath}, the ExpressionVisitor
+ * visits the XPath expression. For any extension functions it 
+ * encounters, it instructs StylesheetRoot to register the
+ * extension namespace. 
+ * 
+ * This mechanism is required to locate extension functions
+ * that may be embedded within an expression.
+ */
+public class ExpressionVisitor extends XPathVisitor
+{
+  private StylesheetRoot m_sroot;
+  
+  /**
+   * The constructor sets the StylesheetRoot variable which
+   * is used to register extension namespaces.
+   * @param sroot the StylesheetRoot that is being constructed.
+   */
+  public ExpressionVisitor (StylesheetRoot sroot)
+  {
+    m_sroot = sroot;
+  }
+  
+  /**
+   * If the function is an extension function, register the namespace.
+   * 
+   * @param owner The current XPath object that owns the expression.
+   * @param func The function currently being visited.
+   * 
+   * @return true to continue the visit in the subtree, if any.
+   */
+  public boolean visitFunction(ExpressionOwner owner, Function func)
+  {
+    if (func instanceof FuncExtFunction)
+    {
+      String namespace = ((FuncExtFunction)func).getNamespace();
+      m_sroot.getExtensionNamespacesManager().registerExtension(namespace);      
+    }
+    else if (func instanceof FuncExtFunctionAvailable)
+    {
+      String arg = ((FuncExtFunctionAvailable)func).getArg0().toString();
+      if (arg.indexOf(":") > 0)
+      {
+      	String prefix = arg.substring(0,arg.indexOf(":"));
+      	String namespace = this.m_sroot.getNamespaceForPrefix(prefix);
+      	m_sroot.getExtensionNamespacesManager().registerExtension(namespace);
+      }
+    }
+    return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExtensionHandler.java b/src/main/java/org/apache/xalan/extensions/ExtensionHandler.java
new file mode 100644
index 0000000..9c46e8a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExtensionHandler.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtensionHandler.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.functions.FuncExtFunction;
+
+/**
+ * Abstract base class for handling an extension namespace for XPath.
+ * Provides functions to test a function's existence and call a function.
+ * Also provides functions for calling an element and testing for
+ * an element's existence.
+ *
+ * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
+ * @xsl.usage internal
+ */
+public abstract class ExtensionHandler
+{
+
+  /** uri of the extension namespace */
+  protected String m_namespaceUri; 
+
+  /** scripting language of implementation */
+  protected String m_scriptLang;
+
+  /**
+   * This method loads a class using the context class loader if we're
+   * running under Java2 or higher.
+   * 
+   * @param className Name of the class to load
+   */
+  static Class getClassForName(String className)
+      throws ClassNotFoundException
+  {
+    // Hack for backwards compatibility with XalanJ1 stylesheets
+    if(className.equals("org.apache.xalan.xslt.extensions.Redirect")) {
+      className = "org.apache.xalan.lib.Redirect";
+    }
+
+    return ObjectFactory.findProviderClass(
+        className, ObjectFactory.findClassLoader(), true);
+  }
+
+  /**
+   * Construct a new extension namespace handler given all the information
+   * needed.
+   *
+   * @param namespaceUri the extension namespace URI that I'm implementing
+   * @param scriptLang   language of code implementing the extension
+   */
+  protected ExtensionHandler(String namespaceUri, String scriptLang)
+  {
+    m_namespaceUri = namespaceUri;
+    m_scriptLang = scriptLang;
+  }
+
+  /**
+   * Tests whether a certain function name is known within this namespace.
+   * @param function name of the function being tested
+   * @return true if its known, false if not.
+   */
+  public abstract boolean isFunctionAvailable(String function);
+
+  /**
+   * Tests whether a certain element name is known within this namespace.
+   * @param element Name of element to check
+   * @return true if its known, false if not.
+   */
+  public abstract boolean isElementAvailable(String element);
+
+  /**
+   * Process a call to a function.
+   *
+   * @param funcName Function name.
+   * @param args     The arguments of the function call.
+   * @param methodKey A key that uniquely identifies this class and method call.
+   * @param exprContext The context in which this expression is being executed.
+   *
+   * @return the return value of the function evaluation.
+   *
+   * @throws TransformerException          if parsing trouble
+   */
+  public abstract Object callFunction(
+    String funcName, Vector args, Object methodKey,
+      ExpressionContext exprContext) throws TransformerException;
+
+  /**
+   * Process a call to a function.
+   *
+   * @param extFunction The XPath extension function.
+   * @param args     The arguments of the function call.
+   * @param exprContext The context in which this expression is being executed.
+   *
+   * @return the return value of the function evaluation.
+   *
+   * @throws TransformerException          if parsing trouble
+   */
+  public abstract Object callFunction(
+    FuncExtFunction extFunction, Vector args,
+      ExpressionContext exprContext) throws TransformerException;
+
+  /**
+   * Process a call to this extension namespace via an element. As a side
+   * effect, the results are sent to the TransformerImpl's result tree.
+   *
+   * @param localPart      Element name's local part.
+   * @param element        The extension element being processed.
+   * @param transformer    Handle to TransformerImpl.
+   * @param stylesheetTree The compiled stylesheet tree.
+   * @param methodKey      A key that uniquely identifies this class and method call.
+   *
+   * @throws XSLProcessorException thrown if something goes wrong
+   *            while running the extension handler.
+   * @throws MalformedURLException if loading trouble
+   * @throws FileNotFoundException if loading trouble
+   * @throws IOException           if loading trouble
+   * @throws TransformerException  if parsing trouble
+   */
+  public abstract void processElement(
+    String localPart, ElemTemplateElement element, TransformerImpl transformer,
+      Stylesheet stylesheetTree, Object methodKey) throws TransformerException, IOException;
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExtensionNamespaceSupport.java b/src/main/java/org/apache/xalan/extensions/ExtensionNamespaceSupport.java
new file mode 100644
index 0000000..8ad232f
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExtensionNamespaceSupport.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtensionNamespaceSupport.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import java.lang.reflect.Constructor;
+
+import javax.xml.transform.TransformerException;
+
+/**
+ * During styleseet composition, an ExtensionNamespaceSupport object is created for each extension 
+ * namespace the stylesheet uses. At the beginning of a transformation, TransformerImpl generates
+ * an ExtensionHandler for each of these objects and adds an entry to the ExtensionsTable hashtable.
+ */
+public class ExtensionNamespaceSupport
+{
+  // Namespace, ExtensionHandler class name, constructor signature 
+  // and arguments.
+  String m_namespace = null;
+  String m_handlerClass = null;
+  Class [] m_sig = null;  
+  Object [] m_args = null;
+ 
+  public ExtensionNamespaceSupport(String namespace, 
+                                   String handlerClass, 
+                                   Object[] constructorArgs)
+  {
+    m_namespace = namespace;
+    m_handlerClass = handlerClass;
+    m_args = constructorArgs;
+    // Create the constructor signature.
+    m_sig = new Class[m_args.length];
+    for (int i = 0; i < m_args.length; i++)
+    {
+      if (m_args[i] != null)
+        m_sig[i] = m_args[i].getClass();//System.out.println("arg class " + i + " " +m_sig[i]);
+      else // If an arguments is null, pick the constructor later.
+      {
+        m_sig = null;
+        break;
+      }
+    }
+  }
+  
+  public String getNamespace()
+  {
+    return m_namespace;
+  }
+  
+  /**
+   * Launch the ExtensionHandler that this ExtensionNamespaceSupport object defines.
+   */
+  public ExtensionHandler launch()
+    throws TransformerException
+  {
+    ExtensionHandler handler = null;
+    try
+    {
+      Class cl = ExtensionHandler.getClassForName(m_handlerClass);
+      Constructor con = null;
+      //System.out.println("class " + cl + " " + m_args + " " + m_args.length + " " + m_sig);
+      if (m_sig != null)
+        con = cl.getConstructor(m_sig);
+      else // Pick the constructor based on number of args.
+      {
+        Constructor[] cons = cl.getConstructors();
+        for (int i = 0; i < cons.length; i ++)
+        {
+          if (cons[i].getParameterTypes().length == m_args.length)
+          {
+            con = cons[i];
+            break;
+          }
+        }
+      }
+      // System.out.println("constructor " + con);
+      if (con != null)
+        handler = (ExtensionHandler)con.newInstance(m_args);
+      else
+        throw new TransformerException("ExtensionHandler constructor not found");
+    }
+    catch (Exception e)
+    {
+      throw new TransformerException(e);
+    }
+    return handler;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExtensionNamespacesManager.java b/src/main/java/org/apache/xalan/extensions/ExtensionNamespacesManager.java
new file mode 100644
index 0000000..867b14c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExtensionNamespacesManager.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtensionNamespacesManager.java 469672 2006-10-31 21:56:19Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import java.util.Vector;
+
+import org.apache.xalan.templates.Constants;
+
+/**
+ * Used during assembly of a stylesheet to collect the information for each 
+ * extension namespace that is required during the transformation process 
+ * to generate an {@link ExtensionHandler}.
+ * 
+ */
+public class ExtensionNamespacesManager
+{
+  /**
+   * Vector of ExtensionNamespaceSupport objects to be used to generate ExtensionHandlers.
+   */
+  private Vector m_extensions = new Vector();
+  /**
+   * Vector of ExtensionNamespaceSupport objects for predefined ExtensionNamespaces. Elements
+   * from this vector are added to the m_extensions vector when encountered in the stylesheet.
+   */
+  private Vector m_predefExtensions = new Vector(7);
+  /**
+   * Vector of extension namespaces for which sufficient information is not yet available to
+   * complete the registration process.
+   */
+  private Vector m_unregisteredExtensions = new Vector();
+  
+  /**
+   * An ExtensionNamespacesManager is instantiated the first time an extension function or
+   * element is found in the stylesheet. During initialization, a vector of ExtensionNamespaceSupport
+   * objects is created, one for each predefined extension namespace.
+   */
+  public ExtensionNamespacesManager()
+  {
+    setPredefinedNamespaces();
+  }
+  
+  /**
+   * If necessary, register the extension namespace found compiling a function or 
+   * creating an extension element. 
+   * 
+   * If it is a predefined namespace, create a
+   * support object to simplify the instantiate of an appropriate ExtensionHandler
+   * during transformation runtime. Otherwise, add the namespace, if necessary,
+   * to a vector of undefined extension namespaces, to be defined later.
+   * 
+   */
+  public void registerExtension(String namespace)
+  {
+    if (namespaceIndex(namespace, m_extensions) == -1)
+    {
+      int predef = namespaceIndex(namespace, m_predefExtensions);
+      if (predef !=-1)
+        m_extensions.add(m_predefExtensions.get(predef));
+      else if (!(m_unregisteredExtensions.contains(namespace)))
+        m_unregisteredExtensions.add(namespace);       
+    }
+  }
+  
+  /**
+   * Register the extension namespace for an ElemExtensionDecl or ElemFunction,
+   * and prepare a support object to launch the appropriate ExtensionHandler at 
+   * transformation runtime.
+   */  
+  public void registerExtension(ExtensionNamespaceSupport extNsSpt)
+  {
+    String namespace = extNsSpt.getNamespace();
+    if (namespaceIndex(namespace, m_extensions) == -1)
+    {
+      m_extensions.add(extNsSpt);
+      if (m_unregisteredExtensions.contains(namespace))
+        m_unregisteredExtensions.remove(namespace);
+    }
+    
+  }
+  
+  /**
+   * Get the index for a namespace entry in the extension namespace Vector, -1 if
+   * no such entry yet exists.
+   */
+  public int namespaceIndex(String namespace, Vector extensions)
+  {
+    for (int i = 0; i < extensions.size(); i++)
+    {
+      if (((ExtensionNamespaceSupport)extensions.get(i)).getNamespace().equals(namespace))
+        return i;
+    }
+    return -1;
+  }
+  
+    
+  /**
+   * 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_extensions;
+  }
+  
+  /**
+   * Attempt to register any unregistered extension namespaces.
+   */
+  public void registerUnregisteredNamespaces()
+  {
+    for (int i = 0; i < m_unregisteredExtensions.size(); i++)
+    {
+      String ns = (String)m_unregisteredExtensions.get(i);
+      ExtensionNamespaceSupport extNsSpt = defineJavaNamespace(ns);
+      if (extNsSpt != null)
+        m_extensions.add(extNsSpt);
+    }    
+  }
+  
+    /**
+   * For any extension namespace that is not either predefined or defined 
+   * by a "component" declaration or exslt function declaration, attempt 
+   * to create an ExtensionNamespaceSuport object for the appropriate 
+   * Java class or Java package Extension Handler.
+   * 
+   * Called by StylesheetRoot.recompose(), after all ElemTemplate compose()
+   * operations have taken place, in order to set up handlers for
+   * the remaining extension namespaces.
+   * 
+   * @param ns The extension namespace URI.
+   * @return   An ExtensionNamespaceSupport object for this namespace
+   * (which defines the ExtensionHandler to be used), or null if such 
+   * an object cannot be created. 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public ExtensionNamespaceSupport defineJavaNamespace(String ns)
+  {
+    return defineJavaNamespace(ns, ns);
+  }
+  public ExtensionNamespaceSupport defineJavaNamespace(String ns, String classOrPackage)
+  {
+    if(null == ns || ns.trim().length() == 0) // defensive. I don't think it's needed.  -sb
+      return null;
+
+    // Prepare the name of the actual class or package, stripping
+    // out any leading "class:".  Next, see if there is a /.  If so,
+    // only look at the text to the right of the rightmost /.
+    String className = classOrPackage;
+    if (className.startsWith("class:"))
+      className = className.substring(6);
+
+    int lastSlash = className.lastIndexOf("/");
+    if (-1 != lastSlash)
+      className = className.substring(lastSlash + 1);
+      
+    // The className can be null here, and can cause an error in getClassForName
+    // in JDK 1.8.
+    if(null == className || className.trim().length() == 0) 
+      return null;
+    
+    try
+    {
+      ExtensionHandler.getClassForName(className);
+      return new ExtensionNamespaceSupport(
+                           ns, 
+                           "org.apache.xalan.extensions.ExtensionHandlerJavaClass",                                         
+                           new Object[]{ns, "javaclass", className});
+    }
+    catch (ClassNotFoundException e)
+    {
+      return new ExtensionNamespaceSupport(
+                            ns, 
+                            "org.apache.xalan.extensions.ExtensionHandlerJavaPackage",
+                            new Object[]{ns, "javapackage", className + "."});
+    }
+  }
+  
+/*
+  public ExtensionNamespaceSupport getSupport(int index, Vector extensions)
+  {
+    return (ExtensionNamespaceSupport)extensions.elementAt(index);
+  }
+*/
+  
+  
+  /**
+   * Set up a Vector for predefined extension namespaces.
+   */
+  private void setPredefinedNamespaces()
+  {    
+    String uri = Constants.S_EXTENSIONS_JAVA_URL;
+    String handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaPackage";
+    String lang = "javapackage";
+    String lib = "";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+   
+    uri = Constants.S_EXTENSIONS_OLD_JAVA_URL;
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    uri = Constants.S_EXTENSIONS_LOTUSXSL_JAVA_URL;
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    uri = Constants.S_BUILTIN_EXTENSIONS_URL;
+    handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaClass";
+    lang = "javaclass"; // for remaining predefined extension namespaces.    
+    lib = "org.apache.xalan.lib.Extensions";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    uri = Constants.S_BUILTIN_OLD_EXTENSIONS_URL;
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    // Xalan extension namespaces (redirect, pipe and SQL).
+    uri = Constants.S_EXTENSIONS_REDIRECT_URL;
+    lib = "org.apache.xalan.lib.Redirect";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+ 
+    uri = Constants.S_EXTENSIONS_PIPE_URL;
+    lib = "org.apache.xalan.lib.PipeDocument";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+ 
+    uri = Constants.S_EXTENSIONS_SQL_URL;
+    lib = "org.apache.xalan.lib.sql.XConnection";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+ 
+    
+    //EXSLT namespaces (not including EXSLT function namespaces which are
+    // registered by the associated ElemFunction.
+    uri = Constants.S_EXSLT_COMMON_URL;
+    lib = "org.apache.xalan.lib.ExsltCommon";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+
+    uri = Constants.S_EXSLT_MATH_URL;
+    lib = "org.apache.xalan.lib.ExsltMath";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    uri = Constants.S_EXSLT_SETS_URL;
+    lib = "org.apache.xalan.lib.ExsltSets";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+    
+    uri = Constants.S_EXSLT_DATETIME_URL;
+    lib = "org.apache.xalan.lib.ExsltDatetime";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+                                             
+    uri = Constants.S_EXSLT_DYNAMIC_URL;
+    lib = "org.apache.xalan.lib.ExsltDynamic";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));
+
+    uri = Constants.S_EXSLT_STRINGS_URL;
+    lib = "org.apache.xalan.lib.ExsltStrings";
+    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
+                                             new Object[]{uri, lang, lib}));                                             
+  }    
+  
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ExtensionsTable.java b/src/main/java/org/apache/xalan/extensions/ExtensionsTable.java
new file mode 100644
index 0000000..cb5cc48
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ExtensionsTable.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtensionsTable.java 469672 2006-10-31 21:56:19Z minchau $
+ */
+package org.apache.xalan.extensions;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xpath.XPathProcessorException;
+import org.apache.xpath.functions.FuncExtFunction;
+
+/**
+ * Class holding a table registered extension namespace handlers
+ * @xsl.usage internal
+ */
+public class ExtensionsTable
+{  
+  /**
+   * Table of extensions that may be called from the expression language
+   * via the call(name, ...) function.  Objects are keyed on the call
+   * name.
+   * @xsl.usage internal
+   */
+  public Hashtable m_extensionFunctionNamespaces = new Hashtable();
+  
+  /**
+   * The StylesheetRoot associated with this extensions table.
+   */
+  private StylesheetRoot m_sroot;
+  
+  /**
+   * The constructor (called from TransformerImpl) registers the
+   * StylesheetRoot for the transformation and instantiates an
+   * ExtensionHandler for each extension namespace.
+   * @xsl.usage advanced
+   */
+  public ExtensionsTable(StylesheetRoot sroot)
+    throws javax.xml.transform.TransformerException
+  {
+    m_sroot = sroot;
+    Vector extensions = m_sroot.getExtensions();
+    for (int i = 0; i < extensions.size(); i++)
+    {
+      ExtensionNamespaceSupport extNamespaceSpt = 
+                 (ExtensionNamespaceSupport)extensions.get(i);
+      ExtensionHandler extHandler = extNamespaceSpt.launch();
+        if (extHandler != null)
+          addExtensionNamespace(extNamespaceSpt.getNamespace(), extHandler);
+      }
+    }
+       
+  /**
+   * Get an ExtensionHandler object that represents the
+   * given namespace.
+   * @param extns A valid extension namespace.
+   *
+   * @return ExtensionHandler object that represents the
+   * given namespace.
+   */
+  public ExtensionHandler get(String extns)
+  {
+    return (ExtensionHandler) m_extensionFunctionNamespaces.get(extns);
+  }
+
+  /**
+   * Register an extension namespace handler. This handler provides
+   * functions for testing whether a function is known within the
+   * namespace and also for invoking the functions.
+   *
+   * @param uri the URI for the extension.
+   * @param extNS the extension handler.
+   * @xsl.usage advanced
+   */
+  public void addExtensionNamespace(String uri, ExtensionHandler extNS)
+  {
+    m_extensionFunctionNamespaces.put(uri, extNS);
+  }
+
+  /**
+   * Execute the function-available() function.
+   * @param ns       the URI of namespace in which the function is needed
+   * @param funcName the function name being tested
+   *
+   * @return whether the given function is available or not.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean functionAvailable(String ns, String funcName)
+          throws javax.xml.transform.TransformerException
+  {
+    boolean isAvailable = false;
+    
+    if (null != ns)
+    {
+      ExtensionHandler extNS = 
+           (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
+      if (extNS != null)
+        isAvailable = extNS.isFunctionAvailable(funcName);
+    }
+    return isAvailable;
+  }
+  
+  /**
+   * Execute the element-available() function.
+   * @param ns       the URI of namespace in which the function is needed
+   * @param elemName name of element being tested
+   *
+   * @return whether the given element is available or not.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean elementAvailable(String ns, String elemName)
+          throws javax.xml.transform.TransformerException
+  {
+    boolean isAvailable = false;
+    if (null != ns)
+    {
+      ExtensionHandler extNS = 
+               (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
+      if (extNS != null) // defensive
+        isAvailable = extNS.isElementAvailable(elemName);
+    } 
+    return isAvailable;        
+  }  
+  
+  /**
+   * Handle an extension function.
+   * @param ns        the URI of namespace in which the function is needed
+   * @param funcName  the function name being called
+   * @param argVec    arguments to the function in a vector
+   * @param methodKey a unique key identifying this function instance in the
+   *                  stylesheet
+   * @param exprContext a context which may be passed to an extension function
+   *                  and provides callback functions to access various
+   *                  areas in the environment
+   *
+   * @return result of executing the function
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public Object extFunction(String ns, String funcName, 
+                            Vector argVec, Object methodKey, 
+                            ExpressionContext exprContext)
+            throws javax.xml.transform.TransformerException
+  {
+    Object result = null;
+    if (null != ns)
+    {
+      ExtensionHandler extNS =
+        (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
+      if (null != extNS)
+      {
+        try
+        {
+          result = extNS.callFunction(funcName, argVec, methodKey,
+                                      exprContext);
+        }
+        catch (javax.xml.transform.TransformerException e)
+        {
+          throw e;
+        }
+        catch (Exception e)
+        {
+          throw new javax.xml.transform.TransformerException(e);
+        }
+      }
+      else
+      {
+        throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, new Object[]{ns, funcName })); 
+        //"Extension function '" + ns + ":" + funcName + "' is unknown");
+      }
+    }
+    return result;    
+  }
+  
+  /**
+   * Handle an extension function.
+   * @param extFunction  the extension function
+   * @param argVec    arguments to the function in a vector
+   * @param exprContext a context which may be passed to an extension function
+   *                  and provides callback functions to access various
+   *                  areas in the environment
+   *
+   * @return result of executing the function
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public Object extFunction(FuncExtFunction extFunction, Vector argVec, 
+                            ExpressionContext exprContext)
+         throws javax.xml.transform.TransformerException
+  {
+    Object result = null;
+    String ns = extFunction.getNamespace();
+    if (null != ns)
+    {
+      ExtensionHandler extNS =
+        (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
+      if (null != extNS)
+      {
+        try
+        {
+          result = extNS.callFunction(extFunction, argVec, exprContext);
+        }
+        catch (javax.xml.transform.TransformerException e)
+        {
+          throw e;
+        }
+        catch (Exception e)
+        {
+          throw new javax.xml.transform.TransformerException(e);
+        }
+      }
+      else
+      {
+        throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, 
+                                          new Object[]{ns, extFunction.getFunctionName()})); 
+      }
+    }
+    return result;        
+  }
+}
diff --git a/src/main/java/org/apache/xalan/extensions/ObjectFactory.java b/src/main/java/org/apache/xalan/extensions/ObjectFactory.java
new file mode 100755
index 0000000..3772cb7
--- /dev/null
+++ b/src/main/java/org/apache/xalan/extensions/ObjectFactory.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectFactory.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+
+package org.apache.xalan.extensions;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id: ObjectFactory.java 468637 2006-10-28 06:51:02Z minchau $
+ */
+class ObjectFactory {
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    {
+        // BEGIN android-changed
+        //     the context class loader is always sufficient
+        return Thread.currentThread().getContextClassLoader();
+        // END android-changed
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = 8564305128443551853L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorAttributeSet.java b/src/main/java/org/apache/xalan/processor/ProcessorAttributeSet.java
new file mode 100644
index 0000000..97f1660
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorAttributeSet.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorAttributeSet.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemAttributeSet;
+import org.apache.xalan.templates.ElemTemplateElement;
+
+import org.xml.sax.Attributes;
+
+/**
+ * This class processes parse events for an xsl:attribute-set.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+ */
+class ProcessorAttributeSet extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -6473739251316787552L;
+
+  /**
+   * Receive notification of the start of an xsl:attribute-set element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   * 
+   * @see org.apache.xalan.processor.StylesheetHandler#startElement
+   * @see org.xml.sax.ContentHandler#startElement
+   * @see org.xml.sax.ContentHandler#endElement
+   * @see org.xml.sax.Attributes
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+    ElemAttributeSet eat = new ElemAttributeSet();
+
+    eat.setLocaterInfo(handler.getLocator());
+    try
+    {
+      eat.setPrefixes(handler.getNamespaceSupport());
+    }
+    catch(TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+
+    eat.setDOMBackPointer(handler.getOriginatingNode());
+    setPropertiesFromAttributes(handler, rawName, attributes, eat);
+    handler.getStylesheet().setAttributeSet(eat);
+
+    // handler.pushElemTemplateElement(eat);
+    ElemTemplateElement parent = handler.getElemTemplateElement();
+
+    parent.appendChild(eat);
+    handler.pushElemTemplateElement(eat);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param name The element type name.
+   * @param attributes The specified or defaulted attributes.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+    handler.popElemTemplateElement();
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorCharacters.java b/src/main/java/org/apache/xalan/processor/ProcessorCharacters.java
new file mode 100644
index 0000000..b318f39
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorCharacters.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorCharacters.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemText;
+import org.apache.xalan.templates.ElemTextLiteral;
+import org.apache.xml.utils.XMLCharacterRecognizer;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class processes character events for a 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 ProcessorCharacters extends XSLTElementProcessor
+{
+    static final long serialVersionUID = 8632900007814162650L;
+
+  /**
+   * Receive notification of the start of the non-text event.  This
+   * is sent to the current processor when any non-text event occurs.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   */
+  public void startNonText(StylesheetHandler handler) throws org.xml.sax.SAXException
+  {
+    if (this == handler.getCurrentProcessor())
+    {
+      handler.popProcessor();
+    }
+
+    int nChars = m_accumulator.length();
+
+    if ((nChars > 0)
+            && ((null != m_xslTextElement)
+                ||!XMLCharacterRecognizer.isWhiteSpace(m_accumulator)) 
+                || handler.isSpacePreserve())
+    {
+      ElemTextLiteral elem = new ElemTextLiteral();
+
+      elem.setDOMBackPointer(m_firstBackPointer);
+      elem.setLocaterInfo(handler.getLocator());
+      try
+      {
+        elem.setPrefixes(handler.getNamespaceSupport());
+      }
+      catch(TransformerException te)
+      {
+        throw new org.xml.sax.SAXException(te);
+      }
+
+      boolean doe = (null != m_xslTextElement)
+                    ? m_xslTextElement.getDisableOutputEscaping() : false;
+
+      elem.setDisableOutputEscaping(doe);
+      elem.setPreserveSpace(true);
+
+      char[] chars = new char[nChars];
+
+      m_accumulator.getChars(0, nChars, chars, 0);
+      elem.setChars(chars);
+
+      ElemTemplateElement parent = handler.getElemTemplateElement();
+
+      parent.appendChild(elem);
+    }
+
+    m_accumulator.setLength(0);
+    m_firstBackPointer = null;
+  }
+  
+  protected Node m_firstBackPointer = null;
+
+  /**
+   * Receive notification of character data inside an element.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param ch The characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#characters
+   */
+  public void characters(
+          StylesheetHandler handler, char ch[], int start, int length)
+            throws org.xml.sax.SAXException
+  {
+
+    m_accumulator.append(ch, start, length);
+    
+    if(null == m_firstBackPointer)
+      m_firstBackPointer = handler.getOriginatingNode();
+
+    // Catch all events until a non-character event.
+    if (this != handler.getCurrentProcessor())
+      handler.pushProcessor(this);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @see org.apache.xalan.processor.StylesheetHandler#startElement
+   * @see org.apache.xalan.processor.StylesheetHandler#endElement
+   * @see org.xml.sax.ContentHandler#startElement
+   * @see org.xml.sax.ContentHandler#endElement
+   * @see org.xml.sax.Attributes
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    // Since this has been installed as the current processor, we 
+    // may get and end element event, in which case, we pop and clear 
+    // and then call the real element processor.
+    startNonText(handler);
+    handler.getCurrentProcessor().endElement(handler, uri, localName,
+                                             rawName);
+    handler.popProcessor();
+  }
+
+  /**
+   * Accumulate characters, until a non-whitespace event has
+   * occured.
+   */
+  private StringBuffer m_accumulator = new StringBuffer();
+
+  /**
+   * The xsl:text processor will call this to set a
+   * preserve space state.
+   */
+  private ElemText m_xslTextElement;
+
+  /**
+   * Set the current setXslTextElement. The xsl:text 
+   * processor will call this to set a preserve space state.
+   *
+   * @param xslTextElement The current xslTextElement that 
+   *                       is preserving state, or null.
+   */
+  void setXslTextElement(ElemText xslTextElement)
+  {
+    m_xslTextElement = xslTextElement;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorDecimalFormat.java b/src/main/java/org/apache/xalan/processor/ProcessorDecimalFormat.java
new file mode 100644
index 0000000..43250a6
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorDecimalFormat.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorDecimalFormat.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.DecimalFormatProperties;
+import org.xml.sax.Attributes;
+
+/**
+ * Process xsl:decimal-format by creating a DecimalFormatProperties 
+ * object and passing it to the stylesheet.
+ * 
+ * @see org.apache.xalan.templates.Stylesheet#setDecimalFormat
+ * @see org.apache.xalan.templates.DecimalFormatProperties
+ * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
+ * @xsl.usage internal
+ */
+class ProcessorDecimalFormat extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -5052904382662921627L;
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   * @see org.apache.xalan.processor.StylesheetHandler#startElement
+   * @see org.apache.xalan.processor.StylesheetHandler#endElement
+   * @see org.xml.sax.ContentHandler#startElement
+   * @see org.xml.sax.ContentHandler#endElement
+   * @see org.xml.sax.Attributes
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+    DecimalFormatProperties dfp = new DecimalFormatProperties(handler.nextUid());
+    
+    dfp.setDOMBackPointer(handler.getOriginatingNode());
+    dfp.setLocaterInfo(handler.getLocator());
+    
+    setPropertiesFromAttributes(handler, rawName, attributes, dfp);
+    handler.getStylesheet().setDecimalFormat(dfp);
+    
+    handler.getStylesheet().appendChild(dfp);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorExsltFuncResult.java b/src/main/java/org/apache/xalan/processor/ProcessorExsltFuncResult.java
new file mode 100644
index 0000000..3a909fa
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorExsltFuncResult.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorExsltFuncResult.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemExsltFuncResult;
+import org.apache.xalan.templates.ElemExsltFunction;
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemVariable;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This class processes parse events for an exslt func:result element.
+ * @xsl.usage internal
+ */
+public class ProcessorExsltFuncResult extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = 6451230911473482423L;
+  
+  /**
+   * Verify that the func:result element does not appear within a variable,
+   * parameter, or another func:result, and that it belongs to a func: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 ancestor = handler.getElemTemplateElement().getParentElem();
+    while (ancestor != null && !(ancestor instanceof ElemExsltFunction))
+    {
+      if (ancestor instanceof ElemVariable 
+          || ancestor instanceof ElemParam
+          || ancestor instanceof ElemExsltFuncResult)
+      {
+        msg = "func:result cannot appear within a variable, parameter, or another func:result.";
+        handler.error(msg, new SAXException(msg));
+      }
+      ancestor = ancestor.getParentElem();
+    }
+    if (ancestor == null)
+    {
+      msg = "func:result must appear in a func:function element";
+      handler.error(msg, new SAXException(msg));
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorExsltFunction.java b/src/main/java/org/apache/xalan/processor/ProcessorExsltFunction.java
new file mode 100644
index 0000000..8eb4e41
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorExsltFunction.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorExsltFunction.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemApplyImport;
+import org.apache.xalan.templates.ElemApplyTemplates;
+import org.apache.xalan.templates.ElemAttribute;
+import org.apache.xalan.templates.ElemCallTemplate;
+import org.apache.xalan.templates.ElemComment;
+import org.apache.xalan.templates.ElemCopy;
+import org.apache.xalan.templates.ElemCopyOf;
+import org.apache.xalan.templates.ElemElement;
+import org.apache.xalan.templates.ElemExsltFuncResult;
+import org.apache.xalan.templates.ElemExsltFunction;
+import org.apache.xalan.templates.ElemFallback;
+import org.apache.xalan.templates.ElemLiteralResult;
+import org.apache.xalan.templates.ElemMessage;
+import org.apache.xalan.templates.ElemNumber;
+import org.apache.xalan.templates.ElemPI;
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemText;
+import org.apache.xalan.templates.ElemTextLiteral;
+import org.apache.xalan.templates.ElemValueOf;
+import org.apache.xalan.templates.ElemVariable;
+import org.apache.xalan.templates.Stylesheet;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+
+/**
+ * This class processes parse events for an exslt func:function element.
+ * @xsl.usage internal
+ */
+public class ProcessorExsltFunction extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = 2411427965578315332L;
+  /**
+   * Start an ElemExsltFunction. 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 Stylesheet))
+    {
+      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 = "func: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.getStylesheet().setTemplate((ElemTemplate) elem);
+  }
+    
+  /**
+   * End an ElemExsltFunction, and verify its validity.
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws SAXException
+  {
+   ElemTemplateElement function = handler.getElemTemplateElement();
+   validate(function, handler); // may throw exception
+   super.endElement(handler, uri, localName, rawName);   
+  }
+  
+  /**
+   * Non-recursive traversal of FunctionElement tree based on TreeWalker to verify that
+   * there are no literal result elements except within a func:result element and that
+   * the func:result element does not contain any following siblings except xsl:fallback.
+   */
+  public void validate(ElemTemplateElement elem, StylesheetHandler handler)
+    throws SAXException
+  {
+    String msg = "";
+    while (elem != null)
+    { 
+      //System.out.println("elem " + elem);
+      if (elem instanceof ElemExsltFuncResult 
+          && elem.getNextSiblingElem() != null 
+          && !(elem.getNextSiblingElem() instanceof ElemFallback))
+      {
+        msg = "func:result has an illegal following sibling (only xsl:fallback allowed)";
+        handler.error(msg, new SAXException(msg));
+      }
+      
+      if((elem instanceof ElemApplyImport
+	 || elem instanceof ElemApplyTemplates
+	 || elem instanceof ElemAttribute
+	 || elem instanceof ElemCallTemplate
+	 || elem instanceof ElemComment
+	 || elem instanceof ElemCopy
+	 || elem instanceof ElemCopyOf
+	 || elem instanceof ElemElement
+	 || elem instanceof ElemLiteralResult
+	 || elem instanceof ElemNumber
+	 || elem instanceof ElemPI
+	 || elem instanceof ElemText
+	 || elem instanceof ElemTextLiteral
+	 || elem instanceof ElemValueOf)
+	&& !(ancestorIsOk(elem)))
+      {
+        msg ="misplaced literal result in a func:function container.";
+        handler.error(msg, new SAXException(msg));
+      }
+      ElemTemplateElement nextElem = elem.getFirstChildElem();
+      while (nextElem == null)
+      {
+        nextElem = elem.getNextSiblingElem();
+        if (nextElem == null)
+          elem = elem.getParentElem();
+        if (elem == null || elem instanceof ElemExsltFunction)
+          return; // ok
+      }  
+      elem = nextElem;
+    }
+  }
+  
+  /**
+   * Verify that a literal result belongs to a result element, a variable, 
+   * or a parameter.
+   */
+  
+  boolean ancestorIsOk(ElemTemplateElement child)
+  {
+    while (child.getParentElem() != null && !(child.getParentElem() instanceof ElemExsltFunction))
+    {
+      ElemTemplateElement parent = child.getParentElem();
+      if (parent instanceof ElemExsltFuncResult 
+          || parent instanceof ElemVariable
+          || parent instanceof ElemParam
+          || parent instanceof ElemMessage)
+        return true;
+      child = parent;      
+    }
+    return false;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorGlobalParamDecl.java b/src/main/java/org/apache/xalan/processor/ProcessorGlobalParamDecl.java
new file mode 100644
index 0000000..3fa4cc3
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorGlobalParamDecl.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorGlobalParamDecl.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemTemplateElement;
+
+/**
+ * This class processes parse events for an xsl:param element.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+ */
+class ProcessorGlobalParamDecl extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = 1900450872353587350L;
+
+  /**
+   * Append the current template element to the current
+   * template element, and then push it onto the current template
+   * element stack.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem The non-null reference to the ElemParam element.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+
+    // Just push, but don't append.
+    handler.pushElemTemplateElement(elem);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param name The element type name.
+   * @param attributes The specified or defaulted attributes.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    ElemParam v = (ElemParam) handler.getElemTemplateElement();
+
+    handler.getStylesheet().appendChild(v);
+    handler.getStylesheet().setParam(v);
+    super.endElement(handler, uri, localName, rawName);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorGlobalVariableDecl.java b/src/main/java/org/apache/xalan/processor/ProcessorGlobalVariableDecl.java
new file mode 100644
index 0000000..8caacbd
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorGlobalVariableDecl.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorGlobalVariableDecl.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemVariable;
+
+/**
+ * This class processes parse events for an xsl:variable element.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+ */
+class ProcessorGlobalVariableDecl extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = -5954332402269819582L;
+
+  /**
+   * Append the current template element to the current
+   * template element, and then push it onto the current template
+   * element stack.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem The non-null reference to the ElemVariable element.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+
+    // Just push, but don't append.
+    handler.pushElemTemplateElement(elem);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param name The element type name.
+   * @param attributes The specified or defaulted attributes.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    ElemVariable v = (ElemVariable) handler.getElemTemplateElement();
+
+    handler.getStylesheet().appendChild(v);
+    handler.getStylesheet().setVariable(v);
+    super.endElement(handler, uri, localName, rawName);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorImport.java b/src/main/java/org/apache/xalan/processor/ProcessorImport.java
new file mode 100644
index 0000000..c044bcf
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorImport.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorImport.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.res.XSLTErrorResources;
+
+/**
+ * This class processes parse events for an xsl:import element.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+ * 
+ * @xsl.usage internal
+ */
+public class ProcessorImport extends ProcessorInclude
+{
+    static final long serialVersionUID = -8247537698214245237L;
+
+  /**
+   * Get the stylesheet type associated with an imported stylesheet
+   *
+   * @return the type of the stylesheet
+   */
+  protected int getStylesheetType()
+  {
+    return StylesheetHandler.STYPE_IMPORT;
+  }
+
+  /**
+   * Get the error number associated with this type of stylesheet importing itself
+   *
+   * @return the appropriate error number
+   */
+  protected String getStylesheetInclErr()
+  {
+    return XSLTErrorResources.ER_IMPORTING_ITSELF;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorInclude.java b/src/main/java/org/apache/xalan/processor/ProcessorInclude.java
new file mode 100644
index 0000000..814a0f3
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorInclude.java
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorInclude.java 469349 2006-10-31 03:06:50Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.io.IOException;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.utils.SystemIDResolver;
+import org.apache.xml.utils.TreeWalker;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * TransformerFactory class for xsl:include markup.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
+ * 
+ * @xsl.usage internal
+ */
+public class ProcessorInclude extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -4570078731972673481L;
+
+  /**
+   * The base URL of the XSL document.
+   * @serial
+   */
+  private String m_href = null;
+
+  /**
+   * Get the base identifier with which this stylesheet is associated.
+   *
+   * @return non-null reference to the href attribute string, or 
+   *         null if setHref has not been called.
+   */
+  public String getHref()
+  {
+    return m_href;
+  }
+
+  /**
+   * Get the base identifier with which this stylesheet is associated.
+   *
+   * @param baseIdent Should be a non-null reference to a valid URL string.
+   */
+  public void setHref(String baseIdent)
+  {
+    // Validate?
+    m_href = baseIdent;
+  }
+
+  /**
+   * Get the stylesheet type associated with an included stylesheet
+   *
+   * @return the type of the stylesheet
+   */
+  protected int getStylesheetType()
+  {
+    return StylesheetHandler.STYPE_INCLUDE;
+  }
+
+  /**
+   * Get the error number associated with this type of stylesheet including itself
+   *
+   * @return the appropriate error number
+   */
+  protected String getStylesheetInclErr()
+  {
+    return XSLTErrorResources.ER_STYLESHEET_INCLUDES_ITSELF;
+  }
+
+  /**
+   * Receive notification of the start of an xsl:include element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+
+    setPropertiesFromAttributes(handler, rawName, attributes, this);
+
+    try
+    {
+
+      // Get the Source from the user's URIResolver (if any).
+      Source sourceFromURIResolver = getSourceFromUriResolver(handler);
+      // Get the system ID of the included/imported stylesheet module
+      String hrefUrl = getBaseURIOfIncludedStylesheet(handler, sourceFromURIResolver);
+
+      if (handler.importStackContains(hrefUrl))
+      {
+        throw new org.xml.sax.SAXException(
+          XSLMessages.createMessage(
+          getStylesheetInclErr(), new Object[]{ hrefUrl }));  //"(StylesheetHandler) "+hrefUrl+" is directly or indirectly importing itself!");
+      }
+
+      // Push the system ID and corresponding Source
+      // on some stacks for later retrieval during parse() time.
+      handler.pushImportURL(hrefUrl);
+      handler.pushImportSource(sourceFromURIResolver);
+
+      int savedStylesheetType = handler.getStylesheetType();
+
+      handler.setStylesheetType(this.getStylesheetType());
+      handler.pushNewNamespaceSupport();
+
+      try
+      {
+        parse(handler, uri, localName, rawName, attributes);
+      }
+      finally
+      {
+        handler.setStylesheetType(savedStylesheetType);
+        handler.popImportURL();
+        handler.popImportSource();
+        handler.popNamespaceSupport();
+      }
+    }
+    catch(TransformerException te)
+    {
+      handler.error(te.getMessage(), te);
+    }
+  }
+
+  /**
+   * Set off a new parse for an included or imported stylesheet.  This will 
+   * set the {@link StylesheetHandler} to a new state, and recurse in with 
+   * a new set of parse events.  Once this function returns, the state of 
+   * the StylesheetHandler should be restored.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, which should be the XSLT namespace.
+   * @param localName The local name (without prefix), which should be "include" or "import".
+   * @param rawName The qualified name (with prefix).
+   * @param attributes The list of attributes on the xsl:include or xsl:import element.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void parse(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    TransformerFactoryImpl processor = handler.getStylesheetProcessor();
+    URIResolver uriresolver = processor.getURIResolver();
+
+    try
+    {
+      Source source = null;
+      
+      // The base identifier, an aboslute URI
+      // that is associated with the included/imported
+      // stylesheet module is known in this method,
+      // so this method does the pushing of the
+      // base ID onto the stack.
+     
+      if (null != uriresolver)
+      {
+        // There is a user provided URI resolver.
+        // At the startElement() call we would
+        // have tried to obtain a Source from it
+        // which we now retrieve
+        source = handler.peekSourceFromURIResolver();
+
+        if (null != source && source instanceof DOMSource)
+        {
+          Node node = ((DOMSource)source).getNode();
+          
+          // There is a user provided URI resolver.
+          // At the startElement() call we would
+          // have already pushed the system ID, obtained
+          // from either the source.getSystemId(), if non-null
+          // or from SystemIDResolver.getAbsoluteURI() as a backup
+          // which we now retrieve.
+          String systemId = handler.peekImportURL();
+          
+          // Push the absolute URI of the included/imported
+          // stylesheet module onto the stack.
+          if (systemId != null)
+              handler.pushBaseIndentifier(systemId);
+        
+          TreeWalker walker = new TreeWalker(handler, new org.apache.xml.utils.DOM2Helper(), systemId);
+
+          try
+          {
+            walker.traverse(node);
+          }
+          catch(org.xml.sax.SAXException se)
+          {
+            throw new TransformerException(se);
+          }
+          if (systemId != null)
+            handler.popBaseIndentifier();
+          return;
+        }
+      }
+      
+      if(null == source)
+      {
+        String absURL = SystemIDResolver.getAbsoluteURI(getHref(),
+                          handler.getBaseIdentifier());
+
+        source = new StreamSource(absURL);
+      }
+      
+      // possible callback to a class that over-rides this method.
+      source = processSource(handler, source);
+      
+      XMLReader reader = null;
+      
+      if(source instanceof SAXSource)
+      {
+        SAXSource saxSource = (SAXSource)source;
+        reader = saxSource.getXMLReader(); // may be null
+      }
+      
+      InputSource inputSource = SAXSource.sourceToInputSource(source);
+
+      if (null == reader)
+      {  
+        // Use JAXP1.1 ( if possible )
+        try {
+          javax.xml.parsers.SAXParserFactory factory=
+                                                     javax.xml.parsers.SAXParserFactory.newInstance();
+          factory.setNamespaceAware( true );
+          
+          if (handler.getStylesheetProcessor().isSecureProcessing())
+          {
+            try
+            {
+              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            }
+            catch (org.xml.sax.SAXException se) {}
+          }
+          
+          javax.xml.parsers.SAXParser jaxpParser=
+                                                 factory.newSAXParser();
+          reader=jaxpParser.getXMLReader();
+          
+        } catch( javax.xml.parsers.ParserConfigurationException ex ) {
+          throw new org.xml.sax.SAXException( ex );
+        } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
+            throw new org.xml.sax.SAXException( ex1.toString() );
+        } 
+        catch( NoSuchMethodError ex2 ) 
+        {
+        }
+        catch (AbstractMethodError ame){}
+      }
+      if (null == reader)
+        reader = XMLReaderFactory.createXMLReader();
+
+      if (null != reader)
+      {
+        reader.setContentHandler(handler);
+        
+        // Push the absolute URI of the included/imported
+        // stylesheet module onto the stack.
+        handler.pushBaseIndentifier(inputSource.getSystemId());
+
+        try
+        {
+          reader.parse(inputSource);
+        }
+        finally
+        {
+          handler.popBaseIndentifier();
+        }
+      }
+    }
+    catch (IOException ioe)
+    {
+      handler.error(XSLTErrorResources.ER_IOEXCEPTION,
+                    new Object[]{ getHref() }, ioe);
+    }
+    catch(TransformerException te)
+    {
+      handler.error(te.getMessage(), te);
+    }
+  }
+
+  /**
+   * This method does nothing, but a class that extends this class could
+   * over-ride it and do some processing of the source.
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param source The source of the included stylesheet.
+   * @return the same or an equivalent source to what was passed in.
+   */
+  protected Source processSource(StylesheetHandler handler, Source source)
+  {
+      return source;
+  }
+  
+  /**
+   * Get the Source object for the included or imported stylesheet module
+   * obtained from the user's URIResolver, if there is no user provided 
+   * URIResolver null is returned.
+   */
+  private Source getSourceFromUriResolver(StylesheetHandler handler)
+            throws TransformerException {
+        Source s = null;
+            TransformerFactoryImpl processor = handler.getStylesheetProcessor();
+            URIResolver uriresolver = processor.getURIResolver();
+            if (uriresolver != null) {
+                String href = getHref();
+                String base = handler.getBaseIdentifier();
+                s = uriresolver.resolve(href,base);
+            }
+
+        return s;
+    }
+
+    /**
+     * Get the base URI of the included or imported stylesheet,
+     * if the user provided a URIResolver, then get the Source
+     * object for the stylsheet from it, and get the systemId 
+     * from that Source object, otherwise try to recover by
+     * using the SysteIDResolver to figure out the base URI.
+     * @param handler The handler that processes the stylesheet as SAX events,
+     * and maintains state
+     * @param s The Source object from a URIResolver, for the included stylesheet module,
+     * so this will be null if there is no URIResolver set.
+     */
+    private String getBaseURIOfIncludedStylesheet(StylesheetHandler handler, Source s)
+            throws TransformerException {
+        
+
+        
+        String baseURI;
+        String idFromUriResolverSource;
+        if (s != null && (idFromUriResolverSource = s.getSystemId()) != null) {
+            // We have a Source obtained from a users's URIResolver,
+            // and the system ID is set on it, so return that as the base URI
+            baseURI = idFromUriResolverSource;
+        } else {
+            // The user did not provide a URIResolver, or it did not 
+            // return a Source for the included stylesheet module, or
+            // the Source has no system ID set, so we fall back to using
+            // the system ID Resolver to take the href and base
+            // to generate the baseURI of the included stylesheet.
+            baseURI = SystemIDResolver.getAbsoluteURI(getHref(), handler
+                    .getBaseIdentifier());
+        }
+
+        return baseURI;
+    }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorKey.java b/src/main/java/org/apache/xalan/processor/ProcessorKey.java
new file mode 100644
index 0000000..2e4cd2a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorKey.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorKey.java 469688 2006-10-31 22:39:43Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.KeyDeclaration;
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:key markup.
+ * <pre>
+ * <!ELEMENT xsl:key EMPTY>
+ * <!ATTLIST xsl:key
+ *   name %qname; #REQUIRED
+ *   match %pattern; #REQUIRED
+ *   use %expr; #REQUIRED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+ */
+class ProcessorKey extends XSLTElementProcessor
+{
+    static final long serialVersionUID = 4285205417566822979L;
+
+  /**
+   * Receive notification of the start of an xsl:key element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+    KeyDeclaration kd = new KeyDeclaration(handler.getStylesheet(), handler.nextUid());
+
+    kd.setDOMBackPointer(handler.getOriginatingNode());
+    kd.setLocaterInfo(handler.getLocator());
+    setPropertiesFromAttributes(handler, rawName, attributes, kd);
+    handler.getStylesheet().setKey(kd);
+  }
+
+  /**
+   * Set the properties of an object from the given attribute list.
+   * @param handler The stylesheet's Content handler, needed for
+   *                error reporting.
+   * @param rawName The raw name of the owner element, needed for
+   *                error reporting.
+   * @param attributes The list of attributes.
+   * @param target The target element where the properties will be set.
+   */
+  void setPropertiesFromAttributes(
+          StylesheetHandler handler, String rawName, Attributes attributes, 
+          org.apache.xalan.templates.ElemTemplateElement target)
+            throws org.xml.sax.SAXException
+  {
+
+    XSLTElementDef def = getElemDef();
+
+    // Keep track of which XSLTAttributeDefs have been processed, so 
+    // I can see which default values need to be set.
+    List processedDefs = new ArrayList();
+    int nAttrs = attributes.getLength();
+
+    for (int i = 0; i < nAttrs; i++)
+    {
+      String attrUri = attributes.getURI(i);
+      String attrLocalName = attributes.getLocalName(i);
+      XSLTAttributeDef attrDef = def.getAttributeDef(attrUri, attrLocalName);
+
+      if (null == attrDef)
+      {
+
+        // Then barf, because this element does not allow this attribute.
+        handler.error(attributes.getQName(i)
+                      + "attribute is not allowed on the " + rawName
+                      + " element!", null);
+      }
+      else
+      {
+        String valueString = attributes.getValue(i);
+
+        if (valueString.indexOf(org.apache.xpath.compiler.Keywords.FUNC_KEY_STRING
+                                + "(") >= 0)
+          handler.error(
+            XSLMessages.createMessage(
+            XSLTErrorResources.ER_INVALID_KEY_CALL, null), null);
+
+        processedDefs.add(attrDef);
+        attrDef.setAttrValue(handler, attrUri, attrLocalName,
+                             attributes.getQName(i), attributes.getValue(i),
+                             target);
+      }
+    }
+
+    XSLTAttributeDef[] attrDefs = def.getAttributes();
+    int nAttrDefs = attrDefs.length;
+
+    for (int i = 0; i < nAttrDefs; i++)
+    {
+      XSLTAttributeDef attrDef = attrDefs[i];
+      String defVal = attrDef.getDefault();
+
+      if (null != defVal)
+      {
+        if (!processedDefs.contains(attrDef))
+        {
+          attrDef.setDefAttrValue(handler, target);
+        }
+      }
+
+      if (attrDef.getRequired())
+      {
+        if (!processedDefs.contains(attrDef))
+          handler.error(
+            XSLMessages.createMessage(
+              XSLTErrorResources.ER_REQUIRES_ATTRIB, new Object[]{ rawName,
+                                                                   attrDef.getName() }), null);
+      }
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorLRE.java b/src/main/java/org/apache/xalan/processor/ProcessorLRE.java
new file mode 100644
index 0000000..baf9f34
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorLRE.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorLRE.java 475981 2006-11-16 23:35:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.List;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemExtensionCall;
+import org.apache.xalan.templates.ElemLiteralResult;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.XMLNSDecl;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xpath.XPath;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Processes an XSLT literal-result-element, or something that looks 
+ * like one.  The actual {@link org.apache.xalan.templates.ElemTemplateElement}
+ * produced may be a {@link org.apache.xalan.templates.ElemLiteralResult}, 
+ * a {@link org.apache.xalan.templates.StylesheetRoot}, or a 
+ * {@link org.apache.xalan.templates.ElemExtensionCall}.
+ * 
+ * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+ * @see org.apache.xalan.templates.ElemLiteralResult
+ * @xsl.usage internal
+ */
+public class ProcessorLRE extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = -1490218021772101404L;
+  /**
+   * Receive notification of the start of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param attributes The specified or defaulted attributes.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      ElemTemplateElement p = handler.getElemTemplateElement();
+      boolean excludeXSLDecl = false;
+      boolean isLREAsStyleSheet = false;
+
+      if (null == p)
+      {
+
+        // Literal Result Template as stylesheet.
+        XSLTElementProcessor lreProcessor = handler.popProcessor();
+        XSLTElementProcessor stylesheetProcessor =
+                                                  handler.getProcessorFor(Constants.S_XSLNAMESPACEURL, "stylesheet",
+                                                                          "xsl:stylesheet");
+
+        handler.pushProcessor(lreProcessor);
+
+        Stylesheet stylesheet;
+        try
+        {
+          stylesheet = getStylesheetRoot(handler);
+        }
+        catch(TransformerConfigurationException tfe)
+        {
+          throw new TransformerException(tfe);
+        }
+
+        // stylesheet.setDOMBackPointer(handler.getOriginatingNode());
+        // ***** Note that we're assigning an empty locator. Is this necessary?
+        SAXSourceLocator slocator = new SAXSourceLocator();
+        Locator locator = handler.getLocator();
+        if(null != locator)
+        {
+          slocator.setLineNumber(locator.getLineNumber());
+          slocator.setColumnNumber(locator.getColumnNumber());
+          slocator.setPublicId(locator.getPublicId());
+          slocator.setSystemId(locator.getSystemId());
+        }
+        stylesheet.setLocaterInfo(slocator);
+        stylesheet.setPrefixes(handler.getNamespaceSupport());
+        handler.pushStylesheet(stylesheet);
+
+        isLREAsStyleSheet = true;
+
+        AttributesImpl stylesheetAttrs = new AttributesImpl();
+        AttributesImpl lreAttrs = new AttributesImpl();
+        int n = attributes.getLength();
+
+        for (int i = 0; i < n; i++)
+        {
+          String attrLocalName = attributes.getLocalName(i);
+          String attrUri = attributes.getURI(i);
+          String value = attributes.getValue(i);
+
+          if ((null != attrUri) && attrUri.equals(Constants.S_XSLNAMESPACEURL))
+          {
+            stylesheetAttrs.addAttribute(null, attrLocalName, attrLocalName,
+                                         attributes.getType(i),
+                                         attributes.getValue(i));
+          }
+          else if ((attrLocalName.startsWith("xmlns:") || attrLocalName.equals(
+                                                                               "xmlns")) && value.equals(Constants.S_XSLNAMESPACEURL))
+          {
+
+            // ignore
+          }
+          else
+          {
+            lreAttrs.addAttribute(attrUri, attrLocalName,
+                                  attributes.getQName(i),
+                                  attributes.getType(i),
+                                  attributes.getValue(i));
+          }
+        }
+
+        attributes = lreAttrs;
+
+        // Set properties from the attributes, but don't throw 
+        // an error if there is an attribute defined that is not 
+        // allowed on a stylesheet.
+				try{
+        stylesheetProcessor.setPropertiesFromAttributes(handler, "stylesheet",
+                                                        stylesheetAttrs, stylesheet);
+				}
+				catch (Exception e)
+				{
+					// This is pretty ugly, but it will have to do for now. 
+					// This is just trying to append some text specifying that
+					// this error came from a missing or invalid XSLT namespace
+					// declaration.
+					// If someone comes up with a better solution, please feel 
+					// free to contribute it. -mm
+         
+					if (stylesheet.getDeclaredPrefixes() == null || 
+						!declaredXSLNS(stylesheet))
+					{
+						throw new org.xml.sax.SAXException(XSLMessages.createWarning(XSLTErrorResources.WG_OLD_XSLT_NS, null));
+					}
+					else
+                    {
+						throw new org.xml.sax.SAXException(e);
+                    }
+				}
+        handler.pushElemTemplateElement(stylesheet);
+
+        ElemTemplate template = new ElemTemplate();
+        if (slocator != null)
+            template.setLocaterInfo(slocator);
+
+        appendAndPush(handler, template);
+
+        XPath rootMatch = new XPath("/", stylesheet, stylesheet, XPath.MATCH, 
+             handler.getStylesheetProcessor().getErrorListener());
+
+        template.setMatch(rootMatch);
+
+        // template.setDOMBackPointer(handler.getOriginatingNode());
+        stylesheet.setTemplate(template);
+
+        p = handler.getElemTemplateElement();
+        excludeXSLDecl = true;
+      }
+
+      XSLTElementDef def = getElemDef();
+      Class classObject = def.getClassObject();
+      boolean isExtension = false;
+      boolean isComponentDecl = false;
+      boolean isUnknownTopLevel = false;
+
+      while (null != p)
+      {
+
+        // System.out.println("Checking: "+p);
+        if (p instanceof ElemLiteralResult)
+        {
+          ElemLiteralResult parentElem = (ElemLiteralResult) p;
+
+          isExtension = parentElem.containsExtensionElementURI(uri);
+        }
+        else if (p instanceof Stylesheet)
+        {
+          Stylesheet parentElem = (Stylesheet) p;
+
+          isExtension = parentElem.containsExtensionElementURI(uri);
+
+          if ((false == isExtension) && (null != uri)
+              && (uri.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
+                  || uri.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
+          {
+            isComponentDecl = true;
+          }
+          else
+          {
+            isUnknownTopLevel = true;
+          }
+        }
+
+        if (isExtension)
+          break;
+
+        p = p.getParentElem();
+      }
+
+      ElemTemplateElement elem = null;
+
+      try
+      {
+        if (isExtension)
+        {
+
+          // System.out.println("Creating extension(1): "+uri);
+          elem = new ElemExtensionCall();
+        }
+        else if (isComponentDecl)
+        {
+          elem = (ElemTemplateElement) classObject.newInstance();
+        }
+        else if (isUnknownTopLevel)
+        {
+
+          // TBD: Investigate, not sure about this.  -sb
+          elem = (ElemTemplateElement) classObject.newInstance();
+        }
+        else
+        {
+          elem = (ElemTemplateElement) classObject.newInstance();
+        }
+
+        elem.setDOMBackPointer(handler.getOriginatingNode());
+        elem.setLocaterInfo(handler.getLocator());
+        elem.setPrefixes(handler.getNamespaceSupport(), excludeXSLDecl);
+
+        if (elem instanceof ElemLiteralResult)
+        {
+          ((ElemLiteralResult) elem).setNamespace(uri);
+          ((ElemLiteralResult) elem).setLocalName(localName);
+          ((ElemLiteralResult) elem).setRawName(rawName);
+          ((ElemLiteralResult) elem).setIsLiteralResultAsStylesheet(
+                                                                    isLREAsStyleSheet);
+        }
+      }
+      catch (InstantiationException ie)
+      {
+        handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT, null, ie);//"Failed creating ElemLiteralResult instance!", ie);
+      }
+      catch (IllegalAccessException iae)
+      {
+        handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT, null, iae);//"Failed creating ElemLiteralResult instance!", iae);
+      }
+
+      setPropertiesFromAttributes(handler, rawName, attributes, elem);
+
+      // bit of a hack here...
+      if (!isExtension && (elem instanceof ElemLiteralResult))
+      {
+        isExtension =
+                     ((ElemLiteralResult) elem).containsExtensionElementURI(uri);
+
+        if (isExtension)
+        {
+
+          // System.out.println("Creating extension(2): "+uri);
+          elem = new ElemExtensionCall();
+
+          elem.setLocaterInfo(handler.getLocator());
+          elem.setPrefixes(handler.getNamespaceSupport());
+          ((ElemLiteralResult) elem).setNamespace(uri);
+          ((ElemLiteralResult) elem).setLocalName(localName);
+          ((ElemLiteralResult) elem).setRawName(rawName);
+          setPropertiesFromAttributes(handler, rawName, attributes, elem);
+        }
+      }
+
+      appendAndPush(handler, elem);
+    }
+    catch(TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * This method could be over-ridden by a class that extends this class.
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @return an object that represents the stylesheet element.
+   */
+  protected Stylesheet getStylesheetRoot(StylesheetHandler handler) throws TransformerConfigurationException
+  {
+    StylesheetRoot stylesheet;
+    stylesheet = new StylesheetRoot(handler.getSchema(), handler.getStylesheetProcessor().getErrorListener());
+    if (handler.getStylesheetProcessor().isSecureProcessing())
+      stylesheet.setSecureProcessing(true);
+    
+    return stylesheet;
+  }
+  
+
+/**
+   * Receive notification of the end of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    ElemTemplateElement elem = handler.getElemTemplateElement();
+
+    if (elem instanceof ElemLiteralResult)
+    {
+      if (((ElemLiteralResult) elem).getIsLiteralResultAsStylesheet())
+      {
+        handler.popStylesheet();
+      }
+    }
+
+    super.endElement(handler, uri, localName, rawName);
+  }
+	
+	private boolean declaredXSLNS(Stylesheet stylesheet)
+	{
+		List declaredPrefixes = stylesheet.getDeclaredPrefixes();
+		int n = declaredPrefixes.size();
+
+		for (int i = 0; i < n; i++)
+		{
+			XMLNSDecl decl = (XMLNSDecl) declaredPrefixes.get(i);
+			if(decl.getURI().equals(Constants.S_XSLNAMESPACEURL))
+				return true;
+		}
+		return false;
+	}
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorNamespaceAlias.java b/src/main/java/org/apache/xalan/processor/ProcessorNamespaceAlias.java
new file mode 100644
index 0000000..5ba7d19
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorNamespaceAlias.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorNamespaceAlias.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.NamespaceAlias;
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:namespace-alias markup.
+ * A stylesheet can use the xsl:namespace-alias element to
+ * declare that one namespace URI is an alias for another namespace URI.
+ * <pre>
+ * <!ELEMENT xsl:namespace-alias EMPTY>
+ * <!ATTLIST xsl:namespace-alias
+ *   stylesheet-prefix CDATA #REQUIRED
+ *   result-prefix CDATA #REQUIRED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+ */
+class ProcessorNamespaceAlias extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -6309867839007018964L;
+
+  /**
+   * Receive notification of the start of an xsl:namespace-alias element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    final String resultNS;
+    NamespaceAlias na = new NamespaceAlias(handler.nextUid());
+
+    setPropertiesFromAttributes(handler, rawName, attributes, na);
+    String prefix = na.getStylesheetPrefix();
+    if(prefix.equals("#default"))
+    {
+      prefix = "";
+      na.setStylesheetPrefix(prefix);
+    }
+    String stylesheetNS = handler.getNamespaceForPrefix(prefix);
+    na.setStylesheetNamespace(stylesheetNS);
+    prefix = na.getResultPrefix();
+    if(prefix.equals("#default"))
+    {
+      prefix = "";
+      na.setResultPrefix(prefix);
+      resultNS = handler.getNamespaceForPrefix(prefix);
+      if(null == resultNS)
+        handler.error(XSLTErrorResources.ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX_FOR_DEFAULT, null, null);
+    }
+    else
+    {
+        resultNS = handler.getNamespaceForPrefix(prefix);
+        if(null == resultNS)
+         handler.error(XSLTErrorResources.ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX, new Object[] {prefix}, null);
+    }
+   
+    na.setResultNamespace(resultNS);
+    handler.getStylesheet().setNamespaceAlias(na);
+    handler.getStylesheet().appendChild(na);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorOutputElem.java b/src/main/java/org/apache/xalan/processor/ProcessorOutputElem.java
new file mode 100644
index 0000000..cb07b43
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorOutputElem.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorOutputElem.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.SystemIDResolver;
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:output markup.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
+ */
+class ProcessorOutputElem extends XSLTElementProcessor
+{
+    static final long serialVersionUID = 3513742319582547590L;
+
+  /** The output properties, set temporarily while the properties are 
+   *  being set from the attributes, and then nulled after that operation 
+   *  is completed.  */
+  private OutputProperties m_outputProperties;
+
+  /**
+   * Set the cdata-section-elements property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#CDATA_SECTION_ELEMENTS
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setCdataSectionElements(java.util.Vector newValue)
+  {
+    m_outputProperties.setQNameProperties(OutputKeys.CDATA_SECTION_ELEMENTS, newValue);
+  }
+
+  /**
+   * Set the doctype-public property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#DOCTYPE_PUBLIC
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setDoctypePublic(String newValue)
+  {
+    m_outputProperties.setProperty(OutputKeys.DOCTYPE_PUBLIC, newValue);
+  }
+
+  /**
+   * Set the doctype-system property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#DOCTYPE_SYSTEM
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setDoctypeSystem(String newValue)
+  {
+    m_outputProperties.setProperty(OutputKeys.DOCTYPE_SYSTEM, newValue);
+  }
+
+  /**
+   * Set the encoding property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#ENCODING
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setEncoding(String newValue)
+  {
+    m_outputProperties.setProperty(OutputKeys.ENCODING, newValue);
+  }
+
+  /**
+   * Set the indent property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#INDENT
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setIndent(boolean newValue)
+  {
+    m_outputProperties.setBooleanProperty(OutputKeys.INDENT, newValue);
+  }
+
+  /**
+   * Set the media type property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setMediaType(String newValue)
+  {
+    m_outputProperties.setProperty(OutputKeys.MEDIA_TYPE, newValue);
+  }
+
+  /**
+   * Set the method property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#METHOD
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setMethod(org.apache.xml.utils.QName newValue)
+  {
+    m_outputProperties.setQNameProperty(OutputKeys.METHOD, newValue);
+  }
+
+  /**
+   * Set the omit-xml-declaration property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#OMIT_XML_DECLARATION
+   * @param newValue processed attribute value.
+   */
+  public void setOmitXmlDeclaration(boolean newValue)
+  {
+    m_outputProperties.setBooleanProperty(OutputKeys.OMIT_XML_DECLARATION, newValue);
+  }
+
+  /**
+   * Set the standalone property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#STANDALONE
+   * @param newValue processed attribute value.
+   */
+  public void setStandalone(boolean newValue)
+  {
+    m_outputProperties.setBooleanProperty(OutputKeys.STANDALONE, newValue);
+  }
+
+  /**
+   * Set the version property from the attribute value.
+   * @see javax.xml.transform.OutputKeys#VERSION
+   * @param newValue non-null reference to processed attribute value.
+   */
+  public void setVersion(String newValue)
+  {
+    m_outputProperties.setProperty(OutputKeys.VERSION, newValue);
+  }
+  
+  /**
+   * Set a foreign property from the attribute value.
+   * @param newValue non-null reference to attribute value.
+   */
+  public void setForeignAttr(String attrUri, String attrLocalName, String attrRawName, String attrValue)
+  {
+    QName key = new QName(attrUri, attrLocalName);
+    m_outputProperties.setProperty(key, attrValue);
+  }
+  
+  /**
+   * Set a foreign property from the attribute value.
+   * @param newValue non-null reference to attribute value.
+   */
+  public void addLiteralResultAttribute(String attrUri, String attrLocalName, String attrRawName, String attrValue)
+  {
+    QName key = new QName(attrUri, attrLocalName);
+    m_outputProperties.setProperty(key, attrValue);
+  }
+
+  /**
+   * Receive notification of the start of an xsl:output element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    // Hmmm... for the moment I don't think I'll have default properties set for this. -sb
+    m_outputProperties = new OutputProperties();
+
+    m_outputProperties.setDOMBackPointer(handler.getOriginatingNode());
+    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 =
+      (String) m_outputProperties.getProperties().get(OutputPropertiesFactory.S_KEY_ENTITIES);
+
+    if (null != entitiesFileName)
+    {
+      try
+      {
+        String absURL = SystemIDResolver.getAbsoluteURI(entitiesFileName,
+                    handler.getBaseIdentifier());
+        m_outputProperties.getProperties().put(OutputPropertiesFactory.S_KEY_ENTITIES, absURL);
+      }
+      catch(TransformerException te)
+      {
+        handler.error(te.getMessage(), te);
+      }
+    }
+    
+    handler.getStylesheet().setOutput(m_outputProperties);
+    
+    ElemTemplateElement parent = handler.getElemTemplateElement();
+    parent.appendChild(m_outputProperties);
+    
+    m_outputProperties = null;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorPreserveSpace.java b/src/main/java/org/apache/xalan/processor/ProcessorPreserveSpace.java
new file mode 100644
index 0000000..ba2e443
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorPreserveSpace.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorPreserveSpace.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.Vector;
+
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.WhiteSpaceInfo;
+import org.apache.xpath.XPath;
+
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:preserve-space markup.
+ * <pre>
+ * <!ELEMENT xsl:preserve-space EMPTY>
+ * <!ATTLIST xsl:preserve-space elements CDATA #REQUIRED>
+ * </pre>
+ */
+class ProcessorPreserveSpace extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -5552836470051177302L;
+
+  /**
+   * Receive notification of the start of an preserve-space element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, 
+          Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    Stylesheet thisSheet = handler.getStylesheet();
+	WhitespaceInfoPaths paths = new WhitespaceInfoPaths(thisSheet);
+    setPropertiesFromAttributes(handler, rawName, attributes, paths);
+
+    Vector xpaths = paths.getElements();
+
+    for (int i = 0; i < xpaths.size(); i++)
+    {
+      WhiteSpaceInfo wsi = new WhiteSpaceInfo((XPath) xpaths.elementAt(i), false, thisSheet);
+      wsi.setUid(handler.nextUid());
+
+      thisSheet.setPreserveSpaces(wsi);
+    }
+    paths.clearElements();
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorStripSpace.java b/src/main/java/org/apache/xalan/processor/ProcessorStripSpace.java
new file mode 100644
index 0000000..1a6d5d7
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorStripSpace.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorStripSpace.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.Vector;
+
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.WhiteSpaceInfo;
+import org.apache.xpath.XPath;
+
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:strip-space markup.
+ * <pre>
+ * <!ELEMENT xsl:strip-space EMPTY>
+ * <!ATTLIST xsl:strip-space elements CDATA #REQUIRED>
+ * </pre>
+ */
+class ProcessorStripSpace extends ProcessorPreserveSpace
+{
+    static final long serialVersionUID = -5594493198637899591L;
+
+  /**
+   * Receive notification of the start of an strip-space element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    Stylesheet thisSheet = handler.getStylesheet();
+	WhitespaceInfoPaths paths = new WhitespaceInfoPaths(thisSheet);
+    setPropertiesFromAttributes(handler, rawName, attributes, paths);
+
+    Vector xpaths = paths.getElements();
+
+    for (int i = 0; i < xpaths.size(); i++)
+    {
+      WhiteSpaceInfo wsi = new WhiteSpaceInfo((XPath) xpaths.elementAt(i), true, thisSheet);
+      wsi.setUid(handler.nextUid());
+
+      thisSheet.setStripSpaces(wsi);
+    }
+    paths.clearElements();
+
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorStylesheetDoc.java b/src/main/java/org/apache/xalan/processor/ProcessorStylesheetDoc.java
new file mode 100644
index 0000000..169b1d3
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorStylesheetDoc.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorStylesheetDoc.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+/**
+ * This class processes the xsl:stylesheet element.  At the 
+ * moment, it defers all methods to it's superclass.
+ * @xsl.usage internal
+ */
+public class ProcessorStylesheetDoc extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -1661497592836231844L;
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorStylesheetElement.java b/src/main/java/org/apache/xalan/processor/ProcessorStylesheetElement.java
new file mode 100644
index 0000000..9314ebd
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorStylesheetElement.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorStylesheetElement.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.StylesheetComposed;
+import org.apache.xalan.templates.StylesheetRoot;
+
+import org.xml.sax.Attributes;
+
+/**
+ * TransformerFactory for xsl:stylesheet or xsl:transform markup.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
+ * 
+ * @xsl.usage internal
+ */
+public class ProcessorStylesheetElement extends XSLTElementProcessor
+{
+    static final long serialVersionUID = -877798927447840792L;
+
+  /**
+   * Receive notification of the start of an strip-space element.
+   *
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param rawName The raw XML 1.0 name (with prefix), or the
+   *        empty string if raw names are not available.
+   * @param attributes The attributes attached to the element.  If
+   *        there are no attributes, it shall be an empty
+   *        Attributes object.
+   */
+  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);
+    try
+    {
+      int stylesheetType = handler.getStylesheetType();
+      Stylesheet stylesheet;
+
+      if (stylesheetType == StylesheetHandler.STYPE_ROOT)
+      {
+        try
+        {
+          stylesheet = getStylesheetRoot(handler);
+        }
+        catch(TransformerConfigurationException tfe)
+        {
+          throw new TransformerException(tfe);
+        }
+      }
+      else
+      {
+        Stylesheet parent = handler.getStylesheet();
+
+        if (stylesheetType == StylesheetHandler.STYPE_IMPORT)
+        {
+          StylesheetComposed sc = new StylesheetComposed(parent);
+
+          parent.setImport(sc);
+
+          stylesheet = sc;
+        }
+        else
+        {
+          stylesheet = new Stylesheet(parent);
+
+          parent.setInclude(stylesheet);
+        }
+      }
+
+      stylesheet.setDOMBackPointer(handler.getOriginatingNode());
+      stylesheet.setLocaterInfo(handler.getLocator());
+
+      stylesheet.setPrefixes(handler.getNamespaceSupport());
+      handler.pushStylesheet(stylesheet);
+      setPropertiesFromAttributes(handler, rawName, attributes,
+                                  handler.getStylesheet());
+      handler.pushElemTemplateElement(handler.getStylesheet());
+    }
+    catch(TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * This method can be over-ridden by a class that extends this one.
+   * @param handler The calling StylesheetHandler/TemplatesBuilder.
+   */
+  protected Stylesheet getStylesheetRoot(StylesheetHandler handler) throws TransformerConfigurationException
+  {
+    StylesheetRoot stylesheet;
+    stylesheet = new StylesheetRoot(handler.getSchema(), handler.getStylesheetProcessor().getErrorListener());
+    
+    if (handler.getStylesheetProcessor().isSecureProcessing())
+      stylesheet.setSecureProcessing(true);
+    
+    return stylesheet;
+  }
+
+/**
+   * Receive notification of the end of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+		super.endElement(handler, uri, localName, rawName);
+    handler.popElemTemplateElement();
+    handler.popStylesheet();
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorTemplate.java b/src/main/java/org/apache/xalan/processor/ProcessorTemplate.java
new file mode 100644
index 0000000..cd11ecd
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorTemplate.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorTemplate.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+
+/**
+ * TransformerFactory for xsl:template markup.
+ */
+class ProcessorTemplate extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = -8457812845473603860L;
+  
+  /**
+   * Append the current template element to the current
+   * template element, and then push it onto the current template
+   * element stack.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem Must be a non-null reference to a {@link org.apache.xalan.templates.ElemTemplate} object.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+
+    super.appendAndPush(handler, elem);
+    elem.setDOMBackPointer(handler.getOriginatingNode());
+    handler.getStylesheet().setTemplate((ElemTemplate) elem);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorTemplateElem.java b/src/main/java/org/apache/xalan/processor/ProcessorTemplateElem.java
new file mode 100644
index 0000000..d3331bd
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorTemplateElem.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorTemplateElem.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.ElemTemplateElement;
+
+import org.xml.sax.Attributes;
+
+/**
+ * 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 ProcessorTemplateElem extends XSLTElementProcessor
+{
+    static final long serialVersionUID = 8344994001943407235L;
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param attributes The specified or defaulted attributes.
+   */
+  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);
+    try
+    {
+      // ElemTemplateElement parent = handler.getElemTemplateElement();
+      XSLTElementDef def = getElemDef();
+      Class classObject = def.getClassObject();
+      ElemTemplateElement elem = null;
+
+      try
+      {
+        elem = (ElemTemplateElement) classObject.newInstance();
+
+        elem.setDOMBackPointer(handler.getOriginatingNode());
+        elem.setLocaterInfo(handler.getLocator());
+        elem.setPrefixes(handler.getNamespaceSupport());
+      }
+      catch (InstantiationException ie)
+      {
+        handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMTMPL, null, ie);//"Failed creating ElemTemplateElement instance!", ie);
+      }
+      catch (IllegalAccessException iae)
+      {
+        handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMTMPL, null, iae);//"Failed creating ElemTemplateElement instance!", iae);
+      }
+
+      setPropertiesFromAttributes(handler, rawName, attributes, elem);
+      appendAndPush(handler, elem);
+    }
+    catch(TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Append the current template element to the current
+   * template element, and then push it onto the current template
+   * element stack.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem non-null reference to a the current template element.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+
+    ElemTemplateElement parent = handler.getElemTemplateElement();
+    if(null != parent)  // defensive, for better multiple error reporting. -sb
+    {
+      parent.appendChild(elem);
+      handler.pushElemTemplateElement(elem);
+    }
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+    super.endElement(handler, uri, localName, rawName);
+    handler.popElemTemplateElement().setEndLocaterInfo(handler.getLocator());
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorText.java b/src/main/java/org/apache/xalan/processor/ProcessorText.java
new file mode 100644
index 0000000..5111a41
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorText.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorText.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemText;
+
+/**
+ * Process xsl:text.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#element-text">element-text in XSLT Specification</a>
+ */
+public class ProcessorText extends ProcessorTemplateElem
+{
+    static final long serialVersionUID = 5170229307201307523L;
+
+  /**
+   * Append the current template element to the current
+   * template element, and then push it onto the current template
+   * element stack.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem non-null reference to a {@link org.apache.xalan.templates.ElemText}.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+
+    // Don't push this element onto the element stack.
+    ProcessorCharacters charProcessor =
+      (ProcessorCharacters) handler.getProcessorFor(null, "text()", "text");
+
+    charProcessor.setXslTextElement((ElemText) elem);
+
+    ElemTemplateElement parent = handler.getElemTemplateElement();
+
+    parent.appendChild(elem);
+    elem.setDOMBackPointer(handler.getOriginatingNode());
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    ProcessorCharacters charProcessor 
+      = (ProcessorCharacters) handler.getProcessorFor(null, "text()", "text");
+
+    charProcessor.setXslTextElement(null);
+
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/ProcessorUnknown.java b/src/main/java/org/apache/xalan/processor/ProcessorUnknown.java
new file mode 100644
index 0000000..8aed015
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/ProcessorUnknown.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ProcessorUnknown.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import org.xml.sax.Attributes;
+
+/**
+ * This class processes an unknown template element.  It is used both 
+ * for unknown top-level elements, and for elements in the 
+ * xslt namespace when the version is higher than the version 
+ * of XSLT that we are set up to process.
+ * @xsl.usage internal
+ */
+public class ProcessorUnknown extends ProcessorLRE
+{
+    static final long serialVersionUID = 600521151487682248L;
+
+}
diff --git a/src/main/java/org/apache/xalan/processor/StylesheetHandler.java b/src/main/java/org/apache/xalan/processor/StylesheetHandler.java
new file mode 100644
index 0000000..dba47ac
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/StylesheetHandler.java
@@ -0,0 +1,1727 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StylesheetHandler.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.Stack;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Templates;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.sax.TemplatesHandler;
+
+import org.apache.xalan.extensions.ExpressionVisitor;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemForEach;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xml.utils.BoolStack;
+import org.apache.xml.utils.NamespaceSupport2;
+import org.apache.xml.utils.NodeConsumer;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xml.utils.XMLCharacterRecognizer;
+import org.apache.xpath.XPath;
+import org.apache.xpath.compiler.FunctionTable;
+import org.apache.xpath.functions.Function;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.NamespaceSupport;
+
+/**
+ * Initializes and processes a stylesheet via SAX events.
+ * This class acts as essentially a state machine, maintaining
+ * a ContentHandler stack, and pushing appropriate content
+ * handlers as parse events occur.
+ * @xsl.usage advanced
+ */
+public class StylesheetHandler extends DefaultHandler
+        implements TemplatesHandler, PrefixResolver, NodeConsumer
+{
+
+
+  /**
+   * The function table of XPath and XSLT;
+   */
+  private FunctionTable m_funcTable = new FunctionTable();
+  
+  /**
+   * The flag for the setting of the optimize feature;
+   */
+  private boolean m_optimize = true;
+  
+  /**
+   * The flag for the setting of the incremental feature;
+   */
+  private boolean m_incremental = false;
+  
+  /**
+   * The flag for the setting of the source_location feature;
+   */
+  private boolean m_source_location = false;
+  
+  /**
+   * Create a StylesheetHandler object, creating a root stylesheet
+   * as the target.
+   *
+   * @param processor non-null reference to the transformer factory that owns this handler.
+   *
+   * @throws TransformerConfigurationException if a StylesheetRoot
+   * can not be constructed for some reason.
+   */
+  public StylesheetHandler(TransformerFactoryImpl processor)
+          throws TransformerConfigurationException
+  {
+    Class func = org.apache.xalan.templates.FuncDocument.class;
+    m_funcTable.installFunction("document", func);
+
+    // func = new org.apache.xalan.templates.FuncKey();
+    // FunctionTable.installFunction("key", func);
+    func = org.apache.xalan.templates.FuncFormatNumb.class;
+
+    m_funcTable.installFunction("format-number", func);
+
+    m_optimize =((Boolean) processor.getAttribute(
+            TransformerFactoryImpl.FEATURE_OPTIMIZE)).booleanValue();
+    m_incremental = ((Boolean) processor.getAttribute(
+            TransformerFactoryImpl.FEATURE_INCREMENTAL)).booleanValue();
+    m_source_location = ((Boolean) processor.getAttribute(
+            TransformerFactoryImpl.FEATURE_SOURCE_LOCATION)).booleanValue();
+    // m_schema = new XSLTSchema();
+    init(processor);
+    
+  }
+
+  /**
+   * Do common initialization.
+   *
+   * @param processor non-null reference to the transformer factory that owns this handler.
+   */
+  void init(TransformerFactoryImpl processor)
+  {
+    m_stylesheetProcessor = processor;
+
+    // Set the initial content handler.
+    m_processors.push(m_schema.getElementProcessor());
+    this.pushNewNamespaceSupport();
+
+    // m_includeStack.push(SystemIDResolver.getAbsoluteURI(this.getBaseIdentifier(), null));
+    // initXPath(processor, null);
+  }
+
+  /**
+   * Process an expression string into an XPath.
+   * Must be public for access by the AVT class.
+   *
+   * @param str A non-null reference to a valid or invalid XPath expression string.
+   *
+   * @return A non-null reference to an XPath object that represents the string argument.
+   *
+   * @throws javax.xml.transform.TransformerException if the expression can not be processed.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Expressions">Section 4 Expressions in XSLT Specification</a>
+   */
+  public XPath createXPath(String str, ElemTemplateElement owningTemplate)
+          throws javax.xml.transform.TransformerException
+  {
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+    XPath xpath = new XPath(str, owningTemplate, this, XPath.SELECT, handler, 
+            m_funcTable);
+    // Visit the expression, registering namespaces for any extension functions it includes.
+    xpath.callVisitors(xpath, new ExpressionVisitor(getStylesheetRoot()));
+    return xpath;
+  }
+
+  /**
+   * Process an expression string into an XPath.
+   *
+   * @param str A non-null reference to a valid or invalid match pattern string.
+   *
+   * @return A non-null reference to an XPath object that represents the string argument.
+   *
+   * @throws javax.xml.transform.TransformerException if the pattern can not be processed.
+   * @see <a href="http://www.w3.org/TR/xslt#patterns">Section 5.2 Patterns in XSLT Specification</a>
+   */
+  XPath createMatchPatternXPath(String str, ElemTemplateElement owningTemplate)
+          throws javax.xml.transform.TransformerException
+  {
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+    XPath xpath = new XPath(str, owningTemplate, this, XPath.MATCH, handler, 
+        m_funcTable);
+    // Visit the expression, registering namespaces for any extension functions it includes.
+    xpath.callVisitors(xpath, new ExpressionVisitor(getStylesheetRoot()));
+    return xpath;    
+  }
+
+  /**
+   * Given a namespace, get the corrisponding prefix from the current
+   * namespace support context.
+   *
+   * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
+   *
+   * @return The associated Namespace URI, or null if the prefix
+   *         is undeclared in this context.
+   */
+  public String getNamespaceForPrefix(String prefix)
+  {
+    return this.getNamespaceSupport().getURI(prefix);
+  }
+
+  /**
+   * Given a namespace, get the corrisponding prefix.  This is here only
+   * to support the {@link org.apache.xml.utils.PrefixResolver} interface,
+   * and will throw an error if invoked on this object.
+   *
+   * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
+   * @param context The node context from which to look up the URI.
+   *
+   * @return The associated Namespace URI, or null if the prefix
+   *         is undeclared in this context.
+   */
+  public String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context)
+  {
+
+    // Don't need to support this here.  Return the current URI for the prefix,
+    // ignoring the context.
+    assertion(true, "can't process a context node in StylesheetHandler!");
+
+    return null;
+  }
+
+  /**
+   * Utility function to see if the stack contains the given URL.
+   *
+   * @param stack non-null reference to a Stack.
+   * @param url URL string on which an equality test will be performed.
+   *
+   * @return true if the stack contains the url argument.
+   */
+  private boolean stackContains(Stack stack, String url)
+  {
+
+    int n = stack.size();
+    boolean contains = false;
+
+    for (int i = 0; i < n; i++)
+    {
+      String url2 = (String) stack.elementAt(i);
+
+      if (url2.equals(url))
+      {
+        contains = true;
+
+        break;
+      }
+    }
+
+    return contains;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the TRAX TemplatesBuilder interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * When this object is used as a ContentHandler or ContentHandler, it will
+   * create a Templates object, which the caller can get once
+   * the SAX events have been completed.
+   * @return The stylesheet object that was created during
+   * the SAX event process, or null if no stylesheet has
+   * been created.
+   * 
+   * Author <a href="mailto:scott_boag@lotus.com">Scott Boag</a>
+   *
+   *
+   */
+  public Templates getTemplates()
+  {
+    return getStylesheetRoot();
+  }
+
+  /**
+   * Set the base ID (URL or system ID) for the stylesheet
+   * created by this builder.  This must be set in order to
+   * resolve relative URLs in the stylesheet.
+   *
+   * @param baseID Base URL for this stylesheet.
+   */
+  public void setSystemId(String baseID)
+  {
+    pushBaseIndentifier(baseID);
+  }
+
+  /**
+   * Get the base ID (URI or system ID) from where relative
+   * URLs will be resolved.
+   *
+   * @return The systemID that was set with {@link #setSystemId}.
+   */
+  public String getSystemId()
+  {
+    return this.getBaseIdentifier();
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the EntityResolver interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Resolve an external entity.
+   *
+   * @param publicId The public identifer, or null if none is
+   *                 available.
+   * @param systemId The system identifier provided in the XML
+   *                 document.
+   * @return The new input source, or null to require the
+   *         default behaviour.
+   *
+   * @throws org.xml.sax.SAXException if the entity can not be resolved.
+   */
+  public InputSource resolveEntity(String publicId, String systemId)
+          throws org.xml.sax.SAXException
+  {
+    return getCurrentProcessor().resolveEntity(this, publicId, systemId);
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of DTDHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive notification of a notation declaration.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass if they wish to keep track of the notations
+   * declared in a document.</p>
+   *
+   * @param name The notation name.
+   * @param publicId The notation public identifier, or null if not
+   *                 available.
+   * @param systemId The notation system identifier.
+   * @see org.xml.sax.DTDHandler#notationDecl
+   */
+  public void notationDecl(String name, String publicId, String systemId)
+  {
+    getCurrentProcessor().notationDecl(this, name, publicId, systemId);
+  }
+
+  /**
+   * Receive notification of an unparsed entity declaration.
+   *
+   * @param name The entity name.
+   * @param publicId The entity public identifier, or null if not
+   *                 available.
+   * @param systemId The entity system identifier.
+   * @param notationName The name of the associated notation.
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void unparsedEntityDecl(String name, String publicId,
+                                 String systemId, String notationName)
+  {
+    getCurrentProcessor().unparsedEntityDecl(this, name, publicId, systemId,
+                                             notationName);
+  }
+
+  /**
+   * Given a namespace URI, and a local name or a node type, get the processor
+   * for the element, or return null if not allowed.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   *
+   * @return A non-null reference to a element processor.
+   *
+   * @throws org.xml.sax.SAXException if the element is not allowed in the
+   * found position in the stylesheet.
+   */
+  XSLTElementProcessor getProcessorFor(
+          String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+
+    XSLTElementProcessor currentProcessor = getCurrentProcessor();
+    XSLTElementDef def = currentProcessor.getElemDef();
+    XSLTElementProcessor elemProcessor = def.getProcessorFor(uri, localName);
+
+    if (null == elemProcessor
+            && !(currentProcessor instanceof ProcessorStylesheetDoc)
+            && ((null == getStylesheet()
+                || Double.valueOf(getStylesheet().getVersion()).doubleValue()
+                   > Constants.XSLTVERSUPPORTED) 
+                ||(!uri.equals(Constants.S_XSLNAMESPACEURL) &&
+                            currentProcessor instanceof ProcessorStylesheetElement)
+                || getElemVersion() > Constants.XSLTVERSUPPORTED
+        ))
+    {
+      elemProcessor = def.getProcessorForUnknown(uri, localName);
+    }
+
+    if (null == elemProcessor)
+      error(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_ALLOWED_IN_POSITION, new Object[]{rawName}),null);//rawName + " is not allowed in this position in the stylesheet!",
+            
+                
+    return elemProcessor;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of ContentHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive a Locator object for document events.
+   * This is called by the parser to push a locator for the
+   * stylesheet being parsed. The stack needs to be popped
+   * after the stylesheet has been parsed. We pop in
+   * popStylesheet.
+   *
+   * @param locator A locator for all SAX document events.
+   * @see org.xml.sax.ContentHandler#setDocumentLocator
+   * @see org.xml.sax.Locator
+   */
+  public void setDocumentLocator(Locator locator)
+  {
+
+    // System.out.println("pushing locator for: "+locator.getSystemId());
+    m_stylesheetLocatorStack.push(new SAXSourceLocator(locator));
+  }
+
+  /**
+   * The level of the stylesheet we are at.
+   */
+  private int m_stylesheetLevel = -1;
+
+  /**
+   * Receive notification of the beginning of the document.
+   *
+   * @see org.xml.sax.ContentHandler#startDocument
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void startDocument() throws org.xml.sax.SAXException
+  {
+    m_stylesheetLevel++;
+    pushSpaceHandling(false);
+  }
+
+  /** m_parsingComplete becomes true when the top-level stylesheet and all
+   * its included/imported stylesheets have been been fully parsed, as an
+   * indication that composition/optimization/compilation can begin.
+   * @see isStylesheetParsingComplete  */
+  private boolean m_parsingComplete = false;
+
+  /**
+   * Test whether the _last_ endDocument() has been processed.
+   * This is needed as guidance for stylesheet optimization
+   * and compilation engines, which generally don't want to start
+   * until all included and imported stylesheets have been fully
+   * parsed.
+   *
+   * @return true iff the complete stylesheet tree has been built.
+   */
+  public boolean isStylesheetParsingComplete()
+  {
+    return m_parsingComplete;
+  }
+
+  /**
+   * Receive notification of the end of the document.
+   *
+   * @see org.xml.sax.ContentHandler#endDocument
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void endDocument() throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      if (null != getStylesheetRoot())
+      {
+        if (0 == m_stylesheetLevel)
+          getStylesheetRoot().recompose();        
+      }
+      else
+        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEETROOT, null)); //"Did not find the stylesheet root!");
+
+      XSLTElementProcessor elemProcessor = getCurrentProcessor();
+
+      if (null != elemProcessor)
+        elemProcessor.startNonText(this);
+
+      m_stylesheetLevel--;			
+      
+      popSpaceHandling();
+
+      // WARNING: This test works only as long as stylesheets are parsed
+      // more or less recursively. If we switch to an iterative "work-list"
+      // model, this will become true prematurely. In that case,
+      // isStylesheetParsingComplete() will have to be adjusted to be aware
+      // of the worklist.
+      m_parsingComplete = (m_stylesheetLevel < 0);
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+  
+  private java.util.Vector m_prefixMappings = new java.util.Vector();
+
+  /**
+   * Receive notification of the start of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each element (such as allocating a new tree node or writing
+   * output to a file).</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @param uri The Namespace URI mapped to the prefix.
+   * @see org.xml.sax.ContentHandler#startPrefixMapping
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void startPrefixMapping(String prefix, String uri)
+          throws org.xml.sax.SAXException
+  {
+
+    // m_nsSupport.pushContext();
+    // this.getNamespaceSupport().declarePrefix(prefix, uri);
+    //m_prefixMappings.add(prefix); // JDK 1.2+ only -sc
+    //m_prefixMappings.add(uri); // JDK 1.2+ only -sc
+    m_prefixMappings.addElement(prefix); // JDK 1.1.x compat -sc
+    m_prefixMappings.addElement(uri); // JDK 1.1.x compat -sc
+  }
+
+  /**
+   * Receive notification of the end of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each element (such as allocating a new tree node or writing
+   * output to a file).</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @see org.xml.sax.ContentHandler#endPrefixMapping
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException
+  {
+
+    // m_nsSupport.popContext();
+  }
+
+  /**
+   * Flush the characters buffer.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  private void flushCharacters() throws org.xml.sax.SAXException
+  {
+
+    XSLTElementProcessor elemProcessor = getCurrentProcessor();
+
+    if (null != elemProcessor)
+      elemProcessor.startNonText(this);
+  }
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param attributes The specified or defaulted attributes.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void startElement(
+          String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    NamespaceSupport nssupport = this.getNamespaceSupport();
+    nssupport.pushContext();
+    
+    int n = m_prefixMappings.size();
+
+    for (int i = 0; i < n; i++) 
+    {
+      String prefix = (String)m_prefixMappings.elementAt(i++);
+      String nsURI = (String)m_prefixMappings.elementAt(i);
+      nssupport.declarePrefix(prefix, nsURI);
+    }
+    //m_prefixMappings.clear(); // JDK 1.2+ only -sc
+    m_prefixMappings.removeAllElements(); // JDK 1.1.x compat -sc
+
+    m_elementID++;
+
+    // This check is currently done for all elements.  We should possibly consider
+    // limiting this check to xsl:stylesheet elements only since that is all it really
+    // applies to.  Also, it could be bypassed if m_shouldProcess is already true.
+    // In other words, the next two statements could instead look something like this:
+    // if (!m_shouldProcess)
+    // {
+    //   if (localName.equals(Constants.ELEMNAME_STYLESHEET_STRING) &&
+    //       url.equals(Constants.S_XSLNAMESPACEURL))
+    //   {
+    //     checkForFragmentID(attributes);
+    //     if (!m_shouldProcess)
+    //       return;
+    //   }
+    //   else
+    //     return;
+    // } 
+    // I didn't include this code statement at this time because in practice 
+    // it is a small performance hit and I was waiting to see if its absence
+    // caused a problem. - GLP
+
+    checkForFragmentID(attributes);
+
+    if (!m_shouldProcess)
+      return;
+
+    flushCharacters();
+    
+    pushSpaceHandling(attributes);
+
+    XSLTElementProcessor elemProcessor = getProcessorFor(uri, localName,
+                                           rawName);
+
+    if(null != elemProcessor)  // defensive, for better multiple error reporting. -sb
+    {
+      this.pushProcessor(elemProcessor);
+      elemProcessor.startElement(this, uri, localName, rawName, attributes);
+    }
+    else
+    {
+      m_shouldProcess = false;
+      popSpaceHandling();
+    }
+                
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @see org.xml.sax.ContentHandler#endElement
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void endElement(String uri, String localName, String rawName)
+          throws org.xml.sax.SAXException
+  {
+
+    m_elementID--;
+
+    if (!m_shouldProcess)
+      return;
+
+    if ((m_elementID + 1) == m_fragmentID)
+      m_shouldProcess = false;
+
+    flushCharacters();
+    
+    popSpaceHandling();
+
+    XSLTElementProcessor p = getCurrentProcessor();
+
+    p.endElement(this, uri, localName, rawName);
+    this.popProcessor();
+    this.getNamespaceSupport().popContext();
+  }
+
+  /**
+   * Receive notification of character data inside an element.
+   *
+   * @param ch The characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @see org.xml.sax.ContentHandler#characters
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void characters(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    if (!m_shouldProcess)
+      return;
+
+    XSLTElementProcessor elemProcessor = getCurrentProcessor();
+    XSLTElementDef def = elemProcessor.getElemDef();
+
+    if (def.getType() != XSLTElementDef.T_PCDATA)
+      elemProcessor = def.getProcessorFor(null, "text()");
+
+    if (null == elemProcessor)
+    {
+
+      // If it's whitespace, just ignore it, otherwise flag an error.
+      if (!XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+        error(
+          XSLMessages.createMessage(XSLTErrorResources.ER_NONWHITESPACE_NOT_ALLOWED_IN_POSITION, null),null);//"Non-whitespace text is not allowed in this position in the stylesheet!",
+          
+    }
+    else
+      elemProcessor.characters(this, ch, start, length);
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   * @param ch The whitespace characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @see org.xml.sax.ContentHandler#ignorableWhitespace
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    if (!m_shouldProcess)
+      return;
+
+    getCurrentProcessor().ignorableWhitespace(this, ch, start, length);
+  }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   * <p>The Parser will invoke this method once for each processing
+   * instruction found: note that processing instructions may occur
+   * before or after the main document element.</p>
+   *
+   * <p>A SAX parser should never report an XML declaration (XML 1.0,
+   * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+   * using this method.</p>
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void processingInstruction(String target, String data)
+          throws org.xml.sax.SAXException
+  {
+    if (!m_shouldProcess)
+      return;
+
+    // Recreating Scott's kluge:
+    // A xsl:for-each or xsl:apply-templates may have a special 
+    // PI that tells us not to cache the document.  This PI 
+    // should really be namespaced.
+    //    String localName = getLocalName(target);
+    //    String ns = m_stylesheet.getNamespaceFromStack(target);
+    //
+    // %REVIEW%: We need a better PI architecture
+    
+    String prefix="",ns="", localName=target;
+    int colon=target.indexOf(':');
+    if(colon>=0)
+    {
+      ns=getNamespaceForPrefix(prefix=target.substring(0,colon));
+      localName=target.substring(colon+1);
+    }
+
+    try
+    {
+      // A xsl:for-each or xsl:apply-templates may have a special 
+      // PI that tells us not to cache the document.  This PI 
+      // should really be namespaced... but since the XML Namespaces
+      // spec never defined namespaces as applying to PI's, and since
+      // the testcase we're trying to support is inconsistant in whether
+      // it binds the prefix, I'm going to make this sloppy for
+      // testing purposes.
+      if(
+        "xalan-doc-cache-off".equals(target) ||
+        "xalan:doc-cache-off".equals(target) ||
+	   ("doc-cache-off".equals(localName) &&
+	    ns.equals("org.apache.xalan.xslt.extensions.Redirect") )
+	 )
+      {
+	if(!(m_elems.peek() instanceof ElemForEach))
+          throw new TransformerException
+	    ("xalan:doc-cache-off not allowed here!", 
+	     getLocator());
+        ElemForEach elem = (ElemForEach)m_elems.peek();
+
+        elem.m_doc_cache_off = true;
+
+	//System.out.println("JJK***** Recognized <? {"+ns+"}"+prefix+":"+localName+" "+data+"?>");
+      }
+    }
+    catch(Exception e)
+    {
+      // JJK: Officially, unknown PIs can just be ignored.
+      // Do we want to issue a warning?
+    }
+
+
+    flushCharacters();
+    getCurrentProcessor().processingInstruction(this, target, data);
+  }
+
+  /**
+   * Receive notification of a skipped entity.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param name The name of the skipped entity.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void skippedEntity(String name) throws org.xml.sax.SAXException
+  {
+
+    if (!m_shouldProcess)
+      return;
+
+    getCurrentProcessor().skippedEntity(this, name);
+  }
+
+  /**
+   * Warn the user of an problem.
+   *
+   * @param msg An key into the {@link org.apache.xalan.res.XSLTErrorResources}
+   * table, that is one of the WG_ prefixed definitions.
+   * @param args An array of arguments for the given warning.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#warning}
+   * method chooses to flag this condition as an error.
+   * @xsl.usage internal
+   */
+  public void warn(String msg, Object args[]) throws org.xml.sax.SAXException
+  {
+
+    String formattedMsg = XSLMessages.createWarning(msg, args);
+    SAXSourceLocator locator = getLocator();
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+
+    try
+    {
+      if (null != handler)
+        handler.warning(new TransformerException(formattedMsg, locator));
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Assert that a condition is true.  If it is not true, throw an error.
+   *
+   * @param condition false if an error should not be thrown, otherwise true.
+   * @param msg Error message to be passed to the RuntimeException as an
+   * argument.
+   * @throws RuntimeException if the condition is not true.
+   * @xsl.usage internal
+   */
+  private void assertion(boolean condition, String msg) throws RuntimeException
+  {
+    if (!condition)
+      throw new RuntimeException(msg);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg An error message.
+   * @param e An error which the SAXException should wrap.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#error}
+   * method chooses to flag this condition as an error.
+   * @xsl.usage internal
+   */
+  protected void error(String msg, Exception e)
+          throws org.xml.sax.SAXException
+  {
+
+    SAXSourceLocator locator = getLocator();
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+    TransformerException pe;
+
+    if (!(e instanceof TransformerException))
+    {
+      pe = (null == e)
+           ? new TransformerException(msg, locator)
+           : new TransformerException(msg, locator, e);
+    }
+    else
+      pe = (TransformerException) e;
+
+    if (null != handler)
+    {
+      try
+      {
+        handler.error(pe);
+      }
+      catch (TransformerException te)
+      {
+        throw new org.xml.sax.SAXException(te);
+      }
+    }
+    else
+      throw new org.xml.sax.SAXException(pe);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg A key into the {@link org.apache.xalan.res.XSLTErrorResources}
+   * table, that is one of the WG_ prefixed definitions.
+   * @param args An array of arguments for the given warning.
+   * @param e An error which the SAXException should wrap.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#error}
+   * method chooses to flag this condition as an error.
+   * @xsl.usage internal
+   */
+  protected void error(String msg, Object args[], Exception e)
+          throws org.xml.sax.SAXException
+  {
+
+    String formattedMsg = XSLMessages.createMessage(msg, args);
+
+    error(formattedMsg, e);
+  }
+
+  /**
+   * Receive notification of a XSLT processing warning.
+   *
+   * @param e The warning information encoded as an exception.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#warning}
+   * method chooses to flag this condition as an error.
+   */
+  public void warning(org.xml.sax.SAXParseException e)
+          throws org.xml.sax.SAXException
+  {
+
+    String formattedMsg = e.getMessage();
+    SAXSourceLocator locator = getLocator();
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+
+    try
+    {
+      handler.warning(new TransformerException(formattedMsg, locator));
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Receive notification of a recoverable XSLT processing error.
+   *
+   * @param e The error information encoded as an exception.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#error}
+   * method chooses to flag this condition as an error.
+   */
+  public void error(org.xml.sax.SAXParseException e)
+          throws org.xml.sax.SAXException
+  {
+
+    String formattedMsg = e.getMessage();
+    SAXSourceLocator locator = getLocator();
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+
+    try
+    {
+      handler.error(new TransformerException(formattedMsg, locator));
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Report a fatal XSLT processing error.
+   *
+   * @param e The error information encoded as an exception.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the current
+   * {@link javax.xml.transform.ErrorListener#fatalError}
+   * method chooses to flag this condition as an error.
+   */
+  public void fatalError(org.xml.sax.SAXParseException e)
+          throws org.xml.sax.SAXException
+  {
+
+    String formattedMsg = e.getMessage();
+    SAXSourceLocator locator = getLocator();
+    ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+
+    try
+    {
+      handler.fatalError(new TransformerException(formattedMsg, locator));
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * If we have a URL to a XML fragment, this is set
+   * to false until the ID is found.
+   * (warning: I worry that this should be in a stack).
+   */
+  private boolean m_shouldProcess = true;
+
+  /**
+   * If we have a URL to a XML fragment, the value is stored
+   * in this string, and the m_shouldProcess flag is set to
+   * false until we match an ID with this string.
+   * (warning: I worry that this should be in a stack).
+   */
+  private String m_fragmentIDString;
+
+  /**
+   * Keep track of the elementID, so we can tell when
+   * is has completed.  This isn't a real ID, but rather
+   * a nesting level.  However, it's good enough for
+   * our purposes.
+   * (warning: I worry that this should be in a stack).
+   */
+  private int m_elementID = 0;
+
+  /**
+   * The ID of the fragment that has been found
+   * (warning: I worry that this should be in a stack).
+   */
+  private int m_fragmentID = 0;
+
+  /**
+   * Check to see if an ID attribute matched the #id, called
+   * from startElement.
+   *
+   * @param attributes The specified or defaulted attributes.
+   */
+  private void checkForFragmentID(Attributes attributes)
+  {
+
+    if (!m_shouldProcess)
+    {
+      if ((null != attributes) && (null != m_fragmentIDString))
+      {
+        int n = attributes.getLength();
+
+        for (int i = 0; i < n; i++)
+        {
+          String name = attributes.getQName(i);
+
+          if (name.equals(Constants.ATTRNAME_ID))
+          {
+            String val = attributes.getValue(i);
+
+            if (val.equalsIgnoreCase(m_fragmentIDString))
+            {
+              m_shouldProcess = true;
+              m_fragmentID = m_elementID;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   *  The XSLT TransformerFactory for needed services.
+   */
+  private TransformerFactoryImpl m_stylesheetProcessor;
+
+  /**
+   * Get the XSLT TransformerFactoryImpl for needed services.
+   * TODO: This method should be renamed.
+   *
+   * @return The TransformerFactoryImpl that owns this handler.
+   */
+  public TransformerFactoryImpl getStylesheetProcessor()
+  {
+    return m_stylesheetProcessor;
+  }
+
+  /**
+   * If getStylesheetType returns this value, the current stylesheet
+   *  is a root stylesheet.
+   * @xsl.usage internal
+   */
+  public static final int STYPE_ROOT = 1;
+
+  /**
+   * If getStylesheetType returns this value, the current stylesheet
+   *  is an included stylesheet.
+   * @xsl.usage internal
+   */
+  public static final int STYPE_INCLUDE = 2;
+
+  /**
+   * If getStylesheetType returns this value, the current stylesheet
+   *  is an imported stylesheet.
+   * @xsl.usage internal
+   */
+  public static final int STYPE_IMPORT = 3;
+
+  /** The current stylesheet type. */
+  private int m_stylesheetType = STYPE_ROOT;
+
+  /**
+   * Get the type of stylesheet that should be built
+   * or is being processed.
+   *
+   * @return one of STYPE_ROOT, STYPE_INCLUDE, or STYPE_IMPORT.
+   */
+  int getStylesheetType()
+  {
+    return m_stylesheetType;
+  }
+
+  /**
+   * Set the type of stylesheet that should be built
+   * or is being processed.
+   *
+   * @param type Must be one of STYPE_ROOT, STYPE_INCLUDE, or STYPE_IMPORT.
+   */
+  void setStylesheetType(int type)
+  {
+    m_stylesheetType = type;
+  }
+
+  /**
+   * The stack of stylesheets being processed.
+   */
+  private Stack m_stylesheets = new Stack();
+
+  /**
+   * Return the stylesheet that this handler is constructing.
+   *
+   * @return The current stylesheet that is on top of the stylesheets stack,
+   *  or null if no stylesheet is on the stylesheets stack.
+   */
+  Stylesheet getStylesheet()
+  {
+    return (m_stylesheets.size() == 0)
+           ? null : (Stylesheet) m_stylesheets.peek();
+  }
+
+  /**
+   * Return the last stylesheet that was popped off the stylesheets stack.
+   *
+   * @return The last popped stylesheet, or null.
+   */
+  Stylesheet getLastPoppedStylesheet()
+  {
+    return m_lastPoppedStylesheet;
+  }
+
+  /**
+   * Return the stylesheet root that this handler is constructing.
+   *
+   * @return The root stylesheet of the stylesheets tree.
+   */
+  public StylesheetRoot getStylesheetRoot()
+  {
+    if (m_stylesheetRoot != null){
+        m_stylesheetRoot.setOptimizer(m_optimize);
+        m_stylesheetRoot.setIncremental(m_incremental);
+        m_stylesheetRoot.setSource_location(m_source_location);  		
+    }
+    return m_stylesheetRoot;
+  }
+
+  /** The root stylesheet of the stylesheets tree. */
+  StylesheetRoot m_stylesheetRoot;
+        
+        /** The last stylesheet that was popped off the stylesheets stack. */
+  Stylesheet m_lastPoppedStylesheet;
+
+  /**
+   * Push the current stylesheet being constructed. If no other stylesheets
+   * have been pushed onto the stack, assume the argument is a stylesheet
+   * root, and also set the stylesheet root member.
+   *
+   * @param s non-null reference to a stylesheet.
+   */
+  public void pushStylesheet(Stylesheet s)
+  {
+
+    if (m_stylesheets.size() == 0)
+      m_stylesheetRoot = (StylesheetRoot) s;
+
+    m_stylesheets.push(s);
+  }
+
+  /**
+   * Pop the last stylesheet pushed, and return the stylesheet that this
+   * handler is constructing, and set the last popped stylesheet member.
+   * Also pop the stylesheet locator stack.
+   *
+   * @return The stylesheet popped off the stack, or the last popped stylesheet.
+   */
+  Stylesheet popStylesheet()
+  {
+
+    // The stylesheetLocatorStack needs to be popped because
+    // a locator was pushed in for this stylesheet by the SAXparser by calling
+    // setDocumentLocator().
+    if (!m_stylesheetLocatorStack.isEmpty())
+      m_stylesheetLocatorStack.pop();
+
+    if (!m_stylesheets.isEmpty())
+      m_lastPoppedStylesheet = (Stylesheet) m_stylesheets.pop();
+
+    // Shouldn't this be null if stylesheets is empty?  -sb
+    return m_lastPoppedStylesheet;
+  }
+
+  /**
+   * The stack of current processors.
+   */
+  private Stack m_processors = new Stack();
+
+  /**
+   * Get the current XSLTElementProcessor at the top of the stack.
+   *
+   * @return Valid XSLTElementProcessor, which should never be null.
+   */
+  XSLTElementProcessor getCurrentProcessor()
+  {
+    return (XSLTElementProcessor) m_processors.peek();
+  }
+
+  /**
+   * Push the current XSLTElementProcessor onto the top of the stack.
+   *
+   * @param processor non-null reference to the current element processor.
+   */
+  void pushProcessor(XSLTElementProcessor processor)
+  {
+    m_processors.push(processor);
+  }
+
+  /**
+   * Pop the current XSLTElementProcessor from the top of the stack.
+   * @return the XSLTElementProcessor which was popped.
+   */
+  XSLTElementProcessor popProcessor()
+  {
+    return (XSLTElementProcessor) m_processors.pop();
+  }
+
+  /**
+   * The root of the XSLT Schema, which tells us how to
+   * transition content handlers, create elements, etc.
+   * For the moment at least, this can't be static, since
+   * the processors store state.
+   */
+  private XSLTSchema m_schema = new XSLTSchema();
+
+  /**
+   * Get the root of the XSLT Schema, which tells us how to
+   * transition content handlers, create elements, etc.
+   *
+   * @return The root XSLT Schema, which should never be null.
+   * @xsl.usage internal
+   */
+  public XSLTSchema getSchema()
+  {
+    return m_schema;
+  }
+
+  /**
+   * The stack of elements, pushed and popped as events occur.
+   */
+  private Stack m_elems = new Stack();
+
+  /**
+   * Get the current ElemTemplateElement at the top of the stack.
+   * @return Valid ElemTemplateElement, which may be null.
+   */
+  ElemTemplateElement getElemTemplateElement()
+  {
+
+    try
+    {
+      return (ElemTemplateElement) m_elems.peek();
+    }
+    catch (java.util.EmptyStackException ese)
+    {
+      return null;
+    }
+  }  
+
+  /** An increasing number that is used to indicate the order in which this element
+   *  was encountered during the parse of the XSLT tree.
+   */
+  private int m_docOrderCount = 0;
+
+  /**
+   * Returns the next m_docOrderCount number and increments the number for future use.
+   */
+  int nextUid()
+  {
+    return m_docOrderCount++;
+  }
+
+  /**
+   * Push the current XSLTElementProcessor to the top of the stack.  As a
+   * side-effect, set the document order index (simply because this is a
+   * convenient place to set it).
+   *
+   * @param elem Should be a non-null reference to the intended current
+   * template element.
+   */
+  void pushElemTemplateElement(ElemTemplateElement elem)
+  {
+
+    if (elem.getUid() == -1)
+      elem.setUid(nextUid());
+
+    m_elems.push(elem);
+  }
+
+  /**
+   * Get the current XSLTElementProcessor from the top of the stack.
+   * @return the ElemTemplateElement which was popped.
+   */
+  ElemTemplateElement popElemTemplateElement()
+  {
+    return (ElemTemplateElement) m_elems.pop();
+  }
+
+  /**
+   * This will act as a stack to keep track of the
+   * current include base.
+   */
+  Stack m_baseIdentifiers = new Stack();
+
+  /**
+   * Push a base identifier onto the base URI stack.
+   *
+   * @param baseID The current base identifier for this position in the
+   * stylesheet, which may be a fragment identifier, or which may be null.
+   * @see <a href="http://www.w3.org/TR/xslt#base-uri">
+   * Section 3.2 Base URI of XSLT specification.</a>
+   */
+  void pushBaseIndentifier(String baseID)
+  {
+
+    if (null != baseID)
+    {
+      int posOfHash = baseID.indexOf('#');
+
+      if (posOfHash > -1)
+      {
+        m_fragmentIDString = baseID.substring(posOfHash + 1);
+        m_shouldProcess = false;
+      }
+      else
+        m_shouldProcess = true;
+    }
+    else
+      m_shouldProcess = true;
+
+    m_baseIdentifiers.push(baseID);
+  }
+
+  /**
+   * Pop a base URI from the stack.
+   * @return baseIdentifier.
+   */
+  String popBaseIndentifier()
+  {
+    return (String) m_baseIdentifiers.pop();
+  }
+
+  /**
+   * Return the base identifier.
+   *
+   * @return The base identifier of the current stylesheet.
+   */
+  public String getBaseIdentifier()
+  {
+
+    // Try to get the baseIdentifier from the baseIdentifier's stack,
+    // which may not be the same thing as the value found in the
+    // SourceLocators stack.
+    String base = (String) (m_baseIdentifiers.isEmpty()
+                            ? null : m_baseIdentifiers.peek());
+
+    // Otherwise try the stylesheet.
+    if (null == base)
+    {
+      SourceLocator locator = getLocator();
+
+      base = (null == locator) ? "" : locator.getSystemId();
+    }
+
+    return base;
+  }
+
+  /**
+   * The top of this stack should contain the currently processed
+   * stylesheet SAX locator object.
+   */
+  private Stack m_stylesheetLocatorStack = new Stack();
+
+  /**
+   * Get the current stylesheet Locator object.
+   *
+   * @return non-null reference to the current locator object.
+   */
+  public SAXSourceLocator getLocator()
+  {
+
+    if (m_stylesheetLocatorStack.isEmpty())
+    {
+      SAXSourceLocator locator = new SAXSourceLocator();
+
+      locator.setSystemId(this.getStylesheetProcessor().getDOMsystemID());
+
+      return locator;
+
+      // m_stylesheetLocatorStack.push(locator);
+    }
+
+    return ((SAXSourceLocator) m_stylesheetLocatorStack.peek());
+  }
+
+  /**
+   * A stack of URL hrefs for imported stylesheets.  This is
+   * used to diagnose circular imports.
+   */
+  private Stack m_importStack = new Stack();
+  
+  /**
+   * A stack of Source objects obtained from a URIResolver,
+   * for each element in this stack there is a 1-1 correspondence
+   * with an element in the m_importStack.
+   */
+  private Stack m_importSourceStack = new Stack();
+
+  /**
+   * Push an import href onto the stylesheet stack.
+   *
+   * @param hrefUrl non-null reference to the URL for the current imported
+   * stylesheet.
+   */
+  void pushImportURL(String hrefUrl)
+  {
+    m_importStack.push(hrefUrl);
+  }
+  
+  /**
+   * Push the Source of an import href onto the stylesheet stack,
+   * obtained from a URIResolver, null if there is no URIResolver,
+   * or if that resolver returned null.
+   */
+  void pushImportSource(Source sourceFromURIResolver)
+  {
+    m_importSourceStack.push(sourceFromURIResolver);
+  }
+
+  /**
+   * See if the imported stylesheet stack already contains
+   * the given URL.  Used to test for recursive imports.
+   *
+   * @param hrefUrl non-null reference to a URL string.
+   *
+   * @return true if the URL is on the import stack.
+   */
+  boolean importStackContains(String hrefUrl)
+  {
+    return stackContains(m_importStack, hrefUrl);
+  }
+
+  /**
+   * Pop an import href from the stylesheet stack.
+   *
+   * @return non-null reference to the import URL that was popped.
+   */
+  String popImportURL()
+  {
+    return (String) m_importStack.pop();
+  }
+  
+  String peekImportURL()
+  {
+    return (String) m_importStack.peek();
+  }
+  
+  Source peekSourceFromURIResolver()
+  {
+    return (Source) m_importSourceStack.peek();
+  }
+  
+  /**
+   * Pop a Source from a user provided URIResolver, corresponding
+   * to the URL popped from the m_importStack.
+   */
+  Source popImportSource()
+  {
+    return (Source) m_importSourceStack.pop();
+  }
+
+  /**
+   * If this is set to true, we've already warned about using the
+   * older XSLT namespace URL.
+   */
+  private boolean warnedAboutOldXSLTNamespace = false;
+
+  /** Stack of NamespaceSupport objects. */
+  Stack m_nsSupportStack = new Stack();
+
+  /**
+   * Push a new NamespaceSupport instance.
+   */
+  void pushNewNamespaceSupport()
+  {
+    m_nsSupportStack.push(new NamespaceSupport2());
+  }
+
+  /**
+   * Pop the current NamespaceSupport object.
+   *
+   */
+  void popNamespaceSupport()
+  {
+    m_nsSupportStack.pop();
+  }
+
+  /**
+   * Get the current NamespaceSupport object.
+   *
+   * @return a non-null reference to the current NamespaceSupport object,
+   * which is the top of the namespace support stack.
+   */
+  NamespaceSupport getNamespaceSupport()
+  {
+    return (NamespaceSupport) m_nsSupportStack.peek();
+  }
+
+  /**
+   * The originating node if the current stylesheet is being created
+   *  from a DOM.
+   *  @see org.apache.xml.utils.NodeConsumer
+   */
+  private Node m_originatingNode;
+
+  /**
+   * Set the node that is originating the SAX event.
+   *
+   * @param n Reference to node that originated the current event.
+   * @see org.apache.xml.utils.NodeConsumer
+   */
+  public void setOriginatingNode(Node n)
+  {
+    m_originatingNode = n;
+  }
+
+  /**
+   * Set the node that is originating the SAX event.
+   *
+   * @return Reference to node that originated the current event.
+   * @see org.apache.xml.utils.NodeConsumer
+   */
+  public Node getOriginatingNode()
+  {
+    return m_originatingNode;
+  }
+  
+  /**
+   * Stack of booleans that are pushed and popped in start/endElement depending 
+   * on the value of xml:space=default/preserve.
+   */
+  private BoolStack m_spacePreserveStack = new BoolStack();
+  
+  /**
+   * Return boolean value from the spacePreserve stack depending on the value 
+   * of xml:space=default/preserve.
+   * 
+   * @return true if space should be preserved, false otherwise.
+   */
+  boolean isSpacePreserve()
+  {
+    return m_spacePreserveStack.peek();
+  }
+  
+  /**
+   * Pop boolean value from the spacePreserve stack.
+   */
+  void popSpaceHandling()
+  {
+    m_spacePreserveStack.pop();
+  }
+  
+  /**
+   * Push boolean value on to the spacePreserve stack.
+   * 
+   * @param b true if space should be preserved, false otherwise.
+   */
+  void pushSpaceHandling(boolean b)
+    throws org.xml.sax.SAXParseException
+  {
+    m_spacePreserveStack.push(b);
+  }
+  
+  /**
+   * Push boolean value on to the spacePreserve stack depending on the value 
+   * of xml:space=default/preserve.
+   * 
+   * @param attrs list of attributes that were passed to startElement.
+   */
+  void pushSpaceHandling(Attributes attrs)
+    throws org.xml.sax.SAXParseException
+  {    
+    String value = attrs.getValue("xml:space");
+    if(null == value)
+    {
+      m_spacePreserveStack.push(m_spacePreserveStack.peekOrFalse());
+    }
+    else if(value.equals("preserve"))
+    {
+      m_spacePreserveStack.push(true);
+    }
+    else if(value.equals("default"))
+    {
+      m_spacePreserveStack.push(false);
+    }
+    else
+    {
+      SAXSourceLocator locator = getLocator();
+      ErrorListener handler = m_stylesheetProcessor.getErrorListener();
+  
+      try
+      {
+        handler.error(new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ILLEGAL_XMLSPACE_VALUE, null), locator)); //"Illegal value for xml:space", locator));
+      }
+      catch (TransformerException te)
+      {
+        throw new org.xml.sax.SAXParseException(te.getMessage(), locator, te);
+      }
+      m_spacePreserveStack.push(m_spacePreserveStack.peek());
+    }
+  }
+  
+  private double getElemVersion()
+  {
+    ElemTemplateElement elem = getElemTemplateElement();
+    double version = -1; 
+    while ((version == -1 || version == Constants.XSLTVERSUPPORTED) && elem != null)
+    {
+      try{
+      version = Double.valueOf(elem.getXmlVersion()).doubleValue();
+      }
+      catch (Exception ex)
+      {
+        version = -1;
+      }
+      elem = elem.getParentElem();
+      }
+    return (version == -1)? Constants.XSLTVERSUPPORTED : version;
+  }
+    /**
+     * @see PrefixResolver#handlesNullPrefixes()
+     */
+    public boolean handlesNullPrefixes() {
+        return false;
+    }
+
+    /**
+     * @return Optimization flag
+     */
+    public boolean getOptimize() {
+        return m_optimize;
+    }
+
+    /**
+     * @return Incremental flag
+     */
+    public boolean getIncremental() {
+        return m_incremental;
+    }
+
+    /**
+     * @return Source Location flag
+     */
+    public boolean getSource_location() {
+        return m_source_location;
+    }
+
+}
+
+
+
diff --git a/src/main/java/org/apache/xalan/processor/TransformerFactoryImpl.java b/src/main/java/org/apache/xalan/processor/TransformerFactoryImpl.java
new file mode 100644
index 0000000..618b412
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/TransformerFactoryImpl.java
@@ -0,0 +1,1043 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformerFactoryImpl.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TemplatesHandler;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TrAXFilter;
+import org.apache.xalan.transformer.TransformerIdentityImpl;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.transformer.XalanProperties;
+
+import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
+import org.apache.xml.utils.DefaultErrorHandler;
+import org.apache.xml.utils.SystemIDResolver;
+import org.apache.xml.utils.TreeWalker;
+import org.apache.xml.utils.StylesheetPIHandler;
+import org.apache.xml.utils.StopParseException;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * The TransformerFactoryImpl, which implements the TRaX TransformerFactory
+ * interface, processes XSLT stylesheets into a Templates object
+ * (a StylesheetRoot).
+ */
+public class TransformerFactoryImpl extends SAXTransformerFactory
+{
+  /** 
+   * The path/filename of the property file: XSLTInfo.properties  
+   * Maintenance note: see also
+   * <code>org.apache.xpath.functions.FuncSystemProperty.XSLT_PROPERTIES</code>
+   */
+  public static final String XSLT_PROPERTIES =
+    "org/apache/xalan/res/XSLTInfo.properties";
+
+  /**
+   * <p>State of secure processing feature.</p>
+   */
+  private boolean m_isSecureProcessing = false;
+
+  /**
+   * Constructor TransformerFactoryImpl
+   *
+   */
+  public TransformerFactoryImpl()
+  {
+  }
+
+  /** Static string to be used for incremental feature */
+  public static final String FEATURE_INCREMENTAL =
+                             "http://xml.apache.org/xalan/features/incremental";
+
+  /** Static string to be used for optimize feature */
+  public static final String FEATURE_OPTIMIZE =
+                             "http://xml.apache.org/xalan/features/optimize";
+
+  /** Static string to be used for source_location feature */
+  public static final String FEATURE_SOURCE_LOCATION =
+                             XalanProperties.SOURCE_LOCATION;
+
+  public javax.xml.transform.Templates processFromNode(Node node)
+          throws TransformerConfigurationException
+  {
+
+    try
+    {
+      TemplatesHandler builder = newTemplatesHandler();
+      TreeWalker walker = new TreeWalker(builder,
+                                         new org.apache.xml.utils.DOM2Helper(),
+                                         builder.getSystemId());
+
+      walker.traverse(node);
+
+      return builder.getTemplates();
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      if (m_errorListener != null)
+      {
+        try
+        {
+          m_errorListener.fatalError(new TransformerException(se));
+        }
+        catch (TransformerConfigurationException ex)
+        {
+          throw ex;
+        }
+        catch (TransformerException ex)
+        {
+          throw new TransformerConfigurationException(ex);
+        }
+
+        return null;
+      }
+      else
+      {
+
+        // Should remove this later... but right now diagnostics from 
+        // TransformerConfigurationException are not good.
+        // se.printStackTrace();
+        throw new TransformerConfigurationException(XSLMessages.createMessage(XSLTErrorResources.ER_PROCESSFROMNODE_FAILED, null), se); 
+        //"processFromNode failed", se);
+      }
+    }
+    catch (TransformerConfigurationException tce)
+    {
+      // Assume it's already been reported to the error listener.
+      throw tce;
+    }
+   /* catch (TransformerException tce)
+    {
+      // Assume it's already been reported to the error listener.
+      throw new TransformerConfigurationException(tce.getMessage(), tce);
+    }*/
+    catch (Exception e)
+    {
+      if (m_errorListener != null)
+      {
+        try
+        {
+          m_errorListener.fatalError(new TransformerException(e));
+        }
+        catch (TransformerConfigurationException ex)
+        {
+          throw ex;
+        }
+        catch (TransformerException ex)
+        {
+          throw new TransformerConfigurationException(ex);
+        }
+
+        return null;
+      }
+      else
+      {
+        // Should remove this later... but right now diagnostics from 
+        // TransformerConfigurationException are not good.
+        // se.printStackTrace();
+        throw new TransformerConfigurationException(XSLMessages.createMessage(XSLTErrorResources.ER_PROCESSFROMNODE_FAILED, null), e); //"processFromNode failed",
+                                                    //e);
+      }
+    }
+  }
+
+  /**
+   * The systemID that was specified in
+   * processFromNode(Node node, String systemID).
+   */
+  private String m_DOMsystemID = null;
+
+  /**
+   * The systemID that was specified in
+   * processFromNode(Node node, String systemID).
+   *
+   * @return The systemID, or null.
+   */
+  String getDOMsystemID()
+  {
+    return m_DOMsystemID;
+  }
+
+  /**
+   * Process the stylesheet from a DOM tree, if the
+   * processor supports the "http://xml.org/trax/features/dom/input"
+   * feature.
+   *
+   * @param node A DOM tree which must contain
+   * valid transform instructions that this processor understands.
+   * @param systemID The systemID from where xsl:includes and xsl:imports
+   * should be resolved from.
+   *
+   * @return A Templates object capable of being used for transformation purposes.
+   *
+   * @throws TransformerConfigurationException
+   */
+  javax.xml.transform.Templates processFromNode(Node node, String systemID)
+          throws TransformerConfigurationException
+  {
+
+    m_DOMsystemID = systemID;
+
+    return processFromNode(node);
+  }
+
+  /**
+   * Get InputSource specification(s) that are associated with the
+   * given document specified in the source param,
+   * via the xml-stylesheet processing instruction
+   * (see http://www.w3.org/TR/xml-stylesheet/), and that matches
+   * the given criteria.  Note that it is possible to return several stylesheets
+   * that match the criteria, in which case they are applied as if they were
+   * a list of imports or cascades.
+   *
+   * <p>Note that DOM2 has it's own mechanism for discovering stylesheets.
+   * Therefore, there isn't a DOM version of this method.</p>
+   *
+   *
+   * @param source The XML source that is to be searched.
+   * @param media The media attribute to be matched.  May be null, in which
+   *              case the prefered templates will be used (i.e. alternate = no).
+   * @param title The value of the title attribute to match.  May be null.
+   * @param charset The value of the charset attribute to match.  May be null.
+   *
+   * @return A Source object capable of being used to create a Templates object.
+   *
+   * @throws TransformerConfigurationException
+   */
+  public Source getAssociatedStylesheet(
+          Source source, String media, String title, String charset)
+            throws TransformerConfigurationException
+  {
+
+    String baseID;
+    InputSource isource = null;
+    Node node = null;
+    XMLReader reader = null;
+
+    if (source instanceof DOMSource)
+    {
+      DOMSource dsource = (DOMSource) source;
+
+      node = dsource.getNode();
+      baseID = dsource.getSystemId();
+    }
+    else
+    {
+      isource = SAXSource.sourceToInputSource(source);
+      baseID = isource.getSystemId();
+    }
+
+    // What I try to do here is parse until the first startElement
+    // is found, then throw a special exception in order to terminate 
+    // the parse.
+    StylesheetPIHandler handler = new StylesheetPIHandler(baseID, media,
+                                    title, charset);
+    
+    // Use URIResolver. Patch from Dmitri Ilyin 
+    if (m_uriResolver != null) 
+    {
+      handler.setURIResolver(m_uriResolver); 
+    }
+
+    try
+    {
+      if (null != node)
+      {
+        TreeWalker walker = new TreeWalker(handler, new org.apache.xml.utils.DOM2Helper(), baseID);
+
+        walker.traverse(node);
+      }
+      else
+      {
+
+        // Use JAXP1.1 ( if possible )
+        try
+        {
+          javax.xml.parsers.SAXParserFactory factory =
+            javax.xml.parsers.SAXParserFactory.newInstance();
+
+          factory.setNamespaceAware(true);
+
+          if (m_isSecureProcessing)
+          {
+            try
+            {
+              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            }
+            catch (org.xml.sax.SAXException e) {}
+          }
+
+          javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
+
+          reader = jaxpParser.getXMLReader();
+        }
+        catch (javax.xml.parsers.ParserConfigurationException ex)
+        {
+          throw new org.xml.sax.SAXException(ex);
+        }
+        catch (javax.xml.parsers.FactoryConfigurationError ex1)
+        {
+          throw new org.xml.sax.SAXException(ex1.toString());
+        }
+        catch (NoSuchMethodError ex2){}
+        catch (AbstractMethodError ame){}
+
+        if (null == reader)
+        {
+          reader = XMLReaderFactory.createXMLReader();
+        }
+
+        // Need to set options!
+        reader.setContentHandler(handler);
+        reader.parse(isource);
+      }
+    }
+    catch (StopParseException spe)
+    {
+
+      // OK, good.
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerConfigurationException(
+        "getAssociatedStylesheets failed", se);
+    }
+    catch (IOException ioe)
+    {
+      throw new TransformerConfigurationException(
+        "getAssociatedStylesheets failed", ioe);
+    }
+
+    return handler.getAssociatedStylesheet();
+  }
+
+  /**
+   * Create a new Transformer object that performs a copy
+   * of the source to the result.
+   *
+   * @return A Transformer object that may be used to perform a transformation
+   * in a single thread, never null.
+   *
+   * @throws TransformerConfigurationException May throw this during
+   *            the parse when it is constructing the
+   *            Templates object and fails.
+   */
+  public TemplatesHandler newTemplatesHandler()
+          throws TransformerConfigurationException
+  {
+    return new StylesheetHandler(this);
+  }
+
+  /**
+   * <p>Set a feature for this <code>TransformerFactory</code> and <code>Transformer</code>s
+   * or <code>Template</code>s created by this factory.</p>
+   * 
+   * <p>
+   * Feature names are fully qualified {@link java.net.URI}s.
+   * Implementations may define their own features.
+   * An {@link TransformerConfigurationException} is thrown if this <code>TransformerFactory</code> or the
+   * <code>Transformer</code>s or <code>Template</code>s it creates cannot support the feature.
+   * It is possible for an <code>TransformerFactory</code> to expose a feature value but be unable to change its state.
+   * </p>
+   * 
+   * <p>See {@link javax.xml.transform.TransformerFactory} for full documentation of specific features.</p>
+   * 
+   * @param name Feature name.
+   * @param value Is feature state <code>true</code> or <code>false</code>.
+   *  
+   * @throws TransformerConfigurationException if this <code>TransformerFactory</code>
+   *   or the <code>Transformer</code>s or <code>Template</code>s it creates cannot support this feature.
+   * @throws NullPointerException If the <code>name</code> parameter is null.
+   */
+  public void setFeature(String name, boolean value)
+	  throws TransformerConfigurationException {
+  
+  	// feature name cannot be null
+  	if (name == null) {
+  	    throw new NullPointerException(
+                  XSLMessages.createMessage(
+                      XSLTErrorResources.ER_SET_FEATURE_NULL_NAME, null));    
+  	}
+  		
+  	// secure processing?
+  	if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+  	    m_isSecureProcessing = value;			
+  	}
+  	// This implementation does not support the setting of a feature other than
+  	// the secure processing feature.
+  	else
+    {
+      throw new TransformerConfigurationException(
+          XSLMessages.createMessage(
+            XSLTErrorResources.ER_UNSUPPORTED_FEATURE, 
+            new Object[] {name}));
+    }
+  }
+
+  /**
+   * Look up the value of a feature.
+   * <p>The feature name is any fully-qualified URI.  It is
+   * possible for an TransformerFactory to recognize a feature name but
+   * to be unable to return its value; this is especially true
+   * in the case of an adapter for a SAX1 Parser, which has
+   * no way of knowing whether the underlying parser is
+   * validating, for example.</p>
+   *
+   * @param name The feature name, which is a fully-qualified URI.
+   * @return The current state of the feature (true or false).
+   */
+  public boolean getFeature(String name) {
+  	
+    // feature name cannot be null
+    if (name == null) 
+    {
+    	throw new NullPointerException(
+            XSLMessages.createMessage(
+            XSLTErrorResources.ER_GET_FEATURE_NULL_NAME, null));    
+    }
+	  	
+    // Try first with identity comparison, which 
+    // will be faster.
+    if ((DOMResult.FEATURE == name) || (DOMSource.FEATURE == name)
+            || (SAXResult.FEATURE == name) || (SAXSource.FEATURE == name)
+            || (StreamResult.FEATURE == name)
+            || (StreamSource.FEATURE == name)
+            || (SAXTransformerFactory.FEATURE == name)
+            || (SAXTransformerFactory.FEATURE_XMLFILTER == name))
+      return true;
+    else if ((DOMResult.FEATURE.equals(name))
+             || (DOMSource.FEATURE.equals(name))
+             || (SAXResult.FEATURE.equals(name))
+             || (SAXSource.FEATURE.equals(name))
+             || (StreamResult.FEATURE.equals(name))
+             || (StreamSource.FEATURE.equals(name))
+             || (SAXTransformerFactory.FEATURE.equals(name))
+             || (SAXTransformerFactory.FEATURE_XMLFILTER.equals(name)))
+      return true;	      
+    // secure processing?
+    else if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING))
+      return m_isSecureProcessing;
+    else      
+      // unknown feature
+      return false;
+  }
+  
+  /**
+   * Flag set by FEATURE_OPTIMIZE.
+   * This feature specifies whether to Optimize stylesheet processing. By
+   * default it is set to true.
+   */
+  private boolean m_optimize = true;
+  
+  /** Flag set by FEATURE_SOURCE_LOCATION.
+   * This feature specifies whether the transformation phase should
+   * keep track of line and column numbers for the input source
+   * document. Note that this works only when that
+   * information is available from the source -- in other words, if you
+   * pass in a DOM, there's little we can do for you.
+   * 
+   * The default is false. Setting it true may significantly
+   * increase storage cost per node. 
+   */
+  private boolean m_source_location = false;
+  
+  /**
+   * Flag set by FEATURE_INCREMENTAL.
+   * This feature specifies whether to produce output incrementally, rather than
+   * waiting to finish parsing the input before generating any output. By 
+   * default this attribute is set to false. 
+   */
+  private boolean m_incremental = false;
+  
+  /**
+   * Allows the user to set specific attributes on the underlying
+   * implementation.
+   *
+   * @param name The name of the attribute.
+   * @param value The value of the attribute; Boolean or String="true"|"false"
+   *
+   * @throws IllegalArgumentException thrown if the underlying
+   * implementation doesn't recognize the attribute.
+   */
+  public void setAttribute(String name, Object value)
+          throws IllegalArgumentException
+  {
+    if (name.equals(FEATURE_INCREMENTAL))
+    {
+      if(value instanceof Boolean)
+      {
+        // Accept a Boolean object..
+        m_incremental = ((Boolean)value).booleanValue();
+      }
+      else if(value instanceof String)
+      {
+        // .. or a String object
+        m_incremental = (new Boolean((String)value)).booleanValue();
+      }
+      else
+      {
+        // Give a more meaningful error message
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
+      }
+	}
+    else if (name.equals(FEATURE_OPTIMIZE))
+    {
+      if(value instanceof Boolean)
+      {
+        // Accept a Boolean object..
+        m_optimize = ((Boolean)value).booleanValue();
+      }
+      else if(value instanceof String)
+      {
+        // .. or a String object
+        m_optimize = (new Boolean((String)value)).booleanValue();
+      }
+      else
+      {
+        // Give a more meaningful error message
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
+      }
+    }
+    
+    // Custom Xalan feature: annotate DTM with SAX source locator fields.
+    // This gets used during SAX2DTM instantiation. 
+    //
+    // %REVIEW% Should the name of this field really be in XalanProperties?
+    // %REVIEW% I hate that it's a global static, but didn't want to change APIs yet.
+    else if(name.equals(FEATURE_SOURCE_LOCATION))
+    {
+      if(value instanceof Boolean)
+      {
+        // Accept a Boolean object..
+        m_source_location = ((Boolean)value).booleanValue();
+      }
+      else if(value instanceof String)
+      {
+        // .. or a String object
+        m_source_location = (new Boolean((String)value)).booleanValue();
+      }
+      else
+      {
+        // Give a more meaningful error message
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
+      }
+    }
+    
+    else
+    {
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUPPORTED, new Object[]{name})); //name + "not supported");
+    }
+  }
+
+  /**
+   * Allows the user to retrieve specific attributes on the underlying
+   * implementation.
+   *
+   * @param name The name of the attribute.
+   * @return value The value of the attribute.
+   *
+   * @throws IllegalArgumentException thrown if the underlying
+   * implementation doesn't recognize the attribute.
+   */
+  public Object getAttribute(String name) throws IllegalArgumentException
+  {
+    if (name.equals(FEATURE_INCREMENTAL))
+    {
+      return new Boolean(m_incremental);            
+    }
+    else if (name.equals(FEATURE_OPTIMIZE))
+    {
+      return new Boolean(m_optimize);
+    }
+    else if (name.equals(FEATURE_SOURCE_LOCATION))
+    {
+      return new Boolean(m_source_location);
+    }
+    else
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_ATTRIB_VALUE_NOT_RECOGNIZED, new Object[]{name})); //name + " attribute not recognized");
+  }
+
+  /**
+   * Create an XMLFilter that uses the given source as the
+   * transformation instructions.
+   *
+   * @param src The source of the transformation instructions.
+   *
+   * @return An XMLFilter object, or null if this feature is not supported.
+   *
+   * @throws TransformerConfigurationException
+   */
+  public XMLFilter newXMLFilter(Source src)
+          throws TransformerConfigurationException
+  {
+
+    Templates templates = newTemplates(src);
+    if( templates==null ) return null;
+    
+    return newXMLFilter(templates);
+  }
+
+  /**
+   * Create an XMLFilter that uses the given source as the
+   * transformation instructions.
+   *
+   * @param templates non-null reference to Templates object.
+   *
+   * @return An XMLFilter object, or null if this feature is not supported.
+   *
+   * @throws TransformerConfigurationException
+   */
+  public XMLFilter newXMLFilter(Templates templates)
+          throws TransformerConfigurationException
+  {
+    try 
+    {
+      return new TrAXFilter(templates);
+    } 
+    catch( TransformerConfigurationException ex ) 
+    {
+      if( m_errorListener != null) 
+      {
+        try 
+        {
+          m_errorListener.fatalError( ex );
+          return null;
+        } 
+        catch( TransformerConfigurationException ex1 ) 
+        {
+          throw ex1;
+        }
+        catch( TransformerException ex1 ) 
+        {
+          throw new TransformerConfigurationException(ex1);
+        }
+      }
+      throw ex;
+    }
+  }
+
+  /**
+   * Get a TransformerHandler object that can process SAX
+   * ContentHandler events into a Result, based on the transformation
+   * instructions specified by the argument.
+   *
+   * @param src The source of the transformation instructions.
+   *
+   * @return TransformerHandler ready to transform SAX events.
+   *
+   * @throws TransformerConfigurationException
+   */
+  public TransformerHandler newTransformerHandler(Source src)
+          throws TransformerConfigurationException
+  {
+
+    Templates templates = newTemplates(src);
+    if( templates==null ) return null;
+    
+    return newTransformerHandler(templates);
+  }
+
+  /**
+   * Get a TransformerHandler object that can process SAX
+   * ContentHandler events into a Result, based on the Templates argument.
+   *
+   * @param templates The source of the transformation instructions.
+   *
+   * @return TransformerHandler ready to transform SAX events.
+   * @throws TransformerConfigurationException
+   */
+  public TransformerHandler newTransformerHandler(Templates templates)
+          throws TransformerConfigurationException
+  {
+    try {
+      TransformerImpl transformer =
+        (TransformerImpl) templates.newTransformer();
+      transformer.setURIResolver(m_uriResolver);
+      TransformerHandler th =
+        (TransformerHandler) transformer.getInputContentHandler(true);
+
+      return th;
+    } 
+    catch( TransformerConfigurationException ex ) 
+    {
+      if( m_errorListener != null ) 
+      {
+        try 
+        {
+          m_errorListener.fatalError( ex );
+          return null;
+        } 
+        catch (TransformerConfigurationException ex1 ) 
+        {
+          throw ex1;
+        }
+        catch (TransformerException ex1 ) 
+        {
+          throw new TransformerConfigurationException(ex1);
+        }
+      }
+      
+      throw ex;
+    }
+    
+  }
+
+//  /** The identity transform string, for support of newTransformerHandler()
+//   *  and newTransformer().  */
+//  private static final String identityTransform =
+//    "<xsl:stylesheet " + "xmlns:xsl='http://www.w3.org/1999/XSL/Transform' "
+//    + "version='1.0'>" + "<xsl:template match='/|node()'>"
+//    + "<xsl:copy-of select='.'/>" + "</xsl:template>" + "</xsl:stylesheet>";
+//
+//  /** The identity transform Templates, built from identityTransform, 
+//   *  for support of newTransformerHandler() and newTransformer().  */
+//  private static Templates m_identityTemplate = null;
+
+  /**
+   * Get a TransformerHandler object that can process SAX
+   * ContentHandler events into a Result.
+   *
+   * @return TransformerHandler ready to transform SAX events.
+   *
+   * @throws TransformerConfigurationException
+   */
+  public TransformerHandler newTransformerHandler()
+          throws TransformerConfigurationException
+  {
+    return new TransformerIdentityImpl(m_isSecureProcessing);
+  }
+
+  /**
+   * Process the source into a Transformer object.  Care must
+   * be given to know that this object can not be used concurrently
+   * in multiple threads.
+   *
+   * @param source An object that holds a URL, input stream, etc.
+   *
+   * @return A Transformer object capable of
+   * being used for transformation purposes in a single thread.
+   *
+   * @throws TransformerConfigurationException May throw this during the parse when it
+   *            is constructing the Templates object and fails.
+   */
+  public Transformer newTransformer(Source source)
+          throws TransformerConfigurationException
+  {
+    try 
+    {
+      Templates tmpl=newTemplates( source );
+      /* this can happen if an ErrorListener is present and it doesn't
+         throw any exception in fatalError. 
+         The spec says: "a Transformer must use this interface
+         instead of throwing an exception" - the newTemplates() does
+         that, and returns null.
+      */
+      if( tmpl==null ) return null;
+      Transformer transformer = tmpl.newTransformer();
+      transformer.setURIResolver(m_uriResolver);
+      return transformer;
+    } 
+    catch( TransformerConfigurationException ex ) 
+    {
+      if( m_errorListener != null ) 
+      {
+        try 
+        {
+          m_errorListener.fatalError( ex );
+          return null; // TODO: but the API promises to never return null...
+        } 
+        catch( TransformerConfigurationException ex1 ) 
+        {
+          throw ex1;
+        }
+        catch( TransformerException ex1 ) 
+        {
+          throw new TransformerConfigurationException( ex1 );
+        }
+      }
+      throw ex;
+    }
+  }
+
+  /**
+   * Create a new Transformer object that performs a copy
+   * of the source to the result.
+   *
+   * @return A Transformer object capable of
+   * being used for transformation purposes in a single thread.
+   *
+   * @throws TransformerConfigurationException May throw this during
+   *            the parse when it is constructing the
+   *            Templates object and it fails.
+   */
+  public Transformer newTransformer() throws TransformerConfigurationException
+  {
+      return new TransformerIdentityImpl(m_isSecureProcessing);
+  }
+
+  /**
+   * Process the source into a Templates object, which is likely
+   * a compiled representation of the source. This Templates object
+   * may then be used concurrently across multiple threads.  Creating
+   * a Templates object allows the TransformerFactory to do detailed
+   * performance optimization of transformation instructions, without
+   * penalizing runtime transformation.
+   *
+   * @param source An object that holds a URL, input stream, etc.
+   * @return A Templates object capable of being used for transformation purposes.
+   *
+   * @throws TransformerConfigurationException May throw this during the parse when it
+   *            is constructing the Templates object and fails.
+   */
+  public Templates newTemplates(Source source)
+          throws TransformerConfigurationException
+  {
+
+    String baseID = source.getSystemId();
+
+    if (null != baseID) {
+       baseID = SystemIDResolver.getAbsoluteURI(baseID);
+    }
+
+
+    if (source instanceof DOMSource)
+    {
+      DOMSource dsource = (DOMSource) source;
+      Node node = dsource.getNode();
+
+      if (null != node)
+        return processFromNode(node, baseID);
+      else
+      {
+        String messageStr = XSLMessages.createMessage(
+          XSLTErrorResources.ER_ILLEGAL_DOMSOURCE_INPUT, null);
+
+        throw new IllegalArgumentException(messageStr);
+      }
+    }
+
+    TemplatesHandler builder = newTemplatesHandler();
+    builder.setSystemId(baseID);
+    
+    try
+    {
+      InputSource isource = SAXSource.sourceToInputSource(source);
+      isource.setSystemId(baseID);
+      XMLReader reader = null;
+
+      if (source instanceof SAXSource)
+        reader = ((SAXSource) source).getXMLReader();
+        
+      if (null == reader)
+      {
+
+        // Use JAXP1.1 ( if possible )
+        try
+        {
+          javax.xml.parsers.SAXParserFactory factory =
+            javax.xml.parsers.SAXParserFactory.newInstance();
+
+          factory.setNamespaceAware(true);
+
+          if (m_isSecureProcessing)
+          {
+            try
+            {
+              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            }
+            catch (org.xml.sax.SAXException se) {}
+          }
+
+          javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
+
+          reader = jaxpParser.getXMLReader();
+        }
+        catch (javax.xml.parsers.ParserConfigurationException ex)
+        {
+          throw new org.xml.sax.SAXException(ex);
+        }
+        catch (javax.xml.parsers.FactoryConfigurationError ex1)
+        {
+          throw new org.xml.sax.SAXException(ex1.toString());
+        }
+        catch (NoSuchMethodError ex2){}
+        catch (AbstractMethodError ame){}
+      }
+
+      if (null == reader)
+        reader = XMLReaderFactory.createXMLReader();
+
+      // If you set the namespaces to true, we'll end up getting double 
+      // xmlns attributes.  Needs to be fixed.  -sb
+      // reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+      reader.setContentHandler(builder);
+      reader.parse(isource);
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      if (m_errorListener != null)
+      {
+        try
+        {
+          m_errorListener.fatalError(new TransformerException(se));
+        }
+        catch (TransformerConfigurationException ex1)
+        {
+          throw ex1;
+        }
+        catch (TransformerException ex1)
+        {
+          throw new TransformerConfigurationException(ex1);
+        }
+      }
+      else
+      {
+        throw new TransformerConfigurationException(se.getMessage(), se);
+      }
+    }
+    catch (Exception e)
+    {
+      if (m_errorListener != null)
+      {
+        try
+        {
+          m_errorListener.fatalError(new TransformerException(e));
+          return null;
+        }
+        catch (TransformerConfigurationException ex1)
+        {
+          throw ex1;
+        }
+        catch (TransformerException ex1)
+        {
+          throw new TransformerConfigurationException(ex1);
+        }
+      }
+      else
+      {
+        throw new TransformerConfigurationException(e.getMessage(), e);
+      }
+    }
+
+    return builder.getTemplates();
+  }
+
+  /**
+   * The object that implements the URIResolver interface,
+   * or null.
+   */
+  URIResolver m_uriResolver;
+
+  /**
+   * Set an object that will be used to resolve URIs used in
+   * xsl:import, etc.  This will be used as the default for the
+   * transformation.
+   * @param resolver An object that implements the URIResolver interface,
+   * or null.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+    m_uriResolver = resolver;
+  }
+
+  /**
+   * Get the object that will be used to resolve URIs used in
+   * xsl:import, etc.  This will be used as the default for the
+   * transformation.
+   *
+   * @return The URIResolver that was set with setURIResolver.
+   */
+  public URIResolver getURIResolver()
+  {
+    return m_uriResolver;
+  }
+
+  /** The error listener.   */
+  private ErrorListener m_errorListener = new org.apache.xml.utils.DefaultErrorHandler(false);
+
+  /**
+   * Get the error listener in effect for the TransformerFactory.
+   *
+   * @return A non-null reference to an error listener.
+   */
+  public ErrorListener getErrorListener()
+  {
+    return m_errorListener;
+  }
+
+  /**
+   * Set an error listener for the TransformerFactory.
+   *
+   * @param listener Must be a non-null reference to an ErrorListener.
+   *
+   * @throws IllegalArgumentException if the listener argument is null.
+   */
+  public void setErrorListener(ErrorListener listener)
+          throws IllegalArgumentException
+  {
+
+    if (null == listener)
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_ERRORLISTENER, null));
+      // "ErrorListener");
+
+    m_errorListener = listener;
+  }
+  
+  /**
+   * Return the state of the secure processing feature.
+   * 
+   * @return state of the secure processing feature.
+   */
+  public boolean isSecureProcessing()
+  {
+    return m_isSecureProcessing;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/WhitespaceInfoPaths.java b/src/main/java/org/apache/xalan/processor/WhitespaceInfoPaths.java
new file mode 100644
index 0000000..086345c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/WhitespaceInfoPaths.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WhitespaceInfoPaths.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.Vector;
+
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.WhiteSpaceInfo;
+
+public class WhitespaceInfoPaths extends WhiteSpaceInfo
+{
+    static final long serialVersionUID = 5954766719577516723L;
+	
+  /**
+   * Bean property to allow setPropertiesFromAttributes to
+   * get the elements attribute.
+   */
+  private Vector m_elements;
+
+  /**
+   * Set from the elements attribute.  This is a list of 
+   * whitespace delimited element qualified names that specify
+   * preservation of whitespace.
+   *
+   * @param elems Should be a non-null reference to a list 
+   *              of {@link org.apache.xpath.XPath} objects.
+   */
+  public void setElements(Vector elems)
+  {
+    m_elements = elems;
+  }
+
+  /**
+   * Get the property set by setElements().  This is a list of 
+   * whitespace delimited element qualified names that specify
+   * preservation of whitespace.
+   *
+   * @return A reference to a list of {@link org.apache.xpath.XPath} objects, 
+   *         or null.
+   */
+  Vector getElements()
+  {
+    return m_elements;
+  }
+  
+  public void clearElements()
+  {
+  	m_elements = null;
+  }
+
+ /**
+   * Constructor WhitespaceInfoPaths
+   *
+   * @param thisSheet The current stylesheet
+   */
+  public WhitespaceInfoPaths(Stylesheet thisSheet)
+  {
+  	super(thisSheet);
+  	setStylesheet(thisSheet);
+  }
+
+
+}
+
diff --git a/src/main/java/org/apache/xalan/processor/XSLProcessorVersion.src b/src/main/java/org/apache/xalan/processor/XSLProcessorVersion.src
new file mode 100644
index 0000000..caae25d
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/XSLProcessorVersion.src
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLProcessorVersion.src 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+/**
+ * Administrative class to keep track of the version number of
+ * the Xalan release.
+ * <P>See also: org/apache/xalan/res/XSLTInfo.properties</P>
+ * @deprecated To be replaced by org.apache.xalan.Version.getVersion()
+ * @xsl.usage general
+ */
+public class XSLProcessorVersion
+{
+
+  /**
+   * Print the processor version to the command line.
+   *
+   * @param argv command line arguments, unused.
+   */
+  public static void main(String argv[])
+  {
+    System.out.println(S_VERSION);
+  }
+
+  /**
+   * Constant name of product.
+   */
+  public static final String PRODUCT = "Xalan";
+
+  /**
+   * Implementation Language.
+   */
+  public static final String LANGUAGE = "Java";
+
+  /**
+   * Major version number.
+   * Version number. This changes only when there is a
+   *          significant, externally apparent enhancement from
+   *          the previous release. 'n' represents the n'th
+   *          version.
+   *
+   *          Clients should carefully consider the implications
+   *          of new versions as external interfaces and behaviour
+   *          may have changed.
+   */
+  public static final int VERSION = @version.VERSION@;
+
+  /**
+   * Release Number.
+   * Release number. This changes when:
+   *            -  a new set of functionality is to be added, eg,
+   *               implementation of a new W3C specification.
+   *            -  API or behaviour change.
+   *            -  its designated as a reference release.
+   */
+  public static final int RELEASE = @version.RELEASE@;
+
+  /**
+   * Maintenance Drop Number.
+   * Optional identifier used to designate maintenance
+   *          drop applied to a specific release and contains
+   *          fixes for defects reported. It maintains compatibility
+   *          with the release and contains no API changes.
+   *          When missing, it designates the final and complete
+   *          development drop for a release.
+   */
+  public static final int MAINTENANCE = @version.MINOR@;
+
+  /**
+   * Development Drop Number.
+   * Optional identifier designates development drop of
+   *          a specific release. D01 is the first development drop
+   *          of a new release.
+   *
+   *          Development drops are works in progress towards a
+   *          compeleted, final release. A specific development drop
+   *          may not completely implement all aspects of a new
+   *          feature, which may take several development drops to
+   *          complete. At the point of the final drop for the
+   *          release, the D suffix will be omitted.
+   *
+   *          Each 'D' drops can contain functional enhancements as
+   *          well as defect fixes. 'D' drops may not be as stable as
+   *          the final releases.
+   */
+  public static final int DEVELOPMENT = 0;
+  
+  /**
+   * Version String like <CODE>"<B>Xalan</B> <B>Language</B>
+   * v.r[.dd| <B>D</B>nn]"</CODE>.
+   * <P>Semantics of the version string are identical to the Xerces project.</P>
+   */
+  public static final String S_VERSION = PRODUCT+" "+LANGUAGE+" "
+                                   +VERSION+"."+RELEASE+"."
+                                   +(DEVELOPMENT > 0 ? ("D"+DEVELOPMENT)
+                                     : (""+MAINTENANCE));
+
+}
diff --git a/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java b/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java
new file mode 100644
index 0000000..6e00c88
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java
@@ -0,0 +1,1665 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTAttributeDef.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.AVT;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.StringToIntTable;
+import org.apache.xml.utils.StringVector;
+import org.apache.xml.utils.XML11Char;
+import org.apache.xpath.XPath;
+
+ 
+/**
+ * This class defines an attribute for an element in a XSLT stylesheet,
+ * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
+ * mapping between Xalan classes and the markup attributes in the element.
+ */
+public class XSLTAttributeDef
+{
+   // How to handle invalid values for this attribute 
+   static final int FATAL = 0;
+   static final int ERROR = 1;
+   static final int WARNING = 2;
+   
+   
+  /**
+   * Construct an instance of XSLTAttributeDef.
+   *
+   * @param namespace The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
+   * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
+   * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME, T_NCNAME.
+   * @param required true if this is attribute is required by the XSLT specification.
+   * @param supportsAVT true if this attribute supports AVT's.
+   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
+   */
+  XSLTAttributeDef(String namespace, String name, int type, boolean required, boolean supportsAVT, int errorType)
+  {
+    this.m_namespace = namespace;
+    this.m_name = name;
+    this.m_type = type;
+    this.m_required = required;
+    this.m_supportsAVT = supportsAVT;
+    this.m_errorType = errorType;
+  }
+
+  /**
+   * Construct an instance of XSLTAttributeDef.
+   *
+   * @param namespace The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR,
+   * T_CHAR, T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM,
+   * T_SIMPLEPATTERNLIST, T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, 
+   * T_ENUM_OR_PQNAME, T_NCNAME.
+   * @param supportsAVT true if this attribute supports AVT's. 
+   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
+   * @param defaultVal The default value for this attribute.
+   */
+  XSLTAttributeDef(String namespace, String name, int type, boolean supportsAVT, int errorType, String defaultVal)
+  {
+
+    this.m_namespace = namespace;
+    this.m_name = name;
+    this.m_type = type;
+    this.m_required = false;
+    this.m_supportsAVT = supportsAVT;  
+    this.m_errorType = errorType;      
+    this.m_default = defaultVal;
+   }
+
+  /**
+   * Construct an instance of XSLTAttributeDef that uses two
+   * enumerated values.
+   *
+   * @param namespace The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param required true if this attribute is required by the XSLT specification.
+   * @param supportsAVT true if this attribute supports AVT's.  
+   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME       
+   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
+   * @param k1 The XSLT name of the enumerated value.
+   * @param v1 An integer representation of k1.
+   * @param k2 The XSLT name of the enumerated value.
+   * @param v2 An integer representation of k2.
+    */
+  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT, 
+                    boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2)
+  {
+
+    this.m_namespace = namespace;
+    this.m_name = name;
+	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
+    this.m_required = required;
+    this.m_supportsAVT = supportsAVT;    
+    this.m_errorType = errorType;    
+    m_enums = new StringToIntTable(2);
+
+    m_enums.put(k1, v1);
+    m_enums.put(k2, v2);
+  }
+
+  /**
+   * Construct an instance of XSLTAttributeDef that uses three
+   * enumerated values.
+   *
+   * @param namespace The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param required true if this attribute is required by the XSLT specification.
+   * @param supportsAVT true if this attribute supports AVT's.
+   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
+   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING.    * 
+   * @param k1 The XSLT name of the enumerated value.
+   * @param v1 An integer representation of k1.
+   * @param k2 The XSLT name of the enumerated value.
+   * @param v2 An integer representation of k2.
+   * @param k3 The XSLT name of the enumerated value.
+   * @param v3 An integer representation of k3.
+   */
+  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
+                    boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2, String k3, int v3)
+  {
+
+    this.m_namespace = namespace;
+    this.m_name = name;
+	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
+    this.m_required = required;
+    this.m_supportsAVT = supportsAVT; 
+    this.m_errorType = errorType;      
+    m_enums = new StringToIntTable(3);
+
+    m_enums.put(k1, v1);
+    m_enums.put(k2, v2);
+    m_enums.put(k3, v3);
+  }
+
+  /**
+   * Construct an instance of XSLTAttributeDef that uses three
+   * enumerated values.
+   *
+   * @param namespace The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param required true if this attribute is required by the XSLT specification.
+   * @param supportsAVT true if this attribute supports AVT's.
+   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
+   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING.    * @param k1 The XSLT name of the enumerated value.
+   * @param v1 An integer representation of k1.
+   * @param k2 The XSLT name of the enumerated value.
+   * @param v2 An integer representation of k2.
+   * @param k3 The XSLT name of the enumerated value.
+   * @param v3 An integer representation of k3.
+   * @param k4 The XSLT name of the enumerated value.
+   * @param v4 An integer representation of k4.
+   */
+  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
+                   boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2, 
+                   String k3, int v3, String k4, int v4)
+  {
+
+    this.m_namespace = namespace;
+    this.m_name = name;
+	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
+    this.m_required = required;
+    this.m_supportsAVT = supportsAVT;      
+    this.m_errorType = errorType; 
+    m_enums = new StringToIntTable(4);
+
+    m_enums.put(k1, v1);
+    m_enums.put(k2, v2);
+    m_enums.put(k3, v3);
+    m_enums.put(k4, v4);
+  }
+
+  /** Type values that represent XSLT attribute types. */
+  static final int T_CDATA = 1,
+
+  // <!-- Used for the type of an attribute value that is a URI reference.-->
+  T_URL = 2,
+
+  // <!-- Used for the type of an attribute value that is an
+  // attribute value template.-->
+  T_AVT = 3,  // Attribute Value Template
+
+  // <!-- Used for the type of an attribute value that is a pattern.-->
+  T_PATTERN = 4,
+
+  // <!-- Used for the type of an attribute value that is an expression.-->
+  T_EXPR = 5,
+
+  // <!-- Used for the type of an attribute value that consists
+  // of a single character.-->
+  T_CHAR = 6,
+
+  // <!-- Used for the type of an attribute value that is a number. -->
+  T_NUMBER = 7,
+
+  // Used for boolean values
+  T_YESNO = 8,
+
+  // <!-- Used for the type of an attribute value that is a QName; the prefix
+  // gets expanded by the XSLT processor. -->
+  T_QNAME = 9,
+
+  // <!--Used for a whitespace-separated list of QNames where the non-prefixed
+  // entries are not to be placed in the default namespace. -->
+  T_QNAMES = 10,
+
+  // <!-- Used for enumerated values -->
+  T_ENUM = 11,
+
+  // Used for simple match patterns, i.e. xsl:strip-space spec.
+  T_SIMPLEPATTERNLIST = 12,
+
+  // Used for a known token.
+  T_NMTOKEN = 13,
+
+  // Used for a list of white-space delimited strings.
+  T_STRINGLIST = 14,
+
+  // Used for a list of white-space delimited strings.
+  // Prefixes are checked to make sure they refer to 
+  // valid namespaces, and are resolved when processed
+  T_PREFIX_URLLIST = 15,
+  
+  // Used for enumerated values, one of which could be a qname-but-not-ncname
+  T_ENUM_OR_PQNAME = 16,
+
+  // Used for the type of an attribute value that is a NCName
+  T_NCNAME = 17,
+  
+  // Used for QName attributes that are always AVT.  Prefix isn't resolved.
+  T_AVT_QNAME = 18,
+  
+  // Used for a list of QNames where non-prefixed items are to be resolved
+  // using the default namespace (This is only true for cdata-section-elements)
+  T_QNAMES_RESOLVE_NULL = 19,
+  
+  // Used for a list of white-space delimited strings.
+  // strings are checked to make sure they are valid 
+  // prefixes, and are not expanded when processed. 
+  T_PREFIXLIST = 20;
+
+  /** Representation for an attribute in a foreign namespace. */
+  static final XSLTAttributeDef m_foreignAttr = new XSLTAttributeDef("*", "*",
+                                            XSLTAttributeDef.T_CDATA,false, false, WARNING);
+
+  /** Method name that objects may implement if they wish to have forein attributes set. */
+  static final String S_FOREIGNATTR_SETTER = "setForeignAttr";
+
+  /**
+   * The allowed namespace for this element.
+   */
+  private String m_namespace;
+
+  /**
+   * Get the allowed namespace for this attribute.
+   *
+   * @return The allowed namespace for this attribute, which may be null, or may be "*".
+   */
+  String getNamespace()
+  {
+    return m_namespace;
+  }
+
+  /**
+   * The name of this element.
+   */
+  private String m_name;
+
+  /**
+   * Get the name of this attribute.
+   *
+   * @return non-null reference to the name of this attribute, which may be "*".
+   */
+  String getName()
+  {
+    return m_name;
+  }
+
+  /**
+   * The type of this attribute value.
+   */
+  private int m_type;
+
+  /**
+   * Get the type of this attribute value.
+   *
+   * @return One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
+   * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
+   * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME.
+   */
+  int getType()
+  {
+    return m_type;
+  }
+
+  /**
+   * If this element is of type T_ENUM, this will contain
+   * a map from the attribute string to the Xalan integer
+   * value.
+   */
+  private StringToIntTable m_enums;
+
+  /**
+   * If this element is of type T_ENUM, this will return
+   * a map from the attribute string to the Xalan integer
+   * value.
+   * @param key The XSLT attribute value.
+   *
+   * @return The integer representation of the enumerated value for this attribute.
+   * @throws Throws NullPointerException if m_enums is null.
+   */
+  private int getEnum(String key)
+  {
+    return m_enums.get(key);
+  }
+
+ /**
+   * If this element is of type T_ENUM, this will return
+   * an array of strings - the values in the enumeration
+   *
+   * @return An array of the enumerated values permitted for this attribute.
+   *
+   * @throws Throws NullPointerException if m_enums is null.
+   */
+  private String[] getEnumNames()
+  {
+    return m_enums.keys();
+  }
+
+  /**
+   * The default value for this attribute.
+   */
+  private String m_default;
+
+  /**
+   * Get the default value for this attribute.
+   *
+   * @return The default value for this attribute, or null.
+   */
+  String getDefault()
+  {
+    return m_default;
+  }
+
+  /**
+   * Set the default value for this attribute.
+   *
+   * @param def String representation of the default value for this attribute.
+   */
+  void setDefault(String def)
+  {
+    m_default = def;
+  }
+
+  /**
+   * If true, this is a required attribute.
+   */
+  private boolean m_required;
+
+  /**
+   * Get whether or not this is a required attribute.
+   *
+   * @return true if this is a required attribute.
+   */
+  boolean getRequired()
+  {
+    return m_required;
+  }
+
+  /**
+   * If true, this is attribute supports AVT's.
+   */
+  private boolean m_supportsAVT;
+
+  /**
+   * Get whether or not this attribute supports AVT's.
+   *
+   * @return true if this attribute supports AVT's.
+   */
+  boolean getSupportsAVT()
+  {
+    return m_supportsAVT;
+  }
+  
+  int m_errorType = this.WARNING;
+  
+  /**
+   * Get the type of error message to use if the attribute value is invalid.
+   *
+   * @return one of XSLAttributeDef.FATAL, XSLAttributeDef.ERROR, XSLAttributeDef.WARNING
+   */
+  int getErrorType()
+  {
+    return m_errorType;
+  }
+  /**
+   * String that should represent the setter method which which
+   * may be used on objects to set a value that represents this attribute  
+   */
+  String m_setterString = null;
+
+  /**
+   * Return a string that should represent the setter method.
+   * The setter method name will be created algorithmically the
+   * first time this method is accessed, and then cached for return
+   * by subsequent invocations of this method.
+   *
+   * @return String that should represent the setter method which which
+   * may be used on objects to set a value that represents this attribute,
+   * of null if no setter method should be called.
+   */
+  public String getSetterMethodName()
+  {
+
+    if (null == m_setterString)
+    {
+      if (m_foreignAttr == this)
+      {
+        return S_FOREIGNATTR_SETTER;
+      }
+      else if (m_name.equals("*"))
+      {
+        m_setterString = "addLiteralResultAttribute";
+
+        return m_setterString;
+      }
+
+      StringBuffer outBuf = new StringBuffer();
+
+      outBuf.append("set");
+
+      if ((m_namespace != null)
+              && m_namespace.equals(Constants.S_XMLNAMESPACEURI))
+      {
+        outBuf.append("Xml");
+      }
+
+      int n = m_name.length();
+
+      for (int i = 0; i < n; i++)
+      {
+        char c = m_name.charAt(i);
+
+        if ('-' == c)
+        {
+          i++;
+
+          c = m_name.charAt(i);
+          c = Character.toUpperCase(c);
+        }
+        else if (0 == i)
+        {
+          c = Character.toUpperCase(c);
+        }
+
+        outBuf.append(c);
+      }
+
+      m_setterString = outBuf.toString();
+    }
+
+    return m_setterString;
+  }
+
+  /**
+   * Process an attribute string of type T_AVT into
+   * a AVT value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value Should be an Attribute Value Template string.
+   *
+   * @return An AVT object that may be used to evaluate the Attribute Value Template.
+   *
+   * @throws org.xml.sax.SAXException which will wrap a
+   * {@link javax.xml.transform.TransformerException}, if there is a syntax error
+   * in the attribute value template string.
+   */
+  AVT processAVT(
+          StylesheetHandler handler, String uri, String name, String rawName, String value,
+          ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+
+      return avt;
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Process an attribute string of type T_CDATA into
+   * a String value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value non-null string reference.
+   *
+   * @return The value argument.
+   * 
+   * @throws org.xml.sax.SAXException.
+   */
+  Object processCDATA(StylesheetHandler handler, String uri, String name,
+                      String rawName, String value, ElemTemplateElement owner)
+                      throws org.xml.sax.SAXException
+  {
+  	if (getSupportsAVT()) {
+	    try
+	    {
+	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+	      return avt;
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }  		
+  	} else {  	  	
+	    return value;
+  	}
+  }
+
+  /**
+   * Process an attribute string of type T_CHAR into
+   * a Character value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value Should be a string with a length of 1.
+   *
+   * @return Character object.
+   *
+   * @throws org.xml.sax.SAXException if the string is not a length of 1.
+   */
+  Object processCHAR(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+	if (getSupportsAVT()) {
+	    try
+	    {
+	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+	
+		  // If an AVT wasn't used, validate the value
+		  if ((avt.isSimple()) && (value.length() != 1)) {
+		  	handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
+            return null;
+		  }	
+	      return avt;
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }
+	} else {    
+	    if (value.length() != 1)
+	    {
+            handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
+            return null;
+	    }
+
+	    return new Character(value.charAt(0));
+	}
+  }
+
+  /**
+   * Process an attribute string of type T_ENUM into a int value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value non-null string that represents an enumerated value that is
+   * valid for this element.
+   * @param owner
+   *
+   * @return An Integer representation of the enumerated value if this attribute does not support
+   *         AVT.  Otherwise, and AVT is returned.
+   */
+  Object processENUM(StylesheetHandler handler, String uri, String name,
+                     String rawName, String value, ElemTemplateElement owner)
+                     throws org.xml.sax.SAXException
+  {
+
+	AVT avt = null;
+	if (getSupportsAVT()) {
+	    try
+	    {
+	      avt = new AVT(handler, uri, name, rawName, value, owner);
+	      
+	      // If this attribute used an avt, then we can't validate at this time.
+	      if (!avt.isSimple()) return avt;
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }
+	}    
+	
+    int retVal = this.getEnum(value);
+    
+	if (retVal == StringToIntTable.INVALID_KEY) 
+    {
+       StringBuffer enumNamesList = getListOfEnums();
+       handleError(handler, XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null);
+       return null;
+    }
+
+	if (getSupportsAVT()) return avt;
+	else return new Integer(retVal);	
+
+  }
+
+  /**
+   * Process an attribute string of that is either an enumerated value or a qname-but-not-ncname.
+   * Returns an AVT, if this attribute support AVT; otherwise returns int or qname.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value non-null string that represents an enumerated value that is
+   * valid for this element.
+   * @param owner
+   *
+   * @return AVT if attribute supports AVT. An Integer representation of the enumerated value if
+   *         attribute does not support AVT and an enumerated value was used.  Otherwise a qname
+   *         is returned.
+   */
+  Object processENUM_OR_PQNAME(StylesheetHandler handler, String uri, String name,
+                     String rawName, String value, ElemTemplateElement owner)
+                     throws org.xml.sax.SAXException
+  {
+
+	Object objToReturn = null;
+	
+	if (getSupportsAVT()) {
+	    try
+	    {
+	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+	      if (!avt.isSimple()) return avt;
+	      else objToReturn = avt;
+	    }  
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }
+	}    
+	
+    // An avt wasn't used.
+  	int key = this.getEnum(value);
+    
+    if (key != StringToIntTable.INVALID_KEY) 
+    {
+        if (objToReturn == null) objToReturn = new Integer(key);
+    }
+
+    // enum not used.  Validate qname-but-not-ncname.
+    else
+    {
+        try 
+        {
+			QName qname = new QName(value, handler, true);
+            if (objToReturn == null) objToReturn = qname;	
+	        
+			if (qname.getPrefix() == null) {
+	           StringBuffer enumNamesList = getListOfEnums();
+
+ 	           enumNamesList.append(" <qname-but-not-ncname>");
+               handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null); 
+               return null;
+        
+	        }            
+        }
+        catch (IllegalArgumentException ie) 
+        {
+           StringBuffer enumNamesList = getListOfEnums();
+           enumNamesList.append(" <qname-but-not-ncname>");
+           
+           handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },ie); 
+           return null;
+
+        }
+        catch (RuntimeException re)
+        {
+           StringBuffer enumNamesList = getListOfEnums();
+           enumNamesList.append(" <qname-but-not-ncname>");
+
+           handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },re); 
+           return null;
+        }    
+  	}
+  	
+  	return objToReturn;
+  }
+
+  /**
+   * Process an attribute string of type T_EXPR into
+   * an XPath value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value An XSLT expression string.
+   *
+   * @return an XPath object that may be used for evaluation.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the expression
+   * string contains a syntax error.
+   */
+  Object processEXPR(
+          StylesheetHandler handler, String uri, String name, String rawName, String value,
+          ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      XPath expr = handler.createXPath(value, owner);
+
+      return expr;
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Process an attribute string of type T_NMTOKEN into
+   * a String value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A NMTOKEN string.
+   *
+   * @return the value argument or an AVT if this attribute supports AVTs.
+   * 
+   * @throws org.xml.sax.SAXException if the value is not a valid nmtoken
+   */
+  Object processNMTOKEN(StylesheetHandler handler, String uri, String name,
+                        String rawName, String value, ElemTemplateElement owner)
+             throws org.xml.sax.SAXException
+  {
+  	
+  	if (getSupportsAVT()) {
+	    try
+	    {
+	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+	
+		  // If an AVT wasn't used, validate the value
+		  if ((avt.isSimple()) && (!XML11Char.isXML11ValidNmtoken(value))) {
+            handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
+            return null;
+		  }	
+	      return avt;
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }  		
+  	} else {
+  		if (!XML11Char.isXML11ValidNmtoken(value)) {
+            handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
+            return null;
+  		}
+  	}	  			
+    return value;
+  }
+
+  /**
+   * Process an attribute string of type T_PATTERN into
+   * an XPath match pattern value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A match pattern string.
+   *
+   * @return An XPath pattern that may be used to evaluate the XPath.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if the match pattern
+   * string contains a syntax error.
+   */
+  Object processPATTERN(
+          StylesheetHandler handler, String uri, String name, String rawName, String value,
+          ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      XPath pattern = handler.createMatchPatternXPath(value, owner);
+
+      return pattern;
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Process an attribute string of type T_NUMBER into
+   * a double value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A string that can be parsed into a double value.
+   * @param number
+   *
+   * @return A Double object.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException}
+   * if the string does not contain a parsable number.
+   */
+  Object processNUMBER(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+
+	if (getSupportsAVT()) 
+	{
+		Double val;
+		AVT avt = null;
+	    try
+	    {
+	      avt = new AVT(handler, uri, name, rawName, value, owner);
+	      
+	      // If this attribute used an avt, then we can't validate at this time.
+	      if (avt.isSimple()) 
+	      {
+	      	val = Double.valueOf(value);
+	      }
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    } 
+	    catch (NumberFormatException nfe)
+	    {
+	     	handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
+            return null;
+	    }
+	    return avt;
+	
+	} 
+	else
+    {
+	    try
+	    {
+	      return Double.valueOf(value);
+	    }
+	    catch (NumberFormatException nfe)
+	    {
+            handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
+            return null;
+	    }
+    }    
+  }
+
+  /**
+   * Process an attribute string of type T_QNAME into a QName value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A string that represents a potentially prefix qualified name.
+   * @param owner
+   *
+   * @return A QName object if this attribute does not support AVT's.  Otherwise, an AVT
+   *         is returned.
+   *
+   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
+   * resolved, or the string contains syntax that is invalid for a qualified name.
+   */
+  Object processQNAME(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+     try 
+        {	
+   	      QName qname = new QName(value, handler, true);
+          return qname;
+        }
+        catch (IllegalArgumentException ie)
+        {
+            // thrown by QName constructor
+            handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},ie);
+            return null;
+        }
+        catch (RuntimeException re) {
+            // thrown by QName constructor
+            handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},re);
+            return null;
+        }
+  	}
+ 
+
+  /**
+   * Process an attribute string of type T_QNAME into a QName value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A string that represents a potentially prefix qualified name.
+   * @param owner
+   *
+   * @return An AVT is returned.
+   *
+   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
+   * resolved, or the string contains syntax that is invalid for a qualified name.
+   */
+  Object processAVT_QNAME(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+       AVT avt = null;
+       try
+       {
+          avt = new AVT(handler, uri, name, rawName, value, owner);
+    
+          // If an AVT wasn't used, validate the value
+          if (avt.isSimple())
+          {
+             int indexOfNSSep = value.indexOf(':');
+
+             if (indexOfNSSep >= 0) 
+             {   
+                  String prefix = value.substring(0, indexOfNSSep);
+                  if (!XML11Char.isXML11ValidNCName(prefix))
+                  {
+                     handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null);
+                     return null;
+                  }
+             }
+                 
+             String localName =  (indexOfNSSep < 0)
+                 ? value : value.substring(indexOfNSSep + 1); 
+             
+             if ((localName == null) || (localName.length() == 0) ||
+                 (!XML11Char.isXML11ValidNCName(localName)))
+             {    
+                     handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null );
+                     return null;
+             }
+          }  
+        }
+        catch (TransformerException te)
+        {
+           // thrown by AVT constructor
+          throw new org.xml.sax.SAXException(te);
+        } 
+    
+    return avt;
+ }
+
+  /**
+   * Process an attribute string of type NCName into a String
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A string that represents a potentially prefix qualified name.
+   * @param owner
+   *
+   * @return A String object if this attribute does not support AVT's.  Otherwise, an AVT
+   *         is returned.
+   *
+   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
+   * resolved, or the string contains syntax that is invalid for a NCName.
+   */
+  Object processNCNAME(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+    
+    if (getSupportsAVT()) 
+    {
+        AVT avt = null;
+        try
+        {
+          avt = new AVT(handler, uri, name, rawName, value, owner);
+    
+          // If an AVT wasn't used, validate the value
+          if ((avt.isSimple()) &&  (!XML11Char.isXML11ValidNCName(value))) 
+          {
+             handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
+             return null;
+          }      
+          return avt;
+        }
+        catch (TransformerException te)
+        {
+           // thrown by AVT constructor
+          throw new org.xml.sax.SAXException(te);
+        } 
+        
+    } else {
+        if (!XML11Char.isXML11ValidNCName(value)) 
+        {
+            handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
+            return null;
+        }
+        return value;
+    }
+ }
+
+  /**
+   * Process an attribute string of type T_QNAMES into a vector of QNames where
+   * the specification requires that non-prefixed elements not be placed in a
+   * namespace.  (See section 2.4 of XSLT 1.0.)
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A whitespace delimited list of qualified names.
+   *
+   * @return a Vector of QName objects.
+   *
+   * @throws org.xml.sax.SAXException if the one of the qualified name strings
+   * contains a prefix that can not be
+   * resolved, or a qualified name contains syntax that is invalid for a qualified name.
+   */
+  Vector processQNAMES(
+          StylesheetHandler handler, String uri, String name, String rawName, String value)
+            throws org.xml.sax.SAXException
+  {
+
+    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+    int nQNames = tokenizer.countTokens();
+    Vector qnames = new Vector(nQNames);
+
+    for (int i = 0; i < nQNames; i++)
+    {
+      // Fix from Alexander Rudnev
+      qnames.addElement(new QName(tokenizer.nextToken(), handler));
+    }
+
+    return qnames;
+  }
+
+ /**
+   * Process an attribute string of type T_QNAMES_RESOLVE_NULL into a vector
+   * of QNames where the specification requires non-prefixed elements to be
+   * placed in the default namespace.  (See section 16 of XSLT 1.0; the
+   * <em>only</em> time that this will get called is for the
+   * <code>cdata-section-elements</code> attribute on <code>xsl:output</code>.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A whitespace delimited list of qualified names.
+   *
+   * @return a Vector of QName objects.
+   *
+   * @throws org.xml.sax.SAXException if the one of the qualified name strings
+   * contains a prefix that can not be resolved, or a qualified name contains
+   * syntax that is invalid for a qualified name.
+   */
+  final Vector processQNAMESRNU(StylesheetHandler handler, String uri,
+    String name, String rawName, String value)
+    throws org.xml.sax.SAXException
+  {
+
+    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+    int nQNames = tokenizer.countTokens();
+    Vector qnames = new Vector(nQNames);
+
+    String defaultURI = handler.getNamespaceForPrefix("");
+    for (int i = 0; i < nQNames; i++)
+    {
+      String tok = tokenizer.nextToken();
+      if (tok.indexOf(':') == -1) {
+        qnames.addElement(new QName(defaultURI,tok));
+      } else {
+        qnames.addElement(new QName(tok, handler));
+      }
+    }
+    return qnames;
+  }
+
+  /**
+   * Process an attribute string of type T_SIMPLEPATTERNLIST into
+   * a vector of XPath match patterns.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A whitespace delimited list of simple match patterns.
+   *
+   * @return A Vector of XPath objects.
+   *
+   * @throws org.xml.sax.SAXException that wraps a
+   * {@link javax.xml.transform.TransformerException} if one of the match pattern
+   * strings contains a syntax error.
+   */
+  Vector processSIMPLEPATTERNLIST(
+          StylesheetHandler handler, String uri, String name, String rawName, String value,
+          ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+      int nPatterns = tokenizer.countTokens();
+      Vector patterns = new Vector(nPatterns);
+
+      for (int i = 0; i < nPatterns; i++)
+      {
+        XPath pattern =
+          handler.createMatchPatternXPath(tokenizer.nextToken(), owner);
+
+        patterns.addElement(pattern);
+      }
+
+      return patterns;
+    }
+    catch (TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+
+  /**
+   * Process an attribute string of type T_STRINGLIST into
+   * a vector of XPath match patterns.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value a whitespace delimited list of string values.
+   *
+   * @return A StringVector of the tokenized strings.
+   */
+  StringVector processSTRINGLIST(StylesheetHandler handler, String uri,
+                                 String name, String rawName, String value)
+  {
+
+    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+    int nStrings = tokenizer.countTokens();
+    StringVector strings = new StringVector(nStrings);
+
+    for (int i = 0; i < nStrings; i++)
+    {
+      strings.addElement(tokenizer.nextToken());
+    }
+
+    return strings;
+  }
+
+  /**
+   * Process an attribute string of type T_URLLIST into
+   * a vector of prefixes that may be resolved to URLs.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A list of whitespace delimited prefixes.
+   *
+   * @return A vector of strings that may be resolved to URLs.
+   *
+   * @throws org.xml.sax.SAXException if one of the prefixes can not be resolved.
+   */
+  StringVector processPREFIX_URLLIST(
+          StylesheetHandler handler, String uri, String name, String rawName, String value)
+            throws org.xml.sax.SAXException
+  {
+
+    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+    int nStrings = tokenizer.countTokens();
+    StringVector strings = new StringVector(nStrings);
+
+    for (int i = 0; i < nStrings; i++)
+    {
+      String prefix = tokenizer.nextToken();
+      String url = handler.getNamespaceForPrefix(prefix);
+
+      if (url != null)
+        strings.addElement(url);
+      else
+        throw new org.xml.sax.SAXException(XSLMessages.createMessage(XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, new Object[] {prefix}));
+    
+    }
+
+    return strings;
+  }
+
+  /**
+    * Process an attribute string of type T_PREFIXLIST into
+    * a vector of prefixes that may be resolved to URLs.
+    *
+    * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+    * @param uri The Namespace URI, or an empty string.
+    * @param name The local name (without prefix), or empty string if not namespace processing.
+    * @param rawName The qualified name (with prefix).
+    * @param value A list of whitespace delimited prefixes.
+    *
+    * @return A vector of strings that may be resolved to URLs.
+    *
+    * @throws org.xml.sax.SAXException if one of the prefixes can not be resolved.
+    */
+   StringVector processPREFIX_LIST(
+           StylesheetHandler handler, String uri, String name, 
+           String rawName, String value) throws org.xml.sax.SAXException
+   {
+    
+     StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
+     int nStrings = tokenizer.countTokens();
+     StringVector strings = new StringVector(nStrings);
+
+     for (int i = 0; i < nStrings; i++)
+     {
+       String prefix = tokenizer.nextToken();
+       String url = handler.getNamespaceForPrefix(prefix);
+       if (prefix.equals(Constants.ATTRVAL_DEFAULT_PREFIX) || url != null)
+         strings.addElement(prefix);
+       else
+         throw new org.xml.sax.SAXException(
+              XSLMessages.createMessage(
+                   XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, 
+                   new Object[] {prefix}));
+    
+     }
+
+     return strings;
+   }
+
+
+  /**
+   * Process an attribute string of type T_URL into
+   * a URL value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value non-null string that conforms to the URL syntax.
+   *
+   * @return The non-absolutized URL argument, in other words, the value argument.  If this 
+   *         attribute supports AVT, an AVT is returned.
+   *
+   * @throws org.xml.sax.SAXException if the URL does not conform to the URL syntax.
+   */
+  Object processURL(
+          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    if (getSupportsAVT()) {
+	    try
+	    {
+	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
+	
+		  // If an AVT wasn't used, validate the value
+		 // if (avt.getSimpleString() != null) {
+			   // TODO: syntax check URL value.
+			    // return SystemIDResolver.getAbsoluteURI(value, 
+			    //                                         handler.getBaseIdentifier());
+		  //}	
+	      return avt;
+	    }
+	    catch (TransformerException te)
+	    {
+	      throw new org.xml.sax.SAXException(te);
+	    }  		
+     } else {
+    // TODO: syntax check URL value.
+    // return SystemIDResolver.getAbsoluteURI(value, 
+    //                                         handler.getBaseIdentifier());
+     	
+	    return value;
+    }
+  }
+
+  /**
+   * Process an attribute string of type T_YESNO into
+   * a Boolean value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value A string that should be "yes" or "no".
+   *
+   * @return Boolean object representation of the value.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  private Boolean processYESNO(
+          StylesheetHandler handler, String uri, String name, String rawName, String value)
+            throws org.xml.sax.SAXException
+  {
+
+    // Is this already checked somewhere else?  -sb
+    if (!(value.equals("yes") || value.equals("no")))
+    {
+      handleError(handler, XSLTErrorResources.INVALID_BOOLEAN, new Object[] {name,value}, null);
+      return null;
+   }
+ 
+     return new Boolean(value.equals("yes") ? true : false);
+  }
+
+  /**
+   * Process an attribute value.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param name The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param value The unprocessed string value of the attribute.
+   *
+   * @return The processed Object representation of the attribute.
+   *
+   * @throws org.xml.sax.SAXException if the attribute value can not be processed.
+   */
+  Object processValue(
+          StylesheetHandler handler, String uri, String name, String rawName, String value,
+          ElemTemplateElement owner)
+            throws org.xml.sax.SAXException
+  {
+
+    int type = getType();
+    Object processedValue = null;
+
+    switch (type)
+    {
+    case T_AVT :
+      processedValue = processAVT(handler, uri, name, rawName, value, owner);
+      break;
+    case T_CDATA :
+      processedValue = processCDATA(handler, uri, name, rawName, value, owner);
+      break;
+    case T_CHAR :
+      processedValue = processCHAR(handler, uri, name, rawName, value, owner);
+      break;
+    case T_ENUM :
+      processedValue = processENUM(handler, uri, name, rawName, value, owner);
+      break;
+    case T_EXPR :
+      processedValue = processEXPR(handler, uri, name, rawName, value, owner);
+      break;
+    case T_NMTOKEN :
+      processedValue = processNMTOKEN(handler, uri, name, rawName, value, owner);
+      break;
+    case T_PATTERN :
+      processedValue = processPATTERN(handler, uri, name, rawName, value, owner);
+      break;
+    case T_NUMBER :
+      processedValue = processNUMBER(handler, uri, name, rawName, value, owner);
+      break;
+    case T_QNAME :
+      processedValue = processQNAME(handler, uri, name, rawName, value, owner);
+      break;
+    case T_QNAMES :
+      processedValue = processQNAMES(handler, uri, name, rawName, value);
+      break;
+	case T_QNAMES_RESOLVE_NULL:
+      processedValue = processQNAMESRNU(handler, uri, name, rawName, value);
+      break;
+    case T_SIMPLEPATTERNLIST :
+      processedValue = processSIMPLEPATTERNLIST(handler, uri, name, rawName,
+                                                value, owner);
+      break;
+    case T_URL :
+      processedValue = processURL(handler, uri, name, rawName, value, owner);
+      break;
+    case T_YESNO :
+      processedValue = processYESNO(handler, uri, name, rawName, value);
+      break;
+    case T_STRINGLIST :
+      processedValue = processSTRINGLIST(handler, uri, name, rawName, value);
+      break;
+    case T_PREFIX_URLLIST :
+      processedValue = processPREFIX_URLLIST(handler, uri, name, rawName,
+                                             value);
+      break;
+    case T_ENUM_OR_PQNAME :
+    	processedValue = processENUM_OR_PQNAME(handler, uri, name, rawName, value, owner);
+    	break;
+    case T_NCNAME :
+        processedValue = processNCNAME(handler, uri, name, rawName, value, owner);
+        break;
+    case T_AVT_QNAME :
+        processedValue = processAVT_QNAME(handler, uri, name, rawName, value, owner);
+        break;
+    case T_PREFIXLIST :
+      processedValue = processPREFIX_LIST(handler, uri, name, rawName,
+                                             value);
+      break;
+
+    default :
+    }
+
+    return processedValue;
+  }
+
+  /**
+   * Set the default value of an attribute.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param elem The object on which the property will be set.
+   *
+   * @throws org.xml.sax.SAXException wraps an invocation exception if the
+   * setter method can not be invoked on the object.
+   */
+  void setDefAttrValue(StylesheetHandler handler, ElemTemplateElement elem)
+          throws org.xml.sax.SAXException
+  {
+    setAttrValue(handler, this.getNamespace(), this.getName(),
+                 this.getName(), this.getDefault(), elem);
+  }
+
+  /**
+   * Get the primative type for the class, if there
+   * is one.  If the class is a Double, for instance,
+   * this will return double.class.  If the class is not one
+   * of the 9 primative types, it will return the same
+   * class that was passed in.
+   *
+   * @param obj The object which will be resolved to a primative class object if possible.
+   *
+   * @return The most primative class representation possible for the object, never null.
+   */
+  private Class getPrimativeClass(Object obj)
+  {
+
+    if (obj instanceof XPath)
+      return XPath.class;
+
+    Class cl = obj.getClass();
+
+    if (cl == Double.class)
+    {
+      cl = double.class;
+    }
+
+    if (cl == Float.class)
+    {
+      cl = float.class;
+    }
+    else if (cl == Boolean.class)
+    {
+      cl = boolean.class;
+    }
+    else if (cl == Byte.class)
+    {
+      cl = byte.class;
+    }
+    else if (cl == Character.class)
+    {
+      cl = char.class;
+    }
+    else if (cl == Short.class)
+    {
+      cl = short.class;
+    }
+    else if (cl == Integer.class)
+    {
+      cl = int.class;
+    }
+    else if (cl == Long.class)
+    {
+      cl = long.class;
+    }
+
+    return cl;
+  }
+  
+  /**
+   * StringBuffer containing comma delimited list of valid values for ENUM type.
+   * Used to build error message.
+   */
+  private StringBuffer getListOfEnums() 
+  {
+     StringBuffer enumNamesList = new StringBuffer();            
+     String [] enumValues = this.getEnumNames();
+
+     for (int i = 0; i < enumValues.length; i++)
+     {
+        if (i > 0)
+        {
+           enumNamesList.append(' ');
+        }
+        enumNamesList.append(enumValues[i]);
+    }        
+    return enumNamesList;
+  }
+
+  /**
+   * Set a value on an attribute.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param attrUri The Namespace URI of the attribute, or an empty string.
+   * @param attrLocalName The local name (without prefix), or empty string if not namespace processing.
+   * @param attrRawName The raw name of the attribute, including possible prefix.
+   * @param attrValue The attribute's value.
+   * @param elem The object that should contain a property that represents the attribute.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  boolean setAttrValue(
+          StylesheetHandler handler, String attrUri, String attrLocalName, 
+          String attrRawName, String attrValue, ElemTemplateElement elem)
+            throws org.xml.sax.SAXException
+  {
+    if(attrRawName.equals("xmlns") || attrRawName.startsWith("xmlns:"))
+      return true;
+      
+    String setterString = getSetterMethodName();
+
+    // If this is null, then it is a foreign namespace and we 
+    // do not process it.
+    if (null != setterString)
+    {
+      try
+      {
+        Method meth;
+        Object[] args;
+
+        if(setterString.equals(S_FOREIGNATTR_SETTER))
+        {
+          // workaround for possible crimson bug
+          if( attrUri==null) attrUri="";
+          // First try to match with the primative value.
+          Class sclass = attrUri.getClass();
+          Class[] argTypes = new Class[]{ sclass, sclass,
+                                      sclass, sclass };
+  
+          meth = elem.getClass().getMethod(setterString, argTypes);
+  
+          args = new Object[]{ attrUri, attrLocalName,
+                                      attrRawName, attrValue };
+        }
+        else
+        {
+          Object value = processValue(handler, attrUri, attrLocalName,
+                                      attrRawName, attrValue, elem);
+          // If a warning was issued because the value for this attribute was
+          // invalid, then the value will be null.  Just return
+          if (null == value) return false;
+                                      
+          // First try to match with the primative value.
+          Class[] argTypes = new Class[]{ getPrimativeClass(value) };
+  
+          try
+          {
+            meth = elem.getClass().getMethod(setterString, argTypes);
+          }
+          catch (NoSuchMethodException nsme)
+          {
+            Class cl = ((Object) value).getClass();
+  
+            // If this doesn't work, try it with the non-primative value;
+            argTypes[0] = cl;
+            meth = elem.getClass().getMethod(setterString, argTypes);
+          }
+  
+          args = new Object[]{ value };
+        }
+
+        meth.invoke(elem, args);
+      }
+      catch (NoSuchMethodException nsme)
+      {
+        if (!setterString.equals(S_FOREIGNATTR_SETTER)) 
+        {
+          handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, nsme);//"Failed calling " + setterString + " method!", nsme);
+          return false;
+        }
+      }
+      catch (IllegalAccessException iae)
+      {
+        handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, iae);//"Failed calling " + setterString + " method!", iae);
+        return false;
+      }
+      catch (InvocationTargetException nsme)
+      {
+        handleError(handler, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
+            new Object[]{ Constants.ATTRNAME_NAME, getName()}, nsme);
+        return false;
+      }
+    }
+    
+    return true;
+  }
+  
+  private void handleError(StylesheetHandler handler, String msg, Object [] args, Exception exc) throws org.xml.sax.SAXException
+  {
+    switch (getErrorType()) 
+    {
+        case (FATAL):
+        case (ERROR):
+                handler.error(msg, args, exc);          
+                break;
+        case (WARNING):
+                handler.warn(msg, args);       
+        default: break;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/XSLTElementDef.java b/src/main/java/org/apache/xalan/processor/XSLTElementDef.java
new file mode 100644
index 0000000..1129639
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/XSLTElementDef.java
@@ -0,0 +1,833 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTElementDef.java 468640 2006-10-28 06:53:53Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xml.utils.QName;
+
+/**
+ * This class defines the allowed structure for an element in a XSLT stylesheet,
+ * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
+ * mapping between Xalan classes and the markup elements in the XSLT instance.
+ * This actually represents both text nodes and elements.
+ */
+public class XSLTElementDef
+{
+
+  /**
+   * Construct an instance of XSLTElementDef.  This must be followed by a
+   * call to build().
+   */
+  XSLTElementDef(){}
+
+  /**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject)
+  {
+    build(namespace, name, nameAlias, elements, attributes, contentHandler,
+          classObject);
+    if ( (null != namespace)
+    &&  (namespace.equals(Constants.S_XSLNAMESPACEURL)
+        || namespace.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
+        || namespace.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
+    {
+      schema.addAvailableElement(new QName(namespace, name));
+      if(null != nameAlias)
+        schema.addAvailableElement(new QName(namespace, nameAlias));
+    } 
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param has_required true if this element has required elements by the XSLT specification.
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, boolean has_required)
+  {
+		this.m_has_required = has_required;
+    build(namespace, name, nameAlias, elements, attributes, contentHandler,
+          classObject);
+    if ( (null != namespace)
+    &&  (namespace.equals(Constants.S_XSLNAMESPACEURL)
+        || namespace.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
+        || namespace.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
+    {
+      schema.addAvailableElement(new QName(namespace, name));
+      if(null != nameAlias)
+        schema.addAvailableElement(new QName(namespace, nameAlias));
+    } 
+		
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param has_required true if this element has required elements by the XSLT specification.
+   * @param required true if this element is required by the XSLT specification.
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, 
+								 boolean has_required, boolean required)
+  {
+    this(schema, namespace, name,  nameAlias,
+                 elements, attributes,
+                 contentHandler, classObject, has_required);
+		this.m_required = required;
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param has_required true if this element has required elements by the XSLT specification.
+   * @param required true if this element is required by the XSLT specification.
+   * @param order the order this element should appear according to the XSLT specification.   
+   * @param multiAllowed whether this element is allowed more than once
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, 
+								 boolean has_required, boolean required, int order, 
+								 boolean multiAllowed)
+  {
+		this(schema, namespace, name,  nameAlias,
+                 elements, attributes,
+                 contentHandler, classObject, has_required, required);    
+		this.m_order = order;
+		this.m_multiAllowed = multiAllowed;
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param has_required true if this element has required elements by the XSLT specification.
+   * @param required true if this element is required by the XSLT specification.
+   * @param has_order whether this element has ordered child elements
+   * @param order the order this element should appear according to the XSLT specification.   
+   * @param multiAllowed whether this element is allowed more than once
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, 
+								 boolean has_required, boolean required, boolean has_order, int order, 
+								 boolean multiAllowed)
+  {
+		this(schema, namespace, name,  nameAlias,
+                 elements, attributes,
+                 contentHandler, classObject, has_required, required);    
+		this.m_order = order;
+		this.m_multiAllowed = multiAllowed;
+    this.m_isOrdered = has_order;		
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param has_order whether this element has ordered child elements
+   * @param order the order this element should appear according to the XSLT specification.   
+   * @param multiAllowed whether this element is allowed more than once
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, 
+								 boolean has_order, int order, boolean multiAllowed)
+  {
+    this(schema, namespace, name,  nameAlias,
+                 elements, attributes,
+                 contentHandler, classObject, 
+								 order, multiAllowed);
+		this.m_isOrdered = has_order;		
+  }
+	
+	/**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   * @param order the order this element should appear according to the XSLT specification.   
+   * @param multiAllowed whether this element is allowed more than once
+   */
+  XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
+                 XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+                 XSLTElementProcessor contentHandler, Class classObject, 
+								 int order, boolean multiAllowed)
+  {
+    this(schema, namespace, name, nameAlias, elements, attributes, contentHandler,
+          classObject);
+    this.m_order = order;
+		this.m_multiAllowed = multiAllowed;
+  }
+
+  /**
+   * Construct an instance of XSLTElementDef that represents text.
+   *
+   * @param classObject The class of the object that this element def should produce.
+   * @param contentHandler The element processor for this element.
+   * @param type Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
+   */
+  XSLTElementDef(Class classObject, XSLTElementProcessor contentHandler,
+                 int type)
+  {
+
+    this.m_classObject = classObject;
+    this.m_type = type;
+
+    setElementProcessor(contentHandler);
+  }
+
+  /**
+   * Construct an instance of XSLTElementDef.
+   *
+   * @param namespace  The Namespace URI, "*", or null.
+   * @param name The local name (without prefix), "*", or null.
+   * @param nameAlias A potential alias for the name, or null.
+   * @param elements An array of allowed child element defs, or null.
+   * @param attributes An array of allowed attribute defs, or null.
+   * @param contentHandler The element processor for this element.
+   * @param classObject The class of the object that this element def should produce.
+   */
+  void build(String namespace, String name, String nameAlias,
+             XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
+             XSLTElementProcessor contentHandler, Class classObject)
+  {
+
+    this.m_namespace = namespace;
+    this.m_name = name;
+    this.m_nameAlias = nameAlias;
+    this.m_elements = elements;
+    this.m_attributes = attributes;
+
+    setElementProcessor(contentHandler);
+
+    this.m_classObject = classObject;
+		
+		if (hasRequired() && m_elements != null)
+		{
+			int n = m_elements.length;
+			for (int i = 0; i < n; i++)
+			{
+				XSLTElementDef def = m_elements[i];
+				
+				if (def != null && def.getRequired())
+				{
+					if (m_requiredFound == null)			
+						m_requiredFound = new Hashtable();
+					m_requiredFound.put(def.getName(), "xsl:" +def.getName()); 
+				}
+			}
+		}
+  }
+
+  /**
+   * Tell if two objects are equal, when either one may be null.
+   * If both are null, they are considered equal.
+   *
+   * @param obj1 A reference to the first object, or null.
+   * @param obj2 A reference to the second object, or null.
+   *
+   * @return true if the to objects are equal by both being null or 
+   * because obj2.equals(obj1) returns true.
+   */
+  private static boolean equalsMayBeNull(Object obj1, Object obj2)
+  {
+    return (obj2 == obj1)
+           || ((null != obj1) && (null != obj2) && obj2.equals(obj1));
+  }
+
+  /**
+   * Tell if the two string refs are equal,
+   * equality being defined as:
+   * 1) Both strings are null.
+   * 2) One string is null and the other is empty.
+   * 3) Both strings are non-null, and equal.
+   *
+   * @param s1 A reference to the first string, or null.
+   * @param s2 A reference to the second string, or null.
+   *
+   * @return true if Both strings are null, or if 
+   * one string is null and the other is empty, or if 
+   * both strings are non-null, and equal because 
+   * s1.equals(s2) returns true.
+   */
+  private static boolean equalsMayBeNullOrZeroLen(String s1, String s2)
+  {
+
+    int len1 = (s1 == null) ? 0 : s1.length();
+    int len2 = (s2 == null) ? 0 : s2.length();
+
+    return (len1 != len2) ? false 
+						 : (len1 == 0) ? true 
+								 : s1.equals(s2);
+  }
+
+  /** Content type enumerations    */
+  static final int T_ELEMENT = 1, T_PCDATA = 2, T_ANY = 3;
+
+  /**
+   * The type of this element.
+   */
+  private int m_type = T_ELEMENT;
+
+  /**
+   * Get the type of this element.
+   *
+   * @return Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
+   */
+  int getType()
+  {
+    return m_type;
+  }
+
+  /**
+   * Set the type of this element.
+   *
+   * @param t Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
+   */
+  void setType(int t)
+  {
+    m_type = t;
+  }
+
+  /**
+   * The allowed namespace for this element.
+   */
+  private String m_namespace;
+
+  /**
+   * Get the allowed namespace for this element.
+   *
+   * @return The Namespace URI, "*", or null.
+   */
+  String getNamespace()
+  {
+    return m_namespace;
+  }
+
+  /**
+   * The name of this element.
+   */
+  private String m_name;
+
+  /**
+   * Get the local name of this element.
+   *
+   * @return The local name of this element, "*", or null.
+   */
+  String getName()
+  {
+    return m_name;
+  }
+
+  /**
+   * The name of this element.
+   */
+  private String m_nameAlias;
+
+  /**
+   * Get the name of this element.
+   *
+   * @return A potential alias for the name, or null.
+   */
+  String getNameAlias()
+  {
+    return m_nameAlias;
+  }
+
+  /**
+   * The allowed elements for this type.
+   */
+  private XSLTElementDef[] m_elements;
+
+  /**
+   * Get the allowed elements for this type.
+   *
+   * @return An array of allowed child element defs, or null.
+   * @xsl.usage internal
+   */
+  public XSLTElementDef[] getElements()
+  {
+    return m_elements;
+  }
+
+  /**
+   * Set the allowed elements for this type.
+   *
+   * @param defs An array of allowed child element defs, or null.
+   */
+  void setElements(XSLTElementDef[] defs)
+  {
+    m_elements = defs;
+  }
+
+  /**
+   * Tell if the namespace URI and local name match this
+   * element.
+   * @param uri The namespace uri, which may be null.
+   * @param localName The local name of an element, which may be null.
+   *
+   * @return true if the uri and local name arguments are considered 
+   * to match the uri and local name of this element def.
+   */
+  private boolean QNameEquals(String uri, String localName)
+  {
+
+    return (equalsMayBeNullOrZeroLen(m_namespace, uri)
+            && (equalsMayBeNullOrZeroLen(m_name, localName)
+                || equalsMayBeNullOrZeroLen(m_nameAlias, localName)));
+  }
+
+  /**
+   * Given a namespace URI, and a local name, get the processor
+   * for the element, or return null if not allowed.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   *
+   * @return The element processor that matches the arguments, or null.
+   */
+  XSLTElementProcessor getProcessorFor(String uri, String localName) 
+	{
+
+    XSLTElementProcessor elemDef = null;  // return value
+
+    if (null == m_elements)
+      return null;
+
+    int n = m_elements.length;
+    int order = -1;
+		boolean multiAllowed = true;
+    for (int i = 0; i < n; i++)
+    {
+      XSLTElementDef def = m_elements[i];
+
+      // A "*" signals that the element allows literal result
+      // elements, so just assign the def, and continue to  
+      // see if anything else matches.
+      if (def.m_name.equals("*"))
+      {
+				
+        // Don't allow xsl elements
+        if (!equalsMayBeNullOrZeroLen(uri, Constants.S_XSLNAMESPACEURL))
+				{
+          elemDef = def.m_elementProcessor;
+				  order = def.getOrder();
+					multiAllowed = def.getMultiAllowed();
+				}
+      }
+			else if (def.QNameEquals(uri, localName))
+			{	
+				if (def.getRequired())
+					this.setRequiredFound(def.getName(), true);
+				order = def.getOrder();
+				multiAllowed = def.getMultiAllowed();
+				elemDef = def.m_elementProcessor;
+				break;
+			}
+		}		
+		
+		if (elemDef != null && this.isOrdered())
+		{			
+			int lastOrder = getLastOrder();
+			if (order > lastOrder)
+				setLastOrder(order);
+			else if (order == lastOrder && !multiAllowed)
+			{
+				return null;
+			}
+			else if (order < lastOrder && order > 0)
+			{
+				return null;
+			}
+		}
+
+    return elemDef;
+  }
+
+  /**
+   * Given an unknown element, get the processor
+   * for the element.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   *
+   * @return normally a {@link ProcessorUnknown} reference.
+   * @see ProcessorUnknown
+   */
+  XSLTElementProcessor getProcessorForUnknown(String uri, String localName)
+  {
+
+    // XSLTElementProcessor lreDef = null; // return value
+    if (null == m_elements)
+      return null;
+
+    int n = m_elements.length;
+
+    for (int i = 0; i < n; i++)
+    {
+      XSLTElementDef def = m_elements[i];
+
+      if (def.m_name.equals("unknown") && uri.length() > 0)
+      {
+        return def.m_elementProcessor;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * The allowed attributes for this type.
+   */
+  private XSLTAttributeDef[] m_attributes;
+
+  /**
+   * Get the allowed attributes for this type.
+   *
+   * @return An array of allowed attribute defs, or null.
+   */
+  XSLTAttributeDef[] getAttributes()
+  {
+    return m_attributes;
+  }
+
+  /**
+   * Given a namespace URI, and a local name, return the element's
+   * attribute definition, if it has one.
+   *
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   *
+   * @return The attribute def that matches the arguments, or null.
+   */
+  XSLTAttributeDef getAttributeDef(String uri, String localName)
+  {
+
+    XSLTAttributeDef defaultDef = null;
+    XSLTAttributeDef[] attrDefs = getAttributes();
+    int nAttrDefs = attrDefs.length;
+
+    for (int k = 0; k < nAttrDefs; k++)
+    {
+      XSLTAttributeDef attrDef = attrDefs[k];
+      String uriDef = attrDef.getNamespace();
+      String nameDef = attrDef.getName();
+      
+      if (nameDef.equals("*") && (equalsMayBeNullOrZeroLen(uri, uriDef) || 
+          (uriDef != null && uriDef.equals("*") && uri!=null && uri.length() > 0 )))
+      {
+        return attrDef;
+      }
+      else if (nameDef.equals("*") && (uriDef == null))
+      {
+
+        // In this case, all attributes are legal, so return 
+        // this as the last resort.
+        defaultDef = attrDef;
+      }
+      else if (equalsMayBeNullOrZeroLen(uri, uriDef)
+               && localName.equals(nameDef))
+      {
+        return attrDef;
+      }
+    }
+
+    if (null == defaultDef)
+    {
+      if (uri.length() > 0 && !equalsMayBeNullOrZeroLen(uri, Constants.S_XSLNAMESPACEURL))
+      {
+        return XSLTAttributeDef.m_foreignAttr;
+      }
+    }
+
+    return defaultDef;
+  }
+
+  /**
+   * If non-null, the ContentHandler/TransformerFactory for this element.
+   */
+  private XSLTElementProcessor m_elementProcessor;
+
+  /**
+   * Return the XSLTElementProcessor for this element.
+   *
+   * @return The element processor for this element.
+   * @xsl.usage internal
+   */
+  public XSLTElementProcessor getElementProcessor()
+  {
+    return m_elementProcessor;
+  }
+
+  /**
+   * Set the XSLTElementProcessor for this element.
+   *
+   * @param handler The element processor for this element.
+   * @xsl.usage internal
+   */
+  public void setElementProcessor(XSLTElementProcessor handler)
+  {
+
+    if (handler != null)
+    {
+      m_elementProcessor = handler;
+
+      m_elementProcessor.setElemDef(this);
+    }
+  }
+
+  /**
+   * If non-null, the class object that should in instantiated for
+   * a Xalan instance of this element.
+   */
+  private Class m_classObject;
+
+  /**
+   * Return the class object that should in instantiated for
+   * a Xalan instance of this element.
+   *
+   * @return The class of the object that this element def should produce, or null.
+   */
+  Class getClassObject()
+  {
+    return m_classObject;
+  }
+	
+	/**
+   * If true, this has a required element.
+   */
+  private boolean m_has_required = false;
+
+  /**
+   * Get whether or not this has a required element.
+   *
+   * @return true if this this has a required element.
+   */
+  boolean hasRequired()
+  {
+    return m_has_required;
+  }
+	
+	/**
+   * If true, this is a required element.
+   */
+  private boolean m_required = false;
+
+  /**
+   * Get whether or not this is a required element.
+   *
+   * @return true if this is a required element.
+   */
+  boolean getRequired()
+  {
+    return m_required;
+  }
+	
+	Hashtable m_requiredFound;
+	
+	/**
+   * Set this required element found.
+   *
+   */
+  void setRequiredFound(String elem, boolean found)
+  {
+   if (m_requiredFound.get(elem) != null) 
+		 m_requiredFound.remove(elem);
+  }
+	
+	/**
+   * Get whether all required elements were found.
+   *
+   * @return true if all required elements were found.
+   */
+  boolean getRequiredFound()
+  {
+		if (m_requiredFound == null)
+			return true;
+    return m_requiredFound.isEmpty();
+  }
+	
+	/**
+   * Get required elements that were not found.
+   *
+   * @return required elements that were not found.
+   */
+  String getRequiredElem()
+  {
+		if (m_requiredFound == null)
+			return null;
+		Enumeration elems = m_requiredFound.elements();
+		String s = "";
+		boolean first = true;
+		while (elems.hasMoreElements())
+		{
+			if (first)
+				first = false;
+			else
+			 s = s + ", ";
+			s = s + (String)elems.nextElement();
+		}
+    return s;
+  }
+	
+	boolean m_isOrdered = false;	
+	
+	/**
+   * Get whether this element requires ordered children.
+   *
+   * @return true if this element requires ordered children.
+   */
+  boolean isOrdered()
+  {
+		/*if (!m_CheckedOrdered)
+		{
+			m_CheckedOrdered = true;
+			m_isOrdered = false;
+			if (null == m_elements)
+				return false;
+
+			int n = m_elements.length;
+
+			for (int i = 0; i < n; i++)
+			{
+				if (m_elements[i].getOrder() > 0)
+				{
+					m_isOrdered = true;
+					return true;
+				}
+			}
+			return false;
+		}
+		else*/
+			return m_isOrdered;
+  }
+	
+	/**
+   * the order that this element should appear, or -1 if not ordered
+   */
+  private int m_order = -1;
+	
+	/**
+   * Get the order that this element should appear .
+   *
+   * @return the order that this element should appear.
+   */
+  int getOrder()
+  {
+    return m_order;
+  }
+	
+	/**
+   * the highest order of child elements have appeared so far, 
+   * or -1 if not ordered
+   */
+  private int m_lastOrder = -1;
+	
+	/**
+   * Get the highest order of child elements have appeared so far .
+   *
+   * @return the highest order of child elements have appeared so far.
+   */
+  int getLastOrder()
+  {
+    return m_lastOrder;
+  }
+	
+	/**
+   * Set the highest order of child elements have appeared so far .
+   *
+   * @param order the highest order of child elements have appeared so far.
+   */
+  void setLastOrder(int order)
+  {
+    m_lastOrder = order ;
+  }
+	
+	/**
+   * True if this element can appear multiple times
+   */
+  private boolean m_multiAllowed = true;
+	
+	/**
+   * Get whether this element can appear multiple times
+   *
+   * @return true if this element can appear multiple times
+   */
+  boolean getMultiAllowed()
+  {
+    return m_multiAllowed;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/XSLTElementProcessor.java b/src/main/java/org/apache/xalan/processor/XSLTElementProcessor.java
new file mode 100644
index 0000000..7858b42
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/XSLTElementProcessor.java
@@ -0,0 +1,383 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTElementProcessor.java 469688 2006-10-31 22:39:43Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xml.utils.IntStack;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class acts as the superclass for all stylesheet element
+ * processors, and deals with things that are common to all elements.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ */
+public class XSLTElementProcessor extends ElemTemplateElement
+{
+    static final long serialVersionUID = 5597421564955304421L;
+
+  /**
+   * Construct a processor for top-level elements.
+   * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+   */
+  XSLTElementProcessor(){}
+	
+	private IntStack m_savedLastOrder;
+
+  /**
+   * The element definition that this processor conforms to.
+   */
+  private XSLTElementDef m_elemDef;
+
+  /**
+   * Get the element definition that belongs to this element.
+   *
+   * @return The element definition object that produced and constrains this element.
+   */
+  XSLTElementDef getElemDef()
+  {
+    return m_elemDef;
+  }
+
+  /**
+   * Set the element definition that belongs to this element.
+   *
+   * @param def The element definition object that produced and constrains this element.
+   */
+  void setElemDef(XSLTElementDef def)
+  {
+    m_elemDef = def;
+  }
+
+  /**
+   * Resolve an external entity.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param publicId The public identifer, or null if none is
+   *                 available.
+   * @param systemId The system identifier provided in the XML
+   *                 document.
+   * @return The new input source, or null to require the
+   *         default behaviour.
+   */
+  public InputSource resolveEntity(
+          StylesheetHandler handler, String publicId, String systemId)
+            throws org.xml.sax.SAXException
+  {
+    return null;
+  }
+
+  /**
+   * Receive notification of a notation declaration.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param name The notation name.
+   * @param publicId The notation public identifier, or null if not
+   *                 available.
+   * @param systemId The notation system identifier.
+   * @see org.xml.sax.DTDHandler#notationDecl
+   */
+  public void notationDecl(StylesheetHandler handler, String name,
+                           String publicId, String systemId)
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of an unparsed entity declaration.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param name The entity name.
+   * @param publicId The entity public identifier, or null if not
+   *                 available.
+   * @param systemId The entity system identifier.
+   * @param notationName The name of the associated notation.
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void unparsedEntityDecl(StylesheetHandler handler, String name,
+                                 String publicId, String systemId,
+                                 String notationName)
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of the start of the non-text event.  This
+   * is sent to the current processor when any non-text event occurs.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   */
+  public void startNonText(StylesheetHandler handler) throws org.xml.sax.SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   * @param attributes The specified or defaulted attributes.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+
+    if (m_savedLastOrder == null)
+				m_savedLastOrder = new IntStack();
+			m_savedLastOrder.push(getElemDef().getLastOrder());
+			getElemDef().setLastOrder(-1);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param uri The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param rawName The qualified name (with prefix).
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+		if (m_savedLastOrder != null && !m_savedLastOrder.empty())
+			getElemDef().setLastOrder(m_savedLastOrder.pop());
+		
+		if (!getElemDef().getRequiredFound())
+			handler.error(XSLTErrorResources.ER_REQUIRED_ELEM_NOT_FOUND, new Object[]{getElemDef().getRequiredElem()}, null);
+  }
+
+  /**
+   * Receive notification of character data inside an element.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param ch The characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   */
+  public void characters(
+          StylesheetHandler handler, char ch[], int start, int length)
+            throws org.xml.sax.SAXException
+  {
+    handler.error(XSLTErrorResources.ER_CHARS_NOT_ALLOWED, null, null);//"Characters are not allowed at this point in the document!",
+                  //null);
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param ch The whitespace characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   */
+  public void ignorableWhitespace(
+          StylesheetHandler handler, char ch[], int start, int length)
+            throws org.xml.sax.SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   */
+  public void processingInstruction(
+          StylesheetHandler handler, String target, String data)
+            throws org.xml.sax.SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of a skipped entity.
+   *
+   *
+   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+   * @param name The name of the skipped entity.
+   */
+  public void skippedEntity(StylesheetHandler handler, String name)
+          throws org.xml.sax.SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Set the properties of an object from the given attribute list.
+   * @param handler The stylesheet's Content handler, needed for
+   *                error reporting.
+   * @param rawName The raw name of the owner element, needed for
+   *                error reporting.
+   * @param attributes The list of attributes.
+   * @param target The target element where the properties will be set.
+   */
+  void setPropertiesFromAttributes(
+          StylesheetHandler handler, String rawName, Attributes attributes, 
+          ElemTemplateElement target)
+            throws org.xml.sax.SAXException
+  {
+    setPropertiesFromAttributes(handler, rawName, attributes, target, true);
+  }
+
+  /**
+   * Set the properties of an object from the given attribute list.
+   * @param handler The stylesheet's Content handler, needed for
+   *                error reporting.
+   * @param rawName The raw name of the owner element, needed for
+   *                error reporting.
+   * @param attributes The list of attributes.
+   * @param target The target element where the properties will be set.
+   * @param throwError True if it should throw an error if an
+   * attribute is not defined.
+   * @return the attributes not allowed on this element.
+   *
+   * @throws TransformerException
+   */
+  Attributes setPropertiesFromAttributes(
+          StylesheetHandler handler, String rawName, Attributes attributes, 
+          ElemTemplateElement target, boolean throwError)
+            throws org.xml.sax.SAXException
+  {
+
+    XSLTElementDef def = getElemDef();
+    AttributesImpl undefines = null;
+    boolean isCompatibleMode = ((null != handler.getStylesheet() 
+                                 && handler.getStylesheet().getCompatibleMode())
+                                || !throwError);
+    if (isCompatibleMode)
+      undefines = new AttributesImpl();
+
+
+    // Keep track of which XSLTAttributeDefs have been processed, so 
+    // I can see which default values need to be set.
+    List processedDefs = new ArrayList();
+
+    // Keep track of XSLTAttributeDefs that were invalid
+    List errorDefs = new ArrayList();    
+    int nAttrs = attributes.getLength();
+
+    for (int i = 0; i < nAttrs; i++)
+    {
+      String attrUri = attributes.getURI(i);
+      // Hack for Crimson.  -sb
+      if((null != attrUri) && (attrUri.length() == 0)
+                           && (attributes.getQName(i).startsWith("xmlns:") || 
+                               attributes.getQName(i).equals("xmlns")))
+      {
+        attrUri = org.apache.xalan.templates.Constants.S_XMLNAMESPACEURI;
+      }
+      String attrLocalName = attributes.getLocalName(i);
+      XSLTAttributeDef attrDef = def.getAttributeDef(attrUri, attrLocalName);
+
+      if (null == attrDef)
+      {
+        if (!isCompatibleMode)
+        {
+
+          // Then barf, because this element does not allow this attribute.
+          handler.error(XSLTErrorResources.ER_ATTR_NOT_ALLOWED, new Object[]{attributes.getQName(i), rawName}, null);//"\""+attributes.getQName(i)+"\""
+                        //+ " attribute is not allowed on the " + rawName
+                       // + " element!", null);
+        }
+        else
+        {
+          undefines.addAttribute(attrUri, attrLocalName,
+                                 attributes.getQName(i),
+                                 attributes.getType(i),
+                                 attributes.getValue(i));
+        }
+      }
+      else
+      {
+        // Can we switch the order here:
+
+        boolean success = attrDef.setAttrValue(handler, attrUri, attrLocalName,
+                             attributes.getQName(i), attributes.getValue(i),
+                             target);
+                             
+        // Now we only add the element if it passed a validation check
+        if (success)
+            processedDefs.add(attrDef);
+        else
+            errorDefs.add(attrDef);
+      }
+    }
+
+    XSLTAttributeDef[] attrDefs = def.getAttributes();
+    int nAttrDefs = attrDefs.length;
+
+    for (int i = 0; i < nAttrDefs; i++)
+    {
+      XSLTAttributeDef attrDef = attrDefs[i];
+      String defVal = attrDef.getDefault();
+
+      if (null != defVal)
+      {
+        if (!processedDefs.contains(attrDef))
+        {
+          attrDef.setDefAttrValue(handler, target);
+        }
+      }
+
+      if (attrDef.getRequired())
+      {
+        if ((!processedDefs.contains(attrDef)) && (!errorDefs.contains(attrDef)))
+          handler.error(
+            XSLMessages.createMessage(
+              XSLTErrorResources.ER_REQUIRES_ATTRIB, new Object[]{ rawName,
+                                                                   attrDef.getName() }), null);
+      }
+    }
+
+    return undefines;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/processor/XSLTSchema.java b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
new file mode 100644
index 0000000..8f6eb2e
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
@@ -0,0 +1,922 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTSchema.java 476466 2006-11-18 08:22:31Z minchau $
+ */
+package org.apache.xalan.processor;
+
+import java.util.HashMap;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemApplyImport;
+import org.apache.xalan.templates.ElemApplyTemplates;
+import org.apache.xalan.templates.ElemAttribute;
+import org.apache.xalan.templates.ElemCallTemplate;
+import org.apache.xalan.templates.ElemChoose;
+import org.apache.xalan.templates.ElemComment;
+import org.apache.xalan.templates.ElemCopy;
+import org.apache.xalan.templates.ElemCopyOf;
+import org.apache.xalan.templates.ElemElement;
+import org.apache.xalan.templates.ElemExsltFuncResult;
+import org.apache.xalan.templates.ElemExsltFunction;
+import org.apache.xalan.templates.ElemExtensionDecl;
+import org.apache.xalan.templates.ElemExtensionScript;
+import org.apache.xalan.templates.ElemFallback;
+import org.apache.xalan.templates.ElemForEach;
+import org.apache.xalan.templates.ElemIf;
+import org.apache.xalan.templates.ElemLiteralResult;
+import org.apache.xalan.templates.ElemMessage;
+import org.apache.xalan.templates.ElemNumber;
+import org.apache.xalan.templates.ElemOtherwise;
+import org.apache.xalan.templates.ElemPI;
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemSort;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemText;
+import org.apache.xalan.templates.ElemTextLiteral;
+import org.apache.xalan.templates.ElemUnknown;
+import org.apache.xalan.templates.ElemValueOf;
+import org.apache.xalan.templates.ElemVariable;
+import org.apache.xalan.templates.ElemWhen;
+import org.apache.xalan.templates.ElemWithParam;
+import org.apache.xml.utils.QName;
+
+/**
+ * This class defines the allowed structure for a stylesheet, and the
+ * mapping between Xalan classes and the markup elements in the stylesheet.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ */
+public class XSLTSchema extends XSLTElementDef
+{
+
+  /**
+   * Construct a XSLTSchema which represents the XSLT "schema".
+   */
+  XSLTSchema()
+  {
+    build();
+  }
+
+  /**
+   * This method builds an XSLT "schema" according to http://www.w3.org/TR/xslt#dtd.  This
+   * schema provides instructions for building the Xalan Stylesheet (Templates) structure.
+   */
+  void build()
+  {
+	// xsl:import, xsl:include
+    XSLTAttributeDef hrefAttr = new XSLTAttributeDef(null, "href",
+                                  XSLTAttributeDef.T_URL, true, false,XSLTAttributeDef.ERROR);
+                                  
+	// xsl:preserve-space, xsl:strip-space
+    XSLTAttributeDef elementsAttr = new XSLTAttributeDef(null, "elements",
+                                      XSLTAttributeDef.T_SIMPLEPATTERNLIST,
+                                      true, false, XSLTAttributeDef.ERROR);
+                                      
+    // XSLTAttributeDef anyNamespacedAttr = new XSLTAttributeDef("*", "*",
+    //                                XSLTAttributeDef.T_CDATA, false);
+    
+    // xsl:output
+    XSLTAttributeDef methodAttr = new XSLTAttributeDef(null, "method",
+                                    XSLTAttributeDef.T_QNAME, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef versionAttr = new XSLTAttributeDef(null, "version",
+                                     XSLTAttributeDef.T_NMTOKEN, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef encodingAttr = new XSLTAttributeDef(null, "encoding",
+                                      XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef omitXmlDeclarationAttr = new XSLTAttributeDef(null,
+                                                "omit-xml-declaration",
+                                                XSLTAttributeDef.T_YESNO,
+                                                false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef standaloneAttr = new XSLTAttributeDef(null,
+                                        "standalone",
+                                        XSLTAttributeDef.T_YESNO, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef doctypePublicAttr = new XSLTAttributeDef(null,
+                                           "doctype-public",
+                                           XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef doctypeSystemAttr = new XSLTAttributeDef(null,
+                                           "doctype-system",
+                                           XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef cdataSectionElementsAttr = new XSLTAttributeDef(null,
+                                                  "cdata-section-elements",
+                                                  XSLTAttributeDef.T_QNAMES_RESOLVE_NULL,
+                                                  false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef indentAttr = new XSLTAttributeDef(null, "indent",
+                                    XSLTAttributeDef.T_YESNO, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef mediaTypeAttr = new XSLTAttributeDef(null, "media-type",
+                                       XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.ERROR);
+                                       
+                  
+    // Required.
+    // It is an error if the name attribute is invalid on any of these elements
+    // xsl:key, xsl:attribute-set, xsl:call-template, xsl:with-param, xsl:variable, xsl:param
+    XSLTAttributeDef nameAttrRequired = new XSLTAttributeDef(null, "name",
+                                          XSLTAttributeDef.T_QNAME, true, false,XSLTAttributeDef.ERROR);
+	// Required.
+    // Support AVT
+    // xsl:element, xsl:attribute                                    
+    XSLTAttributeDef nameAVTRequired = new XSLTAttributeDef(null, "name",
+                                         XSLTAttributeDef.T_AVT_QNAME, true, true,XSLTAttributeDef.WARNING);
+            
+
+    // Required.
+    // Support AVT
+    // xsl:processing-instruction                                     
+    XSLTAttributeDef nameAVT_NCNAMERequired = new XSLTAttributeDef(null, "name",
+                                         XSLTAttributeDef.T_NCNAME, true, true,XSLTAttributeDef.WARNING);
+                                        
+    // Optional.
+    // Static error if invalid
+    // xsl:template, xsl:decimal-format                                      
+    XSLTAttributeDef nameAttrOpt_ERROR = new XSLTAttributeDef(null, "name",
+                                     XSLTAttributeDef.T_QNAME, false, false,XSLTAttributeDef.ERROR);
+
+    // xsl:key                                 
+    XSLTAttributeDef useAttr = new XSLTAttributeDef(null, "use",
+                                 XSLTAttributeDef.T_EXPR, true, false,XSLTAttributeDef.ERROR);
+           
+    // xsl:element, xsl:attribute                              
+    XSLTAttributeDef namespaceAVTOpt = new XSLTAttributeDef(null,
+                                         "namespace",XSLTAttributeDef.T_URL,
+                                         false, true,XSLTAttributeDef.WARNING);
+    // xsl:decimal-format                                     
+    XSLTAttributeDef decimalSeparatorAttr = new XSLTAttributeDef(null,
+                                              "decimal-separator",
+                                              XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR, ".");
+    XSLTAttributeDef infinityAttr = new XSLTAttributeDef(null, "infinity",
+                                      XSLTAttributeDef.T_CDATA, false,XSLTAttributeDef.ERROR,"Infinity");
+    XSLTAttributeDef minusSignAttr = new XSLTAttributeDef(null, "minus-sign",
+                                       XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR,"-");
+    XSLTAttributeDef NaNAttr = new XSLTAttributeDef(null, "NaN",
+                                 XSLTAttributeDef.T_CDATA, false,XSLTAttributeDef.ERROR, "NaN");
+    XSLTAttributeDef percentAttr = new XSLTAttributeDef(null, "percent",
+                                     XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR, "%");
+    XSLTAttributeDef perMilleAttr = new XSLTAttributeDef(null, "per-mille",
+                                      XSLTAttributeDef.T_CHAR,
+                                      false, false,XSLTAttributeDef.ERROR /* ,"&#x2030;" */);
+    XSLTAttributeDef zeroDigitAttr = new XSLTAttributeDef(null, "zero-digit",
+                                       XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR, "0");
+    XSLTAttributeDef digitAttr = new XSLTAttributeDef(null, "digit",
+                                   XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR, "#");
+    XSLTAttributeDef patternSeparatorAttr = new XSLTAttributeDef(null,
+                                              "pattern-separator",
+                                              XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR, ";");
+    // xsl:decimal-format                                         
+    XSLTAttributeDef groupingSeparatorAttr = new XSLTAttributeDef(null,
+                                               "grouping-separator",
+                                               XSLTAttributeDef.T_CHAR, false,XSLTAttributeDef.ERROR,",");
+
+                                              
+    // xsl:element, xsl:attribute-set, xsl:copy                                           
+    XSLTAttributeDef useAttributeSetsAttr = new XSLTAttributeDef(null,
+                                              "use-attribute-sets",
+                                              XSLTAttributeDef.T_QNAMES,
+                                              false, false, XSLTAttributeDef.ERROR);
+
+    // xsl:if, xsl:when         
+    XSLTAttributeDef testAttrRequired = new XSLTAttributeDef(null, "test",   
+                                          XSLTAttributeDef.T_EXPR, true, false,XSLTAttributeDef.ERROR);
+      
+      
+    // Required.                                       
+    // xsl:value-of, xsl:for-each, xsl:copy-of                             
+    XSLTAttributeDef selectAttrRequired = new XSLTAttributeDef(null,
+                                            "select",
+                                            XSLTAttributeDef.T_EXPR, true, false,XSLTAttributeDef.ERROR);
+
+    // Optional.                                          
+    // xsl:variable, xsl:param, xsl:with-param                                       
+    XSLTAttributeDef selectAttrOpt = new XSLTAttributeDef(null, "select",
+                                       XSLTAttributeDef.T_EXPR, false, false,XSLTAttributeDef.ERROR);
+
+    // Optional.
+    // Default: "node()"
+    // xsl:apply-templates                                           
+    XSLTAttributeDef selectAttrDefNode = new XSLTAttributeDef(null, "select",
+                                           XSLTAttributeDef.T_EXPR, false,XSLTAttributeDef.ERROR, "node()");
+    // Optional.
+    // Default: "."
+    // xsl:sort                                        
+    XSLTAttributeDef selectAttrDefDot = new XSLTAttributeDef(null, "select",
+                                          XSLTAttributeDef.T_EXPR, false,XSLTAttributeDef.ERROR, ".");
+    // xsl:key                                      
+    XSLTAttributeDef matchAttrRequired = new XSLTAttributeDef(null, "match",
+                                           XSLTAttributeDef.T_PATTERN, true, false,XSLTAttributeDef.ERROR);
+    // xsl:template                                       
+    XSLTAttributeDef matchAttrOpt = new XSLTAttributeDef(null, "match",
+                                      XSLTAttributeDef.T_PATTERN, false, false,XSLTAttributeDef.ERROR);
+    // xsl:template                                  
+    XSLTAttributeDef priorityAttr = new XSLTAttributeDef(null, "priority",
+                                     XSLTAttributeDef.T_NUMBER, false, false,XSLTAttributeDef.ERROR);
+                                     
+    // xsl:template, xsl:apply-templates                                 
+    XSLTAttributeDef modeAttr = new XSLTAttributeDef(null, "mode",
+                                     XSLTAttributeDef.T_QNAME, false, false,XSLTAttributeDef.ERROR);
+   
+    XSLTAttributeDef spaceAttr =
+      new XSLTAttributeDef(Constants.S_XMLNAMESPACEURI, "space", false, false, false, XSLTAttributeDef.WARNING,
+                           "default", Constants.ATTRVAL_STRIP, "preserve",
+                           Constants.ATTRVAL_PRESERVE);
+                           
+                         
+    XSLTAttributeDef spaceAttrLiteral =
+      new XSLTAttributeDef(Constants.S_XMLNAMESPACEURI, "space", 
+                                          XSLTAttributeDef.T_URL, false, true,XSLTAttributeDef.ERROR);
+    // xsl:namespace-alias                                      
+    XSLTAttributeDef stylesheetPrefixAttr = new XSLTAttributeDef(null,
+                                              "stylesheet-prefix",
+                                              XSLTAttributeDef.T_CDATA, true, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef resultPrefixAttr = new XSLTAttributeDef(null,
+                                          "result-prefix",
+                                          XSLTAttributeDef.T_CDATA, true, false,XSLTAttributeDef.ERROR);
+                                          
+    // xsl:text, xsl:value-of                                      
+    XSLTAttributeDef disableOutputEscapingAttr = new XSLTAttributeDef(null,
+                                                   "disable-output-escaping",
+                                                   XSLTAttributeDef.T_YESNO,
+                                                   false, false,XSLTAttributeDef.ERROR);
+                                                   
+	// xsl:number                                                   
+    XSLTAttributeDef levelAttr = new XSLTAttributeDef(null, "level", false, false, false, XSLTAttributeDef.ERROR,
+                                   "single", Constants.NUMBERLEVEL_SINGLE,
+                                   "multiple", Constants.NUMBERLEVEL_MULTI,
+                                   "any", Constants.NUMBERLEVEL_ANY);
+    levelAttr.setDefault("single");
+    XSLTAttributeDef countAttr = new XSLTAttributeDef(null, "count",
+                                   XSLTAttributeDef.T_PATTERN, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef fromAttr = new XSLTAttributeDef(null, "from",
+                                  XSLTAttributeDef.T_PATTERN, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef valueAttr = new XSLTAttributeDef(null, "value",
+                                   XSLTAttributeDef.T_EXPR, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef formatAttr = new XSLTAttributeDef(null, "format",
+                                    XSLTAttributeDef.T_CDATA, false, true,XSLTAttributeDef.ERROR);
+    formatAttr.setDefault("1");
+    
+    // xsl:number, xsl:sort
+    XSLTAttributeDef langAttr = new XSLTAttributeDef(null, "lang",
+                                  XSLTAttributeDef.T_NMTOKEN, false, true,XSLTAttributeDef.ERROR);
+   
+    // xsl:number
+    XSLTAttributeDef letterValueAttr = new XSLTAttributeDef(null,
+                                         "letter-value",
+                                         false, true, false, XSLTAttributeDef.ERROR,
+                                         "alphabetic", Constants.NUMBERLETTER_ALPHABETIC,
+                                         "traditional", Constants.NUMBERLETTER_TRADITIONAL);
+    // xsl:number
+    XSLTAttributeDef groupingSeparatorAVT = new XSLTAttributeDef(null,
+                                              "grouping-separator",
+                                              XSLTAttributeDef.T_CHAR, false, true,XSLTAttributeDef.ERROR);
+    // xsl:number
+    XSLTAttributeDef groupingSizeAttr = new XSLTAttributeDef(null,
+                                          "grouping-size",
+                                          XSLTAttributeDef.T_NUMBER, false, true,XSLTAttributeDef.ERROR);
+   
+   // xsl:sort
+    XSLTAttributeDef dataTypeAttr = new XSLTAttributeDef(null, "data-type", false, true, true, XSLTAttributeDef.ERROR,
+                                    "text", Constants.SORTDATATYPE_TEXT ,"number", Constants.SORTDATATYPE_TEXT);
+	dataTypeAttr.setDefault("text");
+	
+	// xsl:sort
+    XSLTAttributeDef orderAttr = new XSLTAttributeDef(null, "order", false, true, false,XSLTAttributeDef.ERROR,
+                                    "ascending", Constants.SORTORDER_ASCENDING, 
+                                    "descending", Constants.SORTORDER_DESCENDING);
+    orderAttr.setDefault("ascending");
+
+    // xsl:sort                             
+    XSLTAttributeDef caseOrderAttr = new XSLTAttributeDef(null, "case-order", false, true, false,XSLTAttributeDef.ERROR,
+                                       "upper-first", Constants.SORTCASEORDER_UPPERFIRST ,
+                                       "lower-first", Constants.SORTCASEORDER_LOWERFIRST);
+	    
+    // xsl:message                                   
+    XSLTAttributeDef terminateAttr = new XSLTAttributeDef(null, "terminate",
+                                       XSLTAttributeDef.T_YESNO, false, false,XSLTAttributeDef.ERROR);
+    terminateAttr.setDefault("no");
+
+	// top level attributes
+    XSLTAttributeDef xslExcludeResultPrefixesAttr =
+      new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL,
+                           "exclude-result-prefixes",
+                           XSLTAttributeDef.T_PREFIXLIST, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef xslExtensionElementPrefixesAttr =
+      new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL,
+                           "extension-element-prefixes",
+                           XSLTAttributeDef.T_PREFIX_URLLIST, false, false,XSLTAttributeDef.ERROR);
+    // result-element-atts                       
+    XSLTAttributeDef xslUseAttributeSetsAttr =
+      new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "use-attribute-sets",
+                           XSLTAttributeDef.T_QNAMES, false, false,XSLTAttributeDef.ERROR);
+    XSLTAttributeDef xslVersionAttr =
+      new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "version",
+                           XSLTAttributeDef.T_NMTOKEN, false, false,XSLTAttributeDef.ERROR);
+                           
+    XSLTElementDef charData = new XSLTElementDef(this, null, "text()",
+                                null /*alias */, null /* elements */, null,  /* attributes */
+                                new ProcessorCharacters(),
+                                ElemTextLiteral.class /* class object */);
+
+    charData.setType(XSLTElementDef.T_PCDATA);
+
+    XSLTElementDef whiteSpaceOnly = new XSLTElementDef(this, null, "text()",
+                                      null /*alias */, null /* elements */,
+                                      null,  /* attributes */
+                                      null,
+                                      ElemTextLiteral.class /* should be null? -sb */);
+
+    charData.setType(XSLTElementDef.T_PCDATA);
+
+    XSLTAttributeDef resultAttr = new XSLTAttributeDef(null, "*",
+                                    XSLTAttributeDef.T_AVT, false, true,XSLTAttributeDef.WARNING);
+    XSLTAttributeDef xslResultAttr =
+      new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
+                           XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.WARNING);
+                           
+    XSLTElementDef[] templateElements = new XSLTElementDef[23];
+    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[24];
+    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[24];
+    //exslt
+    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[24];
+    
+    XSLTElementDef[] charTemplateElements = new XSLTElementDef[15];
+    XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
+                                     null /*alias */,
+                                     templateElements /* elements */,
+                                     new XSLTAttributeDef[]{
+                                       spaceAttrLiteral, // special
+                                       xslExcludeResultPrefixesAttr,
+                                       xslExtensionElementPrefixesAttr,
+                                       xslUseAttributeSetsAttr,
+                                       xslVersionAttr,
+                                       xslResultAttr,
+                                       resultAttr }, 
+                                        new ProcessorLRE(),
+                                     ElemLiteralResult.class /* class object */, 20, true);
+    XSLTElementDef unknownElement =
+      new XSLTElementDef(this, "*", "unknown", null /*alias */,
+                         templateElementsAndParams /* elements */,
+                         new XSLTAttributeDef[]{ xslExcludeResultPrefixesAttr,
+                                                 xslExtensionElementPrefixesAttr,
+                                                 xslUseAttributeSetsAttr,
+                                                 xslVersionAttr,
+                                                 xslResultAttr,
+                                                 resultAttr }, 
+                                                                                                 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(),
+                                  ElemValueOf.class /* class object */, 20, true);
+    XSLTElementDef xslCopyOf = new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "copy-of",
+                                 null /*alias */, null /* elements */,
+                                 new XSLTAttributeDef[]{ selectAttrRequired },
+                                 new ProcessorTemplateElem(),
+                                 ElemCopyOf.class /* class object */, 20, true);
+    XSLTElementDef xslNumber = new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "number",
+                                 null /*alias */, null /* elements */,
+                                 new XSLTAttributeDef[]{ levelAttr,
+                                                         countAttr,
+                                                         fromAttr,
+                                                         valueAttr,
+                                                         formatAttr,
+                                                         langAttr,
+                                                         letterValueAttr,
+                                                         groupingSeparatorAVT,
+                                                         groupingSizeAttr }, 
+                                        new ProcessorTemplateElem(),
+                                 ElemNumber.class /* class object */, 20, true);
+
+    // <!-- xsl:sort cannot occur after any other elements or
+    // any non-whitespace character -->
+    XSLTElementDef xslSort = new XSLTElementDef(this,
+                                                Constants.S_XSLNAMESPACEURL,
+                                                "sort", null /*alias */,
+                                                null /* elements */,
+                                                new XSLTAttributeDef[]{
+                                                  selectAttrDefDot,
+                                                  langAttr,
+                                                  dataTypeAttr,
+                                                  orderAttr,
+                                                  caseOrderAttr }, 
+                                       new ProcessorTemplateElem(),
+                                                ElemSort.class/* class object */, 19, true );
+    XSLTElementDef xslWithParam = new XSLTElementDef(this,
+                                    Constants.S_XSLNAMESPACEURL,
+                                    "with-param", null /*alias */,
+                                    templateElements /* elements */,  // %template;>
+                                    new XSLTAttributeDef[]{ nameAttrRequired,
+                                                            selectAttrOpt }, new ProcessorTemplateElem(),
+                                                                             ElemWithParam.class /* class object */, 19, true);
+    XSLTElementDef xslApplyTemplates = new XSLTElementDef(this,
+                                         Constants.S_XSLNAMESPACEURL,
+                                         "apply-templates", null /*alias */,
+                                         new XSLTElementDef[]{ xslSort,
+                                                               xslWithParam } /* elements */, new XSLTAttributeDef[]{
+                                                                 selectAttrDefNode,
+                                                                 modeAttr }, 
+                                                                        new ProcessorTemplateElem(),
+                                         ElemApplyTemplates.class /* class object */, 20, true);
+    XSLTElementDef xslApplyImports =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "apply-imports",
+                         null /*alias */, null /* elements */,
+                         new XSLTAttributeDef[]{},
+                         new ProcessorTemplateElem(),
+                         ElemApplyImport.class /* class object */);
+    XSLTElementDef xslForEach = new XSLTElementDef(this,
+                                  Constants.S_XSLNAMESPACEURL, "for-each",
+                                  null /*alias */, templateElementsAndSort,  // (#PCDATA %instructions; %result-elements; | xsl:sort)*
+                                  new XSLTAttributeDef[]{ selectAttrRequired,
+                                                          spaceAttr }, 
+                                               new ProcessorTemplateElem(),
+                                  ElemForEach.class /* class object */, true, false, true, 20, true);
+    XSLTElementDef xslIf = new XSLTElementDef(this,
+                                              Constants.S_XSLNAMESPACEURL,
+                                              "if", null /*alias */,
+                                              templateElements /* elements */,  // %template;
+                                              new XSLTAttributeDef[]{
+                                                testAttrRequired,
+                                                spaceAttr }, new ProcessorTemplateElem(),
+                                                             ElemIf.class /* class object */, 20, true);
+    XSLTElementDef xslWhen =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "when",
+                         null /*alias */, templateElements /* elements */,  // %template;>
+                                                new XSLTAttributeDef[]{
+                                                  testAttrRequired,
+                                                  spaceAttr }, new ProcessorTemplateElem(),
+                                                               ElemWhen.class /* class object */,
+                                                                                                false, true, 1, true);
+    XSLTElementDef xslOtherwise = new XSLTElementDef(this,
+                                    Constants.S_XSLNAMESPACEURL, "otherwise",
+                                    null /*alias */,
+                                    templateElements /* elements */,  // %template;>
+                                    new XSLTAttributeDef[]{ spaceAttr },
+                                    new ProcessorTemplateElem(),
+                                    ElemOtherwise.class /* class object */,
+                                                       false, false, 2, false);
+    XSLTElementDef xslChoose = new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "choose",
+                                 null /*alias */,
+                                 new XSLTElementDef[]{ xslWhen,
+                                                       xslOtherwise } /* elements */, 
+                                        new XSLTAttributeDef[]{ spaceAttr },
+                                 new ProcessorTemplateElem(),
+                                 ElemChoose.class /* class object */, true, false, true, 20, true);                                
+    XSLTElementDef xslAttribute = new XSLTElementDef(this,
+                                    Constants.S_XSLNAMESPACEURL, "attribute",
+                                    null /*alias */,
+                                    charTemplateElements /* elements */,  // %char-template;>
+                                    new XSLTAttributeDef[]{ nameAVTRequired,
+                                                            namespaceAVTOpt,
+                                                            spaceAttr }, 
+                                    new ProcessorTemplateElem(),
+                                    ElemAttribute.class /* class object */, 20, true);
+    XSLTElementDef xslCallTemplate =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "call-template",
+                         null /*alias */,
+                         new XSLTElementDef[]{ xslWithParam } /* elements */,
+                         new XSLTAttributeDef[]{ nameAttrRequired },
+                         new ProcessorTemplateElem(),
+                         ElemCallTemplate.class /* class object */, 20, true);
+    XSLTElementDef xslVariable = new XSLTElementDef(this,
+                                   Constants.S_XSLNAMESPACEURL, "variable",
+                                   null /*alias */,
+                                   templateElements /* elements */,  // %template;>
+                                   new XSLTAttributeDef[]{ nameAttrRequired,
+                                                           selectAttrOpt }, 
+                                  new ProcessorTemplateElem(),
+                                   ElemVariable.class /* class object */, 20, true);
+    XSLTElementDef xslParam = new XSLTElementDef(this,
+                                Constants.S_XSLNAMESPACEURL, "param",
+                                null /*alias */,
+                                templateElements /* elements */,  // %template;>
+                                new XSLTAttributeDef[]{ nameAttrRequired,
+                                                        selectAttrOpt }, 
+                                       new ProcessorTemplateElem(),
+                                ElemParam.class /* class object */, 19, true);
+    XSLTElementDef xslText =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "text",
+                         null /*alias */,
+                         new XSLTElementDef[]{ charData } /* elements */,
+                         new XSLTAttributeDef[]{ disableOutputEscapingAttr },
+                         new ProcessorText(),
+                         ElemText.class /* class object */, 20, true);
+    XSLTElementDef xslProcessingInstruction =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL,
+                         "processing-instruction", null /*alias */,
+                         charTemplateElements /* elements */,  // %char-template;>
+                         new XSLTAttributeDef[]{
+                                                  nameAVT_NCNAMERequired,
+                                                  spaceAttr }, 
+                                        new ProcessorTemplateElem(),
+                          ElemPI.class /* class object */, 20, true);
+    XSLTElementDef xslElement = new XSLTElementDef(this,
+                                  Constants.S_XSLNAMESPACEURL, "element",
+                                  null /*alias */,
+                                  templateElements /* elements */,  // %template;
+                                  new XSLTAttributeDef[]{ nameAVTRequired,
+                                                          namespaceAVTOpt,
+                                                          useAttributeSetsAttr,
+                                                          spaceAttr }, 
+                                               new ProcessorTemplateElem(),
+                                  ElemElement.class /* class object */, 20, true);
+    XSLTElementDef xslComment = new XSLTElementDef(this,
+                                  Constants.S_XSLNAMESPACEURL, "comment",
+                                  null /*alias */,
+                                  charTemplateElements /* elements */,  // %char-template;>
+                                  new XSLTAttributeDef[]{ spaceAttr },
+                                  new ProcessorTemplateElem(),
+                                  ElemComment.class /* class object */, 20, true);
+    XSLTElementDef xslCopy =
+      new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "copy",
+                         null /*alias */, templateElements /* elements */,  // %template;>
+                          new XSLTAttributeDef[]{
+                                                  spaceAttr,
+                                                  useAttributeSetsAttr }, 
+                                        new ProcessorTemplateElem(),
+                          ElemCopy.class /* class object */, 20, true);
+    XSLTElementDef xslMessage = new XSLTElementDef(this,
+                                  Constants.S_XSLNAMESPACEURL, "message",
+                                  null /*alias */,
+                                  templateElements /* elements */,  // %template;>
+                                  new XSLTAttributeDef[]{ terminateAttr },
+                                  new ProcessorTemplateElem(),
+                                  ElemMessage.class /* class object */, 20, true);
+    XSLTElementDef xslFallback = new XSLTElementDef(this,
+                                   Constants.S_XSLNAMESPACEURL, "fallback",
+                                   null /*alias */,
+                                   templateElements /* elements */,  // %template;>
+                                   new XSLTAttributeDef[]{ spaceAttr },
+                                   new ProcessorTemplateElem(),
+                                   ElemFallback.class /* class object */, 20, true);
+    //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 */);            
+    
+
+    int i = 0;
+
+    templateElements[i++] = charData;  // #PCDATA
+
+    // char-instructions
+    templateElements[i++] = xslApplyTemplates;
+    templateElements[i++] = xslCallTemplate;
+    templateElements[i++] = xslApplyImports;
+    templateElements[i++] = xslForEach;
+    templateElements[i++] = xslValueOf;
+    templateElements[i++] = xslCopyOf;
+    templateElements[i++] = xslNumber;
+    templateElements[i++] = xslChoose;
+    templateElements[i++] = xslIf;
+    templateElements[i++] = xslText;
+    templateElements[i++] = xslCopy;
+    templateElements[i++] = xslVariable;
+    templateElements[i++] = xslMessage;
+    templateElements[i++] = xslFallback;
+
+    // instructions
+    templateElements[i++] = xslProcessingInstruction;
+    templateElements[i++] = xslComment;
+    templateElements[i++] = xslElement;
+    templateElements[i++] = xslAttribute;
+    templateElements[i++] = resultElement;
+    templateElements[i++] = unknownElement;
+    templateElements[i++] = exsltFunction;
+    templateElements[i++] = exsltResult;
+
+    System.arraycopy(templateElements, 0, templateElementsAndParams, 0, i);
+    System.arraycopy(templateElements, 0, templateElementsAndSort, 0, i);
+    System.arraycopy(templateElements, 0, exsltFunctionElements, 0, i);
+    
+    templateElementsAndParams[i] = xslParam;
+    templateElementsAndSort[i] = xslSort;
+    exsltFunctionElements[i]   = xslParam;
+
+    i = 0;
+    charTemplateElements[i++] = charData;  // #PCDATA
+
+    // char-instructions
+    charTemplateElements[i++] = xslApplyTemplates;
+    charTemplateElements[i++] = xslCallTemplate;
+    charTemplateElements[i++] = xslApplyImports;
+    charTemplateElements[i++] = xslForEach;
+    charTemplateElements[i++] = xslValueOf;
+    charTemplateElements[i++] = xslCopyOf;
+    charTemplateElements[i++] = xslNumber;
+    charTemplateElements[i++] = xslChoose;
+    charTemplateElements[i++] = xslIf;
+    charTemplateElements[i++] = xslText;
+    charTemplateElements[i++] = xslCopy;
+    charTemplateElements[i++] = xslVariable;
+    charTemplateElements[i++] = xslMessage;
+    charTemplateElements[i++] = xslFallback;
+
+    XSLTElementDef importDef = new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "import",
+                                 null /*alias */, null /* elements */,
+                                 new XSLTAttributeDef[]{ hrefAttr },  // EMPTY
+                                 new ProcessorImport(),
+                                 null /* class object */,
+                                        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);
+    
+    XSLTAttributeDef[] scriptAttrs = new XSLTAttributeDef[]{
+    					    new XSLTAttributeDef(null, "lang", XSLTAttributeDef.T_NMTOKEN,
+                                                                 true, false,XSLTAttributeDef.WARNING),
+                                            new XSLTAttributeDef(null, "src", XSLTAttributeDef.T_URL, 
+                                            			 false, false,XSLTAttributeDef.WARNING)};
+
+    XSLTAttributeDef[] componentAttrs = new XSLTAttributeDef[]{ 
+                                            new XSLTAttributeDef(null, "prefix", XSLTAttributeDef.T_NMTOKEN, 
+                                            			 true, false,XSLTAttributeDef.WARNING),
+                                            new XSLTAttributeDef(null, "elements", XSLTAttributeDef.T_STRINGLIST, 
+                                            			 false, false,XSLTAttributeDef.WARNING),
+                                            new XSLTAttributeDef(null, "functions", XSLTAttributeDef.T_STRINGLIST, 
+                                            			 false, false,XSLTAttributeDef.WARNING) };
+
+    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_ERROR,
+                                                  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_ERROR,
+                                                   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 */,
+                                                        scriptAttrs, 
+                                                        new ProcessorLRE(),
+                                                        ElemExtensionScript.class /* class object */, 20, true) },  // EMPTY
+                                           componentAttrs, 
+                                           new ProcessorLRE(), ElemExtensionDecl.class /* class object */),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_BUILTIN_OLD_EXTENSIONS_URL,
+                                           "component",
+                                           null /*alias */,
+                                           new XSLTElementDef[]{
+                                                    new XSLTElementDef(
+                                                        this,
+                                                        Constants.S_BUILTIN_OLD_EXTENSIONS_URL,
+                                                        "script",
+                                                        null /*alias */,
+                                                    	new XSLTElementDef[]{ 
+                                                        charData } /* elements */,
+                                                        scriptAttrs, 
+                                                        new ProcessorLRE(),
+                                                        ElemExtensionScript.class /* class object */, 20, true) },  // EMPTY
+                                           componentAttrs, 
+                                           new ProcessorLRE(), ElemExtensionDecl.class /* class object */),
+                                  exsltFunction}/* exslt */;  //end of topevelElements
+    
+    XSLTAttributeDef excludeResultPrefixesAttr =
+      new XSLTAttributeDef(null, "exclude-result-prefixes",
+                           XSLTAttributeDef.T_PREFIXLIST, false,false,XSLTAttributeDef.WARNING);
+    XSLTAttributeDef extensionElementPrefixesAttr =
+      new XSLTAttributeDef(null, "extension-element-prefixes",
+                           XSLTAttributeDef.T_PREFIX_URLLIST, false,false,XSLTAttributeDef.WARNING);
+    XSLTAttributeDef idAttr = new XSLTAttributeDef(null, "id",
+                                XSLTAttributeDef.T_CDATA, false,false,XSLTAttributeDef.WARNING);
+    XSLTAttributeDef versionAttrRequired = new XSLTAttributeDef(null,
+                                             "version",
+                                             XSLTAttributeDef.T_NMTOKEN,
+                                             true,false,XSLTAttributeDef.WARNING);
+    XSLTElementDef stylesheetElemDef = new XSLTElementDef(this,
+                                         Constants.S_XSLNAMESPACEURL,
+                                         "stylesheet", "transform",
+                                         topLevelElements,
+                                         new XSLTAttributeDef[]{
+                                           extensionElementPrefixesAttr,
+                                           excludeResultPrefixesAttr,
+                                           idAttr,
+                                           versionAttrRequired,
+                                           spaceAttr }, new ProcessorStylesheetElement(),  /* ContentHandler */
+                                         null  /* class object */,
+                                         true, -1, false);
+
+    importDef.setElements(new XSLTElementDef[]{ stylesheetElemDef,
+                                                resultElement,
+                                                unknownElement });
+    includeDef.setElements(new XSLTElementDef[]{ stylesheetElemDef,
+                                                 resultElement,
+                                                 unknownElement });
+    build(null, null, null, new XSLTElementDef[]{ stylesheetElemDef,
+                                                  whiteSpaceOnly,
+                                                  resultElement,
+                                                  unknownElement }, null,
+                                                                    new ProcessorStylesheetDoc(),  /* ContentHandler */
+                                                                    null  /* class object */
+                                                                      );
+  }
+
+  /**
+   * A hashtable of all available built-in elements for use by the element-available
+   * function.
+   * TODO:  When we convert to Java2, this should be a Set.
+   */
+  private HashMap m_availElems = new HashMap();
+  
+  /**
+   * Get the table of available elements.
+   * 
+   * @return table of available elements, keyed by qualified names, and with 
+   * values of the same qualified names.
+   */
+  public HashMap getElemsAvailable() 
+  {
+    return m_availElems;
+  }
+
+  /**
+   * Adds a new element name to the Hashtable of available elements.
+   * @param elemName The name of the element to add to the Hashtable of available elements.
+   */
+  void addAvailableElement(QName elemName)
+  {
+    m_availElems.put(elemName, elemName);
+  }
+
+  /**
+   * Determines whether the passed element name is present in the list of available elements.
+   * @param elemName The name of the element to look up.
+   *
+   * @return true if an element corresponding to elemName is available.
+   */
+  public boolean elementAvailable(QName elemName)
+  {
+    return m_availElems.containsKey(elemName);
+  }
+}
+
diff --git a/src/main/java/org/apache/xalan/processor/package.html b/src/main/java/org/apache/xalan/processor/package.html
new file mode 100644
index 0000000..6d1dd4e
--- /dev/null
+++ b/src/main/java/org/apache/xalan/processor/package.html
@@ -0,0 +1,41 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468640 2006-10-28 06:53:53Z minchau $ -->
+<html>
+  <title>Xalan Processor Package.</title>
+  <body>
+    <p>Parses an XSLT stylesheet document (which may include and import other stylesheet documents) and produces a StylesheetRoot
+    (a TRaX Templates object).</p>
+    
+    <p>StylesheetProcessor implements the TRaX {@link javax.xml.transform.TransformerFactory} interface,
+    as well as the {@link javax.xml.transform.sax.SAXTransformerFactory} interface. 
+    It registers the {@link org.apache.xalan.processor.StylesheetHandler} object 
+    (a TrAX {@link javax.xml.transform.sax.TemplatesHandler} implementation) 
+    as the SAX ContentHandler for an XMLReader, and uses the XMLReader to parse 
+    the stylesheet document.</p>
+    <p>Before parsing the XSLT input, StylesheetHandler assembles an {@link org.apache.xalan.processor.XSLTSchema}, 
+    which uses {@link org.apache.xalan.processor.XSLTElementDef}
+    and {@link org.apache.xalan.processor.XSLTAttributeDef} objects to 
+    recursively define the elements and attributes that an XSLT stylesheet may 
+    contain. The StylesheetHandler then passes on each parse event to the 
+    {@link org.apache.xalan.processor.XSLTElementProcessor} which the 
+    XSLTElementDef assigned to the element associated with that event.</p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xalan/res/XSLMessages.java b/src/main/java/org/apache/xalan/res/XSLMessages.java
new file mode 100644
index 0000000..cbbfd88
--- /dev/null
+++ b/src/main/java/org/apache/xalan/res/XSLMessages.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLMessages.java 468641 2006-10-28 06:54:42Z minchau $
+ */
+package org.apache.xalan.res;
+
+import java.util.ListResourceBundle;
+
+import org.apache.xpath.res.XPATHMessages;
+
+/**
+ * Sets things up for issuing error messages.  This class is misnamed, and
+ * should be called XalanMessages, or some such.
+ * @xsl.usage internal
+ */
+public class XSLMessages extends XPATHMessages
+{
+
+  /** The language specific resource object for Xalan messages.  */
+  private static ListResourceBundle XSLTBundle = new XSLTErrorResources(); // android-changed
+
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param msgKey    The key for the message text.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted message string.
+   */
+  public static final String createMessage(String msgKey, Object args[])  //throws Exception
+  {
+      // BEGIN android-changed
+      //     don't localize resources
+      return createMsg(XSLTBundle, msgKey, args);
+      // END android-changed
+  }
+  
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param msgKey    The key for the message text.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted warning string.
+   */
+  public static final String createWarning(String msgKey, Object args[])  //throws Exception
+  {
+      // BEGIN android-changed
+      //     don't localize exception messages
+      return createMsg(XSLTBundle, msgKey, args);
+      // END android-changed
+  }
+}
diff --git a/src/main/java/org/apache/xalan/res/XSLTErrorResources.java b/src/main/java/org/apache/xalan/res/XSLTErrorResources.java
new file mode 100644
index 0000000..8310540
--- /dev/null
+++ b/src/main/java/org/apache/xalan/res/XSLTErrorResources.java
@@ -0,0 +1,1511 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTErrorResources.java 468641 2006-10-28 06:54:42Z minchau $
+ */
+package org.apache.xalan.res;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Set up error messages.
+ * We build a two dimensional array of message keys and
+ * message strings. In order to add a new message here,
+ * you need to first add a String constant. And 
+ *  you need to enter key , value pair as part of contents
+ * Array. You also need to update MAX_CODE for error strings
+ * and MAX_WARNING for warnings ( Needed for only information
+ * purpose )
+ */
+public class XSLTErrorResources extends ListResourceBundle
+{
+
+/*
+ * This file contains error and warning messages related to Xalan Error
+ * Handling.
+ *
+ *  General notes to translators:
+ *
+ *  1) Xalan (or more properly, Xalan-interpretive) and XSLTC are names of
+ *     components.
+ *     XSLT is an acronym for "XML Stylesheet Language: Transformations".
+ *     XSLTC is an acronym for XSLT Compiler.
+ *
+ *  2) A stylesheet is a description of how to transform an input XML document
+ *     into a resultant XML document (or HTML document or text).  The
+ *     stylesheet itself is described in the form of an XML document.
+ *
+ *  3) A template is a component of a stylesheet that is used to match a
+ *     particular portion of an input document and specifies the form of the
+ *     corresponding portion of the output document.
+ *
+ *  4) An element is a mark-up tag in an XML document; an attribute is a
+ *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+ *     "elem" is an element name, "attr" and "attr2" are attribute names with
+ *     the values "val" and "val2", respectively.
+ *
+ *  5) A namespace declaration is a special attribute that is used to associate
+ *     a prefix with a URI (the namespace).  The meanings of element names and
+ *     attribute names that use that prefix are defined with respect to that
+ *     namespace.
+ *
+ *  6) "Translet" is an invented term that describes the class file that
+ *     results from compiling an XML stylesheet into a Java class.
+ *
+ *  7) XPath is a specification that describes a notation for identifying
+ *     nodes in a tree-structured representation of an XML document.  An
+ *     instance of that notation is referred to as an XPath expression.
+ *
+ */
+
+  /* 
+   * Static variables
+   */
+  public static final String ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX = 
+	"ER_INVALID_SET_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX"; 
+	
+  public static final String ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX_FOR_DEFAULT =
+	"ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX_FOR_DEFAULT";
+   
+  public static final String ER_NO_CURLYBRACE = "ER_NO_CURLYBRACE";
+  public static final String ER_FUNCTION_NOT_SUPPORTED = "ER_FUNCTION_NOT_SUPPORTED";
+  public static final String ER_ILLEGAL_ATTRIBUTE = "ER_ILLEGAL_ATTRIBUTE";
+  public static final String ER_NULL_SOURCENODE_APPLYIMPORTS = "ER_NULL_SOURCENODE_APPLYIMPORTS";
+  public static final String ER_CANNOT_ADD = "ER_CANNOT_ADD"; 
+  public static final String ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES="ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES";
+  public static final String ER_NO_NAME_ATTRIB = "ER_NO_NAME_ATTRIB";
+  public static final String ER_TEMPLATE_NOT_FOUND = "ER_TEMPLATE_NOT_FOUND";
+  public static final String ER_CANT_RESOLVE_NAME_AVT = "ER_CANT_RESOLVE_NAME_AVT";
+  public static final String ER_REQUIRES_ATTRIB = "ER_REQUIRES_ATTRIB";
+  public static final String ER_MUST_HAVE_TEST_ATTRIB = "ER_MUST_HAVE_TEST_ATTRIB";
+  public static final String ER_BAD_VAL_ON_LEVEL_ATTRIB =
+	 "ER_BAD_VAL_ON_LEVEL_ATTRIB";
+  public static final String ER_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML =
+	 "ER_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML";
+  public static final String ER_PROCESSINGINSTRUCTION_NOTVALID_NCNAME = 
+	 "ER_PROCESSINGINSTRUCTION_NOTVALID_NCNAME";
+  public static final String ER_NEED_MATCH_ATTRIB = "ER_NEED_MATCH_ATTRIB";
+  public static final String ER_NEED_NAME_OR_MATCH_ATTRIB = 
+	 "ER_NEED_NAME_OR_MATCH_ATTRIB";
+  public static final String ER_CANT_RESOLVE_NSPREFIX =
+	 "ER_CANT_RESOLVE_NSPREFIX";
+  public static final String ER_ILLEGAL_VALUE = "ER_ILLEGAL_VALUE";
+  public static final String ER_NO_OWNERDOC = "ER_NO_OWNERDOC";
+  public static final String ER_ELEMTEMPLATEELEM_ERR ="ER_ELEMTEMPLATEELEM_ERR";
+  public static final String ER_NULL_CHILD = "ER_NULL_CHILD";
+  public static final String ER_NEED_SELECT_ATTRIB = "ER_NEED_SELECT_ATTRIB";
+  public static final String ER_NEED_TEST_ATTRIB = "ER_NEED_TEST_ATTRIB";
+  public static final String ER_NEED_NAME_ATTRIB = "ER_NEED_NAME_ATTRIB";
+  public static final String ER_NO_CONTEXT_OWNERDOC = "ER_NO_CONTEXT_OWNERDOC";
+  public static final String ER_COULD_NOT_CREATE_XML_PROC_LIAISON = 
+	 "ER_COULD_NOT_CREATE_XML_PROC_LIAISON";
+  public static final String ER_PROCESS_NOT_SUCCESSFUL = 
+	 "ER_PROCESS_NOT_SUCCESSFUL";
+  public static final String ER_NOT_SUCCESSFUL = "ER_NOT_SUCCESSFUL";
+  public static final String ER_ENCODING_NOT_SUPPORTED = 
+	 "ER_ENCODING_NOT_SUPPORTED";
+  public static final String ER_COULD_NOT_CREATE_TRACELISTENER = 
+	 "ER_COULD_NOT_CREATE_TRACELISTENER";
+  public static final String ER_KEY_REQUIRES_NAME_ATTRIB = 
+	 "ER_KEY_REQUIRES_NAME_ATTRIB";
+  public static final String ER_KEY_REQUIRES_MATCH_ATTRIB = 
+	 "ER_KEY_REQUIRES_MATCH_ATTRIB";
+  public static final String ER_KEY_REQUIRES_USE_ATTRIB = 
+	 "ER_KEY_REQUIRES_USE_ATTRIB";
+  public static final String ER_REQUIRES_ELEMENTS_ATTRIB = 
+	 "ER_REQUIRES_ELEMENTS_ATTRIB";
+  public static final String ER_MISSING_PREFIX_ATTRIB = 
+	 "ER_MISSING_PREFIX_ATTRIB";
+  public static final String ER_BAD_STYLESHEET_URL = "ER_BAD_STYLESHEET_URL";
+  public static final String ER_FILE_NOT_FOUND = "ER_FILE_NOT_FOUND";
+  public static final String ER_IOEXCEPTION = "ER_IOEXCEPTION";
+  public static final String ER_NO_HREF_ATTRIB = "ER_NO_HREF_ATTRIB";
+  public static final String ER_STYLESHEET_INCLUDES_ITSELF = 
+	 "ER_STYLESHEET_INCLUDES_ITSELF";
+  public static final String ER_PROCESSINCLUDE_ERROR ="ER_PROCESSINCLUDE_ERROR";
+  public static final String ER_MISSING_LANG_ATTRIB = "ER_MISSING_LANG_ATTRIB";
+  public static final String ER_MISSING_CONTAINER_ELEMENT_COMPONENT = 
+	 "ER_MISSING_CONTAINER_ELEMENT_COMPONENT";
+  public static final String ER_CAN_ONLY_OUTPUT_TO_ELEMENT = 
+	 "ER_CAN_ONLY_OUTPUT_TO_ELEMENT";
+  public static final String ER_PROCESS_ERROR = "ER_PROCESS_ERROR";
+  public static final String ER_UNIMPLNODE_ERROR = "ER_UNIMPLNODE_ERROR";
+  public static final String ER_NO_SELECT_EXPRESSION ="ER_NO_SELECT_EXPRESSION";
+  public static final String ER_CANNOT_SERIALIZE_XSLPROCESSOR = 
+	 "ER_CANNOT_SERIALIZE_XSLPROCESSOR";
+  public static final String ER_NO_INPUT_STYLESHEET = "ER_NO_INPUT_STYLESHEET";
+  public static final String ER_FAILED_PROCESS_STYLESHEET = 
+	 "ER_FAILED_PROCESS_STYLESHEET";
+  public static final String ER_COULDNT_PARSE_DOC = "ER_COULDNT_PARSE_DOC";
+  public static final String ER_COULDNT_FIND_FRAGMENT = 
+	 "ER_COULDNT_FIND_FRAGMENT";
+  public static final String ER_NODE_NOT_ELEMENT = "ER_NODE_NOT_ELEMENT";
+  public static final String ER_FOREACH_NEED_MATCH_OR_NAME_ATTRIB = 
+	 "ER_FOREACH_NEED_MATCH_OR_NAME_ATTRIB";
+  public static final String ER_TEMPLATES_NEED_MATCH_OR_NAME_ATTRIB = 
+	 "ER_TEMPLATES_NEED_MATCH_OR_NAME_ATTRIB";
+  public static final String ER_NO_CLONE_OF_DOCUMENT_FRAG = 
+	 "ER_NO_CLONE_OF_DOCUMENT_FRAG";
+  public static final String ER_CANT_CREATE_ITEM = "ER_CANT_CREATE_ITEM";
+  public static final String ER_XMLSPACE_ILLEGAL_VALUE = 
+	 "ER_XMLSPACE_ILLEGAL_VALUE";
+  public static final String ER_NO_XSLKEY_DECLARATION = 
+	 "ER_NO_XSLKEY_DECLARATION";
+  public static final String ER_CANT_CREATE_URL = "ER_CANT_CREATE_URL";
+  public static final String ER_XSLFUNCTIONS_UNSUPPORTED = 
+	 "ER_XSLFUNCTIONS_UNSUPPORTED";
+  public static final String ER_PROCESSOR_ERROR = "ER_PROCESSOR_ERROR";
+  public static final String ER_NOT_ALLOWED_INSIDE_STYLESHEET = 
+	 "ER_NOT_ALLOWED_INSIDE_STYLESHEET";
+  public static final String ER_RESULTNS_NOT_SUPPORTED = 
+	 "ER_RESULTNS_NOT_SUPPORTED";
+  public static final String ER_DEFAULTSPACE_NOT_SUPPORTED = 
+	 "ER_DEFAULTSPACE_NOT_SUPPORTED";
+  public static final String ER_INDENTRESULT_NOT_SUPPORTED = 
+	 "ER_INDENTRESULT_NOT_SUPPORTED";
+  public static final String ER_ILLEGAL_ATTRIB = "ER_ILLEGAL_ATTRIB";
+  public static final String ER_UNKNOWN_XSL_ELEM = "ER_UNKNOWN_XSL_ELEM";
+  public static final String ER_BAD_XSLSORT_USE = "ER_BAD_XSLSORT_USE";
+  public static final String ER_MISPLACED_XSLWHEN = "ER_MISPLACED_XSLWHEN";
+  public static final String ER_XSLWHEN_NOT_PARENTED_BY_XSLCHOOSE = 
+	 "ER_XSLWHEN_NOT_PARENTED_BY_XSLCHOOSE";
+  public static final String ER_MISPLACED_XSLOTHERWISE = 
+	 "ER_MISPLACED_XSLOTHERWISE";
+  public static final String ER_XSLOTHERWISE_NOT_PARENTED_BY_XSLCHOOSE = 
+	 "ER_XSLOTHERWISE_NOT_PARENTED_BY_XSLCHOOSE";
+  public static final String ER_NOT_ALLOWED_INSIDE_TEMPLATE = 
+	 "ER_NOT_ALLOWED_INSIDE_TEMPLATE";
+  public static final String ER_UNKNOWN_EXT_NS_PREFIX = 
+	 "ER_UNKNOWN_EXT_NS_PREFIX";
+  public static final String ER_IMPORTS_AS_FIRST_ELEM = 
+	 "ER_IMPORTS_AS_FIRST_ELEM";
+  public static final String ER_IMPORTING_ITSELF = "ER_IMPORTING_ITSELF";
+  public static final String ER_XMLSPACE_ILLEGAL_VAL ="ER_XMLSPACE_ILLEGAL_VAL";
+  public static final String ER_PROCESSSTYLESHEET_NOT_SUCCESSFUL = 
+	 "ER_PROCESSSTYLESHEET_NOT_SUCCESSFUL";
+  public static final String ER_SAX_EXCEPTION = "ER_SAX_EXCEPTION";
+  public static final String ER_XSLT_ERROR = "ER_XSLT_ERROR";
+  public static final String ER_CURRENCY_SIGN_ILLEGAL=
+	 "ER_CURRENCY_SIGN_ILLEGAL";
+  public static final String ER_DOCUMENT_FUNCTION_INVALID_IN_STYLESHEET_DOM = 
+	 "ER_DOCUMENT_FUNCTION_INVALID_IN_STYLESHEET_DOM";
+  public static final String ER_CANT_RESOLVE_PREFIX_OF_NON_PREFIX_RESOLVER = 
+	 "ER_CANT_RESOLVE_PREFIX_OF_NON_PREFIX_RESOLVER";
+  public static final String ER_REDIRECT_COULDNT_GET_FILENAME = 
+	 "ER_REDIRECT_COULDNT_GET_FILENAME";
+  public static final String ER_CANNOT_BUILD_FORMATTERLISTENER_IN_REDIRECT = 
+	 "ER_CANNOT_BUILD_FORMATTERLISTENER_IN_REDIRECT";
+  public static final String ER_INVALID_PREFIX_IN_EXCLUDERESULTPREFIX = 
+	 "ER_INVALID_PREFIX_IN_EXCLUDERESULTPREFIX";
+  public static final String ER_MISSING_NS_URI = "ER_MISSING_NS_URI";
+  public static final String ER_MISSING_ARG_FOR_OPTION = 
+	 "ER_MISSING_ARG_FOR_OPTION";
+  public static final String ER_INVALID_OPTION = "ER_INVALID_OPTION";
+  public static final String ER_MALFORMED_FORMAT_STRING = 
+	 "ER_MALFORMED_FORMAT_STRING";
+  public static final String ER_STYLESHEET_REQUIRES_VERSION_ATTRIB = 
+	 "ER_STYLESHEET_REQUIRES_VERSION_ATTRIB";
+  public static final String ER_ILLEGAL_ATTRIBUTE_VALUE = 
+	 "ER_ILLEGAL_ATTRIBUTE_VALUE";
+  public static final String ER_CHOOSE_REQUIRES_WHEN ="ER_CHOOSE_REQUIRES_WHEN";
+  public static final String ER_NO_APPLY_IMPORT_IN_FOR_EACH = 
+	 "ER_NO_APPLY_IMPORT_IN_FOR_EACH";
+  public static final String ER_CANT_USE_DTM_FOR_OUTPUT = 
+	 "ER_CANT_USE_DTM_FOR_OUTPUT";
+  public static final String ER_CANT_USE_DTM_FOR_INPUT = 
+	 "ER_CANT_USE_DTM_FOR_INPUT";
+  public static final String ER_CALL_TO_EXT_FAILED = "ER_CALL_TO_EXT_FAILED";
+  public static final String ER_PREFIX_MUST_RESOLVE = "ER_PREFIX_MUST_RESOLVE";
+  public static final String ER_INVALID_UTF16_SURROGATE = 
+	 "ER_INVALID_UTF16_SURROGATE";
+  public static final String ER_XSLATTRSET_USED_ITSELF = 
+	 "ER_XSLATTRSET_USED_ITSELF";
+  public static final String ER_CANNOT_MIX_XERCESDOM ="ER_CANNOT_MIX_XERCESDOM";
+  public static final String ER_TOO_MANY_LISTENERS = "ER_TOO_MANY_LISTENERS";
+  public static final String ER_IN_ELEMTEMPLATEELEM_READOBJECT = 
+	 "ER_IN_ELEMTEMPLATEELEM_READOBJECT";
+  public static final String ER_DUPLICATE_NAMED_TEMPLATE = 
+	 "ER_DUPLICATE_NAMED_TEMPLATE";
+  public static final String ER_INVALID_KEY_CALL = "ER_INVALID_KEY_CALL";
+  public static final String ER_REFERENCING_ITSELF = "ER_REFERENCING_ITSELF";
+  public static final String ER_ILLEGAL_DOMSOURCE_INPUT = 
+	 "ER_ILLEGAL_DOMSOURCE_INPUT";
+  public static final String ER_CLASS_NOT_FOUND_FOR_OPTION = 
+	 "ER_CLASS_NOT_FOUND_FOR_OPTION";
+  public static final String ER_REQUIRED_ELEM_NOT_FOUND = 
+	 "ER_REQUIRED_ELEM_NOT_FOUND";
+  public static final String ER_INPUT_CANNOT_BE_NULL ="ER_INPUT_CANNOT_BE_NULL";
+  public static final String ER_URI_CANNOT_BE_NULL = "ER_URI_CANNOT_BE_NULL";
+  public static final String ER_FILE_CANNOT_BE_NULL = "ER_FILE_CANNOT_BE_NULL";
+  public static final String ER_SOURCE_CANNOT_BE_NULL = 
+	 "ER_SOURCE_CANNOT_BE_NULL";
+  public static final String ER_CANNOT_INIT_BSFMGR = "ER_CANNOT_INIT_BSFMGR";
+  public static final String ER_CANNOT_CMPL_EXTENSN = "ER_CANNOT_CMPL_EXTENSN";
+  public static final String ER_CANNOT_CREATE_EXTENSN = 
+	 "ER_CANNOT_CREATE_EXTENSN";
+  public static final String ER_INSTANCE_MTHD_CALL_REQUIRES = 
+	 "ER_INSTANCE_MTHD_CALL_REQUIRES";
+  public static final String ER_INVALID_ELEMENT_NAME ="ER_INVALID_ELEMENT_NAME";
+  public static final String ER_ELEMENT_NAME_METHOD_STATIC = 
+	 "ER_ELEMENT_NAME_METHOD_STATIC";
+  public static final String ER_EXTENSION_FUNC_UNKNOWN = 
+	 "ER_EXTENSION_FUNC_UNKNOWN";
+  public static final String ER_MORE_MATCH_CONSTRUCTOR = 
+	 "ER_MORE_MATCH_CONSTRUCTOR";
+  public static final String ER_MORE_MATCH_METHOD = "ER_MORE_MATCH_METHOD";
+  public static final String ER_MORE_MATCH_ELEMENT = "ER_MORE_MATCH_ELEMENT";
+  public static final String ER_INVALID_CONTEXT_PASSED = 
+	 "ER_INVALID_CONTEXT_PASSED";
+  public static final String ER_POOL_EXISTS = "ER_POOL_EXISTS";
+  public static final String ER_NO_DRIVER_NAME = "ER_NO_DRIVER_NAME";
+  public static final String ER_NO_URL = "ER_NO_URL";
+  public static final String ER_POOL_SIZE_LESSTHAN_ONE = 
+	 "ER_POOL_SIZE_LESSTHAN_ONE";
+  public static final String ER_INVALID_DRIVER = "ER_INVALID_DRIVER";
+  public static final String ER_NO_STYLESHEETROOT = "ER_NO_STYLESHEETROOT";
+  public static final String ER_ILLEGAL_XMLSPACE_VALUE = 
+	 "ER_ILLEGAL_XMLSPACE_VALUE";
+  public static final String ER_PROCESSFROMNODE_FAILED = 
+	 "ER_PROCESSFROMNODE_FAILED";
+  public static final String ER_RESOURCE_COULD_NOT_LOAD = 
+	 "ER_RESOURCE_COULD_NOT_LOAD";
+  public static final String ER_BUFFER_SIZE_LESSTHAN_ZERO = 
+	 "ER_BUFFER_SIZE_LESSTHAN_ZERO";
+  public static final String ER_UNKNOWN_ERROR_CALLING_EXTENSION = 
+	 "ER_UNKNOWN_ERROR_CALLING_EXTENSION";
+  public static final String ER_NO_NAMESPACE_DECL = "ER_NO_NAMESPACE_DECL";
+  public static final String ER_ELEM_CONTENT_NOT_ALLOWED = 
+	 "ER_ELEM_CONTENT_NOT_ALLOWED";
+  public static final String ER_STYLESHEET_DIRECTED_TERMINATION = 
+	 "ER_STYLESHEET_DIRECTED_TERMINATION";
+  public static final String ER_ONE_OR_TWO = "ER_ONE_OR_TWO";
+  public static final String ER_TWO_OR_THREE = "ER_TWO_OR_THREE";
+  public static final String ER_COULD_NOT_LOAD_RESOURCE = 
+	 "ER_COULD_NOT_LOAD_RESOURCE";
+  public static final String ER_CANNOT_INIT_DEFAULT_TEMPLATES = 
+	 "ER_CANNOT_INIT_DEFAULT_TEMPLATES";
+  public static final String ER_RESULT_NULL = "ER_RESULT_NULL";
+  public static final String ER_RESULT_COULD_NOT_BE_SET = 
+	 "ER_RESULT_COULD_NOT_BE_SET";
+  public static final String ER_NO_OUTPUT_SPECIFIED = "ER_NO_OUTPUT_SPECIFIED";
+  public static final String ER_CANNOT_TRANSFORM_TO_RESULT_TYPE = 
+	 "ER_CANNOT_TRANSFORM_TO_RESULT_TYPE";
+  public static final String ER_CANNOT_TRANSFORM_SOURCE_TYPE = 
+	 "ER_CANNOT_TRANSFORM_SOURCE_TYPE";
+  public static final String ER_NULL_CONTENT_HANDLER ="ER_NULL_CONTENT_HANDLER";
+  public static final String ER_NULL_ERROR_HANDLER = "ER_NULL_ERROR_HANDLER";
+  public static final String ER_CANNOT_CALL_PARSE = "ER_CANNOT_CALL_PARSE";
+  public static final String ER_NO_PARENT_FOR_FILTER ="ER_NO_PARENT_FOR_FILTER";
+  public static final String ER_NO_STYLESHEET_IN_MEDIA = 
+	 "ER_NO_STYLESHEET_IN_MEDIA";
+  public static final String ER_NO_STYLESHEET_PI = "ER_NO_STYLESHEET_PI";
+  public static final String ER_NOT_SUPPORTED = "ER_NOT_SUPPORTED";
+  public static final String ER_PROPERTY_VALUE_BOOLEAN = 
+	 "ER_PROPERTY_VALUE_BOOLEAN";
+  public static final String ER_COULD_NOT_FIND_EXTERN_SCRIPT = 
+	 "ER_COULD_NOT_FIND_EXTERN_SCRIPT";
+  public static final String ER_RESOURCE_COULD_NOT_FIND = 
+	 "ER_RESOURCE_COULD_NOT_FIND";
+  public static final String ER_OUTPUT_PROPERTY_NOT_RECOGNIZED = 
+	 "ER_OUTPUT_PROPERTY_NOT_RECOGNIZED";
+  public static final String ER_FAILED_CREATING_ELEMLITRSLT = 
+	 "ER_FAILED_CREATING_ELEMLITRSLT";
+  public static final String ER_VALUE_SHOULD_BE_NUMBER = 
+	 "ER_VALUE_SHOULD_BE_NUMBER";
+  public static final String ER_VALUE_SHOULD_EQUAL = "ER_VALUE_SHOULD_EQUAL";
+  public static final String ER_FAILED_CALLING_METHOD = 
+	 "ER_FAILED_CALLING_METHOD";
+  public static final String ER_FAILED_CREATING_ELEMTMPL = 
+	 "ER_FAILED_CREATING_ELEMTMPL";
+  public static final String ER_CHARS_NOT_ALLOWED = "ER_CHARS_NOT_ALLOWED";
+  public static final String ER_ATTR_NOT_ALLOWED = "ER_ATTR_NOT_ALLOWED";
+  public static final String ER_BAD_VALUE = "ER_BAD_VALUE";
+  public static final String ER_ATTRIB_VALUE_NOT_FOUND = 
+	 "ER_ATTRIB_VALUE_NOT_FOUND";
+  public static final String ER_ATTRIB_VALUE_NOT_RECOGNIZED = 
+	 "ER_ATTRIB_VALUE_NOT_RECOGNIZED";
+  public static final String ER_NULL_URI_NAMESPACE = "ER_NULL_URI_NAMESPACE";
+  public static final String ER_NUMBER_TOO_BIG = "ER_NUMBER_TOO_BIG";
+  public static final String  ER_CANNOT_FIND_SAX1_DRIVER = 
+	 "ER_CANNOT_FIND_SAX1_DRIVER";
+  public static final String  ER_SAX1_DRIVER_NOT_LOADED = 
+	 "ER_SAX1_DRIVER_NOT_LOADED";
+  public static final String  ER_SAX1_DRIVER_NOT_INSTANTIATED = 
+	 "ER_SAX1_DRIVER_NOT_INSTANTIATED" ;
+  public static final String ER_SAX1_DRIVER_NOT_IMPLEMENT_PARSER = 
+	 "ER_SAX1_DRIVER_NOT_IMPLEMENT_PARSER";
+  public static final String  ER_PARSER_PROPERTY_NOT_SPECIFIED = 
+	 "ER_PARSER_PROPERTY_NOT_SPECIFIED";
+  public static final String  ER_PARSER_ARG_CANNOT_BE_NULL = 
+	 "ER_PARSER_ARG_CANNOT_BE_NULL" ;
+  public static final String  ER_FEATURE = "ER_FEATURE";
+  public static final String ER_PROPERTY = "ER_PROPERTY" ;
+  public static final String ER_NULL_ENTITY_RESOLVER ="ER_NULL_ENTITY_RESOLVER";
+  public static final String  ER_NULL_DTD_HANDLER = "ER_NULL_DTD_HANDLER" ;
+  public static final String ER_NO_DRIVER_NAME_SPECIFIED = 
+	 "ER_NO_DRIVER_NAME_SPECIFIED";
+  public static final String ER_NO_URL_SPECIFIED = "ER_NO_URL_SPECIFIED";
+  public static final String ER_POOLSIZE_LESS_THAN_ONE = 
+	 "ER_POOLSIZE_LESS_THAN_ONE";
+  public static final String ER_INVALID_DRIVER_NAME = "ER_INVALID_DRIVER_NAME";
+  public static final String ER_ERRORLISTENER = "ER_ERRORLISTENER";
+  public static final String ER_ASSERT_NO_TEMPLATE_PARENT = 
+	 "ER_ASSERT_NO_TEMPLATE_PARENT";
+  public static final String ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR = 
+	 "ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR";
+  public static final String ER_NOT_ALLOWED_IN_POSITION = 
+	 "ER_NOT_ALLOWED_IN_POSITION";
+  public static final String ER_NONWHITESPACE_NOT_ALLOWED_IN_POSITION = 
+	 "ER_NONWHITESPACE_NOT_ALLOWED_IN_POSITION";
+  public static final String ER_NAMESPACE_CONTEXT_NULL_NAMESPACE =
+  	 "ER_NAMESPACE_CONTEXT_NULL_NAMESPACE";
+  public static final String ER_NAMESPACE_CONTEXT_NULL_PREFIX =
+ 	 "ER_NAMESPACE_CONTEXT_NULL_PREFIX";
+  public static final String ER_XPATH_RESOLVER_NULL_QNAME =
+	 "ER_XPATH_RESOLVER_NULL_QNAME";
+  public static final String ER_XPATH_RESOLVER_NEGATIVE_ARITY =
+	 "ER_XPATH_RESOLVER_NEGATIVE_ARITY";
+  public static final String INVALID_TCHAR = "INVALID_TCHAR";
+  public static final String INVALID_QNAME = "INVALID_QNAME";
+  public static final String INVALID_ENUM = "INVALID_ENUM";
+  public static final String INVALID_NMTOKEN = "INVALID_NMTOKEN";
+  public static final String INVALID_NCNAME = "INVALID_NCNAME";
+  public static final String INVALID_BOOLEAN = "INVALID_BOOLEAN";
+  public static final String INVALID_NUMBER = "INVALID_NUMBER";
+  public static final String ER_ARG_LITERAL = "ER_ARG_LITERAL";
+  public static final String ER_DUPLICATE_GLOBAL_VAR ="ER_DUPLICATE_GLOBAL_VAR";
+  public static final String ER_DUPLICATE_VAR = "ER_DUPLICATE_VAR";
+  public static final String ER_TEMPLATE_NAME_MATCH = "ER_TEMPLATE_NAME_MATCH";
+  public static final String ER_INVALID_PREFIX = "ER_INVALID_PREFIX";
+  public static final String ER_NO_ATTRIB_SET = "ER_NO_ATTRIB_SET";
+  public static final String ER_FUNCTION_NOT_FOUND = 
+	 "ER_FUNCTION_NOT_FOUND"; 
+  public static final String ER_CANT_HAVE_CONTENT_AND_SELECT = 
+     "ER_CANT_HAVE_CONTENT_AND_SELECT";
+  public static final String ER_INVALID_SET_PARAM_VALUE = "ER_INVALID_SET_PARAM_VALUE";    
+  public static final String ER_SET_FEATURE_NULL_NAME =
+  	"ER_SET_FEATURE_NULL_NAME";
+  public static final String ER_GET_FEATURE_NULL_NAME =
+  	"ER_GET_FEATURE_NULL_NAME";
+  public static final String ER_UNSUPPORTED_FEATURE =
+  	"ER_UNSUPPORTED_FEATURE";
+  public static final String ER_EXTENSION_ELEMENT_NOT_ALLOWED_IN_SECURE_PROCESSING =
+  	"ER_EXTENSION_ELEMENT_NOT_ALLOWED_IN_SECURE_PROCESSING";
+     
+  public static final String WG_FOUND_CURLYBRACE = "WG_FOUND_CURLYBRACE";
+  public static final String WG_COUNT_ATTRIB_MATCHES_NO_ANCESTOR = 
+	 "WG_COUNT_ATTRIB_MATCHES_NO_ANCESTOR";
+  public static final String WG_EXPR_ATTRIB_CHANGED_TO_SELECT = 
+	 "WG_EXPR_ATTRIB_CHANGED_TO_SELECT";
+  public static final String WG_NO_LOCALE_IN_FORMATNUMBER = 
+	 "WG_NO_LOCALE_IN_FORMATNUMBER";
+  public static final String WG_LOCALE_NOT_FOUND = "WG_LOCALE_NOT_FOUND";
+  public static final String WG_CANNOT_MAKE_URL_FROM ="WG_CANNOT_MAKE_URL_FROM";
+  public static final String WG_CANNOT_LOAD_REQUESTED_DOC = 
+	 "WG_CANNOT_LOAD_REQUESTED_DOC";
+  public static final String WG_CANNOT_FIND_COLLATOR ="WG_CANNOT_FIND_COLLATOR";
+  public static final String WG_FUNCTIONS_SHOULD_USE_URL = 
+	 "WG_FUNCTIONS_SHOULD_USE_URL";
+  public static final String WG_ENCODING_NOT_SUPPORTED_USING_UTF8 = 
+	 "WG_ENCODING_NOT_SUPPORTED_USING_UTF8";
+  public static final String WG_ENCODING_NOT_SUPPORTED_USING_JAVA = 
+	 "WG_ENCODING_NOT_SUPPORTED_USING_JAVA";
+  public static final String WG_SPECIFICITY_CONFLICTS = 
+	 "WG_SPECIFICITY_CONFLICTS";
+  public static final String WG_PARSING_AND_PREPARING = 
+	 "WG_PARSING_AND_PREPARING";
+  public static final String WG_ATTR_TEMPLATE = "WG_ATTR_TEMPLATE";
+  public static final String WG_CONFLICT_BETWEEN_XSLSTRIPSPACE_AND_XSLPRESERVESPACE = "WG_CONFLICT_BETWEEN_XSLSTRIPSPACE_AND_XSLPRESERVESP";
+  public static final String WG_ATTRIB_NOT_HANDLED = "WG_ATTRIB_NOT_HANDLED";
+  public static final String WG_NO_DECIMALFORMAT_DECLARATION = 
+	 "WG_NO_DECIMALFORMAT_DECLARATION";
+  public static final String WG_OLD_XSLT_NS = "WG_OLD_XSLT_NS";
+  public static final String WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED = 
+	 "WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED";
+  public static final String WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE = 
+	 "WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE";
+  public static final String WG_ILLEGAL_ATTRIBUTE = "WG_ILLEGAL_ATTRIBUTE";
+  public static final String WG_COULD_NOT_RESOLVE_PREFIX = 
+	 "WG_COULD_NOT_RESOLVE_PREFIX";
+  public static final String WG_STYLESHEET_REQUIRES_VERSION_ATTRIB = 
+	 "WG_STYLESHEET_REQUIRES_VERSION_ATTRIB";
+  public static final String WG_ILLEGAL_ATTRIBUTE_NAME = 
+	 "WG_ILLEGAL_ATTRIBUTE_NAME";
+  public static final String WG_ILLEGAL_ATTRIBUTE_VALUE = 
+	 "WG_ILLEGAL_ATTRIBUTE_VALUE";
+  public static final String WG_EMPTY_SECOND_ARG = "WG_EMPTY_SECOND_ARG";
+  public static final String WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML = 
+	 "WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML";
+  public static final String WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME = 
+	 "WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME";
+  public static final String WG_ILLEGAL_ATTRIBUTE_POSITION = 
+	 "WG_ILLEGAL_ATTRIBUTE_POSITION";
+  public static final String NO_MODIFICATION_ALLOWED_ERR = 
+         "NO_MODIFICATION_ALLOWED_ERR";
+
+  /*
+   * Now fill in the message text.
+   * Then fill in the message text for that message code in the
+   * array. Use the new error code as the index into the array.
+   */
+
+  // Error messages...
+
+  /** Get the lookup table for error messages.   
+   *
+   * @return The int to message lookup table.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][] {
+
+  /** Error message ID that has a null message, but takes in a single object.    */
+  {"ER0000" , "{0}" },
+
+    { ER_NO_CURLYBRACE,                            
+      "Error: Can not have '{' within expression"},
+
+    { ER_ILLEGAL_ATTRIBUTE , 
+     "{0} has an illegal attribute: {1}"},
+
+  {ER_NULL_SOURCENODE_APPLYIMPORTS ,
+      "sourceNode is null in xsl:apply-imports!"},
+
+  {ER_CANNOT_ADD,
+      "Can not add {0} to {1}"},
+
+    { ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES, 
+      "sourceNode is null in handleApplyTemplatesInstruction!"},
+
+    { ER_NO_NAME_ATTRIB, 
+     "{0} must have a name attribute."},
+
+    {ER_TEMPLATE_NOT_FOUND,
+     "Could not find template named: {0}"},
+
+    {ER_CANT_RESOLVE_NAME_AVT,
+      "Could not resolve name AVT in xsl:call-template."},
+
+    {ER_REQUIRES_ATTRIB,
+     "{0} requires attribute: {1}"},
+
+    { ER_MUST_HAVE_TEST_ATTRIB, 
+      "{0} must have a ''test'' attribute."},
+
+    {ER_BAD_VAL_ON_LEVEL_ATTRIB,
+      "Bad value on level attribute: {0}"},
+
+    {ER_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML, 
+      "processing-instruction name can not be 'xml'"},
+
+    { ER_PROCESSINGINSTRUCTION_NOTVALID_NCNAME,
+      "processing-instruction name must be a valid NCName: {0}"},
+
+    { ER_NEED_MATCH_ATTRIB,
+      "{0} must have a match attribute if it has a mode."},
+
+    { ER_NEED_NAME_OR_MATCH_ATTRIB,
+      "{0} requires either a name or a match attribute."},
+
+    {ER_CANT_RESOLVE_NSPREFIX,
+      "Can not resolve namespace prefix: {0}"},
+
+    { ER_ILLEGAL_VALUE,
+     "xml:space has an illegal value: {0}"},
+
+    { ER_NO_OWNERDOC,
+      "Child node does not have an owner document!"},
+
+    { ER_ELEMTEMPLATEELEM_ERR,
+     "ElemTemplateElement error: {0}"},
+
+    { ER_NULL_CHILD,
+     "Trying to add a null child!"},
+
+    { ER_NEED_SELECT_ATTRIB,
+     "{0} requires a select attribute."},
+
+    { ER_NEED_TEST_ATTRIB ,
+      "xsl:when must have a 'test' attribute."},
+
+    { ER_NEED_NAME_ATTRIB,
+      "xsl:with-param must have a 'name' attribute."},
+
+    { ER_NO_CONTEXT_OWNERDOC,
+      "context does not have an owner document!"},
+
+    {ER_COULD_NOT_CREATE_XML_PROC_LIAISON,
+      "Could not create XML TransformerFactory Liaison: {0}"},
+
+    {ER_PROCESS_NOT_SUCCESSFUL,
+      "Xalan: Process was not successful."},
+
+    { ER_NOT_SUCCESSFUL,
+     "Xalan: was not successful."},
+
+    { ER_ENCODING_NOT_SUPPORTED,
+     "Encoding not supported: {0}"},
+
+    {ER_COULD_NOT_CREATE_TRACELISTENER,
+      "Could not create TraceListener: {0}"},
+
+    {ER_KEY_REQUIRES_NAME_ATTRIB,
+      "xsl:key requires a 'name' attribute!"},
+
+    { ER_KEY_REQUIRES_MATCH_ATTRIB,
+      "xsl:key requires a 'match' attribute!"},
+
+    { ER_KEY_REQUIRES_USE_ATTRIB,
+      "xsl:key requires a 'use' attribute!"},
+
+    { ER_REQUIRES_ELEMENTS_ATTRIB,
+      "(StylesheetHandler) {0} requires an ''elements'' attribute!"},
+
+    { ER_MISSING_PREFIX_ATTRIB,
+      "(StylesheetHandler) {0} attribute ''prefix'' is missing"},
+
+    { ER_BAD_STYLESHEET_URL,
+     "Stylesheet URL is bad: {0}"},
+
+    { ER_FILE_NOT_FOUND,
+     "Stylesheet file was not found: {0}"},
+
+    { ER_IOEXCEPTION,
+      "Had IO Exception with stylesheet file: {0}"},
+
+    { ER_NO_HREF_ATTRIB, 
+      "(StylesheetHandler) Could not find href attribute for {0}"},
+
+    { ER_STYLESHEET_INCLUDES_ITSELF, 
+      "(StylesheetHandler) {0} is directly or indirectly including itself!"},
+
+    { ER_PROCESSINCLUDE_ERROR,
+      "StylesheetHandler.processInclude error, {0}"},
+
+    { ER_MISSING_LANG_ATTRIB,
+      "(StylesheetHandler) {0} attribute ''lang'' is missing"},
+
+    { ER_MISSING_CONTAINER_ELEMENT_COMPONENT,
+      "(StylesheetHandler) misplaced {0} element?? Missing container element ''component''"},
+
+    { ER_CAN_ONLY_OUTPUT_TO_ELEMENT,
+      "Can only output to an Element, DocumentFragment, Document, or PrintWriter."},
+
+    { ER_PROCESS_ERROR,
+     "StylesheetRoot.process error"},
+
+    { ER_UNIMPLNODE_ERROR,
+     "UnImplNode error: {0}"},
+
+    { ER_NO_SELECT_EXPRESSION,
+      "Error! Did not find xpath select expression (-select)."},
+
+    { ER_CANNOT_SERIALIZE_XSLPROCESSOR, 
+      "Can not serialize an XSLProcessor!"},
+
+    { ER_NO_INPUT_STYLESHEET,
+      "Stylesheet input was not specified!"},
+
+    { ER_FAILED_PROCESS_STYLESHEET,
+      "Failed to process stylesheet!"},
+
+    { ER_COULDNT_PARSE_DOC,       
+     "Could not parse {0} document!"},
+
+    { ER_COULDNT_FIND_FRAGMENT,
+     "Could not find fragment: {0}"},
+
+    { ER_NODE_NOT_ELEMENT,
+      "Node pointed to by fragment identifier was not an element: {0}"},
+
+    { ER_FOREACH_NEED_MATCH_OR_NAME_ATTRIB,
+      "for-each must have either a match or name attribute"},
+
+    { ER_TEMPLATES_NEED_MATCH_OR_NAME_ATTRIB, 
+      "templates must have either a match or name attribute"},
+
+    { ER_NO_CLONE_OF_DOCUMENT_FRAG,
+      "No clone of a document fragment!"},
+
+    { ER_CANT_CREATE_ITEM,
+      "Can not create item in result tree: {0}"},
+
+    { ER_XMLSPACE_ILLEGAL_VALUE,
+      "xml:space in the source XML has an illegal value: {0}"},
+
+    { ER_NO_XSLKEY_DECLARATION,
+      "There is no xsl:key declaration for {0}!"},
+
+    { ER_CANT_CREATE_URL, 
+     "Error! Cannot create url for: {0}"},
+
+    { ER_XSLFUNCTIONS_UNSUPPORTED,
+     "xsl:functions is unsupported"},
+
+    { ER_PROCESSOR_ERROR, 
+     "XSLT TransformerFactory Error"},
+
+    { ER_NOT_ALLOWED_INSIDE_STYLESHEET,
+      "(StylesheetHandler) {0} not allowed inside a stylesheet!"},
+
+    { ER_RESULTNS_NOT_SUPPORTED, 
+      "result-ns no longer supported!  Use xsl:output instead."},
+
+    { ER_DEFAULTSPACE_NOT_SUPPORTED, 
+      "default-space no longer supported!  Use xsl:strip-space or xsl:preserve-space instead."},
+
+    { ER_INDENTRESULT_NOT_SUPPORTED,
+      "indent-result no longer supported!  Use xsl:output instead."},
+
+    { ER_ILLEGAL_ATTRIB,
+      "(StylesheetHandler) {0} has an illegal attribute: {1}"},
+
+    { ER_UNKNOWN_XSL_ELEM,
+     "Unknown XSL element: {0}"},
+
+    { ER_BAD_XSLSORT_USE,
+      "(StylesheetHandler) xsl:sort can only be used with xsl:apply-templates or xsl:for-each."},
+
+    { ER_MISPLACED_XSLWHEN,
+      "(StylesheetHandler) misplaced xsl:when!"},
+
+    { ER_XSLWHEN_NOT_PARENTED_BY_XSLCHOOSE,
+      "(StylesheetHandler) xsl:when not parented by xsl:choose!"},
+
+    { ER_MISPLACED_XSLOTHERWISE,
+      "(StylesheetHandler) misplaced xsl:otherwise!"},
+
+    { ER_XSLOTHERWISE_NOT_PARENTED_BY_XSLCHOOSE,
+      "(StylesheetHandler) xsl:otherwise not parented by xsl:choose!"},
+
+    { ER_NOT_ALLOWED_INSIDE_TEMPLATE,
+      "(StylesheetHandler) {0} is not allowed inside a template!"},
+
+    { ER_UNKNOWN_EXT_NS_PREFIX, 
+      "(StylesheetHandler) {0} extension namespace prefix {1} unknown"},
+
+    { ER_IMPORTS_AS_FIRST_ELEM, 
+      "(StylesheetHandler) Imports can only occur as the first elements in the stylesheet!"},
+
+    { ER_IMPORTING_ITSELF,
+      "(StylesheetHandler) {0} is directly or indirectly importing itself!"},
+
+    { ER_XMLSPACE_ILLEGAL_VAL,
+      "(StylesheetHandler) " + "xml:space has an illegal value: {0}"},
+
+    { ER_PROCESSSTYLESHEET_NOT_SUCCESSFUL,
+      "processStylesheet not succesfull!"},
+
+    { ER_SAX_EXCEPTION, 
+     "SAX Exception"},
+
+//  add this message to fix bug 21478
+    { ER_FUNCTION_NOT_SUPPORTED, 
+     "Function not supported!"},
+
+    { ER_XSLT_ERROR,
+     "XSLT Error"},
+
+    { ER_CURRENCY_SIGN_ILLEGAL,
+      "currency sign is not allowed in format pattern string"},
+
+    { ER_DOCUMENT_FUNCTION_INVALID_IN_STYLESHEET_DOM,
+      "Document function not supported in Stylesheet DOM!"},
+
+    { ER_CANT_RESOLVE_PREFIX_OF_NON_PREFIX_RESOLVER,
+      "Can't resolve prefix of non-Prefix resolver!"},
+
+    { ER_REDIRECT_COULDNT_GET_FILENAME,
+      "Redirect extension: Could not get filename - file or select attribute must return vald string."},
+
+    { ER_CANNOT_BUILD_FORMATTERLISTENER_IN_REDIRECT,
+      "Can not build FormatterListener in Redirect extension!"},
+
+    { ER_INVALID_PREFIX_IN_EXCLUDERESULTPREFIX,
+      "Prefix in exclude-result-prefixes is not valid: {0}"},
+
+    { ER_MISSING_NS_URI, 
+      "Missing namespace URI for specified prefix"},
+
+    { ER_MISSING_ARG_FOR_OPTION,
+      "Missing argument for option: {0}"},
+
+    { ER_INVALID_OPTION,
+     "Invalid option: {0}"},
+
+    { ER_MALFORMED_FORMAT_STRING,
+     "Malformed format string: {0}"},
+
+    { ER_STYLESHEET_REQUIRES_VERSION_ATTRIB,
+      "xsl:stylesheet requires a 'version' attribute!"},
+
+    { ER_ILLEGAL_ATTRIBUTE_VALUE,
+      "Attribute: {0} has an illegal value: {1}"},
+
+    { ER_CHOOSE_REQUIRES_WHEN,
+     "xsl:choose requires an xsl:when"},
+
+    { ER_NO_APPLY_IMPORT_IN_FOR_EACH,
+      "xsl:apply-imports not allowed in a xsl:for-each"},
+
+    { ER_CANT_USE_DTM_FOR_OUTPUT,
+      "Cannot use a DTMLiaison for an output DOM node... pass a org.apache.xpath.DOM2Helper instead!"},
+
+    { ER_CANT_USE_DTM_FOR_INPUT,
+      "Cannot use a DTMLiaison for a input DOM node... pass a org.apache.xpath.DOM2Helper instead!"},
+
+    { ER_CALL_TO_EXT_FAILED,
+      "Call to extension element failed: {0}"},
+
+    { ER_PREFIX_MUST_RESOLVE,
+      "Prefix must resolve to a namespace: {0}"},
+
+    { ER_INVALID_UTF16_SURROGATE,
+      "Invalid UTF-16 surrogate detected: {0} ?"},
+
+    { ER_XSLATTRSET_USED_ITSELF,
+      "xsl:attribute-set {0} used itself, which will cause an infinite loop."},
+
+    { ER_CANNOT_MIX_XERCESDOM,
+      "Can not mix non Xerces-DOM input with Xerces-DOM output!"},
+
+    { ER_TOO_MANY_LISTENERS,
+      "addTraceListenersToStylesheet - TooManyListenersException"},
+
+    { ER_IN_ELEMTEMPLATEELEM_READOBJECT,
+      "In ElemTemplateElement.readObject: {0}"},
+
+    { ER_DUPLICATE_NAMED_TEMPLATE,
+      "Found more than one template named: {0}"},
+
+    { ER_INVALID_KEY_CALL,
+      "Invalid function call: recursive key() calls are not allowed"},
+
+    { ER_REFERENCING_ITSELF,
+      "Variable {0} is directly or indirectly referencing itself!"},
+
+    { ER_ILLEGAL_DOMSOURCE_INPUT,
+      "The input node can not be null for a DOMSource for newTemplates!"},
+
+    { ER_CLASS_NOT_FOUND_FOR_OPTION,
+	"Class file not found for option {0}"},
+
+    { ER_REQUIRED_ELEM_NOT_FOUND,
+	"Required Element not found: {0}"},
+
+    { ER_INPUT_CANNOT_BE_NULL,
+	"InputStream cannot be null"},
+
+    { ER_URI_CANNOT_BE_NULL,
+	"URI cannot be null"},
+
+    { ER_FILE_CANNOT_BE_NULL,
+	"File cannot be null"},
+
+    { ER_SOURCE_CANNOT_BE_NULL,
+		"InputSource cannot be null"},
+
+    { ER_CANNOT_INIT_BSFMGR,
+		"Could not initialize BSF Manager"},
+
+    { ER_CANNOT_CMPL_EXTENSN,
+		"Could not compile extension"},
+
+    { ER_CANNOT_CREATE_EXTENSN,
+      "Could not create extension: {0} because of: {1}"},
+
+    { ER_INSTANCE_MTHD_CALL_REQUIRES,
+      "Instance method call to method {0} requires an Object instance as first argument"},
+
+    { ER_INVALID_ELEMENT_NAME,
+      "Invalid element name specified {0}"},
+
+    { ER_ELEMENT_NAME_METHOD_STATIC,
+      "Element name method must be static {0}"},
+
+    { ER_EXTENSION_FUNC_UNKNOWN,
+             "Extension function {0} : {1} is unknown"},
+
+    { ER_MORE_MATCH_CONSTRUCTOR,
+             "More than one best match for constructor for {0}"},
+
+    { ER_MORE_MATCH_METHOD,
+             "More than one best match for method {0}"},
+
+    { ER_MORE_MATCH_ELEMENT,
+             "More than one best match for element method {0}"},
+
+    { ER_INVALID_CONTEXT_PASSED,
+             "Invalid context passed to evaluate {0}"},
+
+    { ER_POOL_EXISTS,
+             "Pool already exists"},
+
+    { ER_NO_DRIVER_NAME,
+             "No driver Name specified"},
+
+    { ER_NO_URL,
+             "No URL specified"},
+
+    { ER_POOL_SIZE_LESSTHAN_ONE,
+             "Pool size is less than one!"},
+
+    { ER_INVALID_DRIVER,
+             "Invalid driver name specified!"},
+
+    { ER_NO_STYLESHEETROOT,
+             "Did not find the stylesheet root!"},
+
+    { ER_ILLEGAL_XMLSPACE_VALUE,
+         "Illegal value for xml:space"},
+
+    { ER_PROCESSFROMNODE_FAILED,
+         "processFromNode failed"},
+
+    { ER_RESOURCE_COULD_NOT_LOAD,
+        "The resource [ {0} ] could not load: {1} \n {2} \t {3}"},
+
+    { ER_BUFFER_SIZE_LESSTHAN_ZERO,
+        "Buffer size <=0"},
+
+    { ER_UNKNOWN_ERROR_CALLING_EXTENSION,
+        "Unknown error when calling extension"},
+
+    { ER_NO_NAMESPACE_DECL,
+        "Prefix {0} does not have a corresponding namespace declaration"},
+
+    { ER_ELEM_CONTENT_NOT_ALLOWED,
+        "Element content not allowed for lang=javaclass {0}"},
+
+    { ER_STYLESHEET_DIRECTED_TERMINATION,
+        "Stylesheet directed termination"},
+
+    { ER_ONE_OR_TWO,
+        "1 or 2"},
+
+    { ER_TWO_OR_THREE,
+        "2 or 3"},
+
+    { ER_COULD_NOT_LOAD_RESOURCE,
+        "Could not load {0} (check CLASSPATH), now using just the defaults"},
+
+    { ER_CANNOT_INIT_DEFAULT_TEMPLATES,
+        "Cannot initialize default templates"},
+
+    { ER_RESULT_NULL,
+        "Result should not be null"},
+
+    { ER_RESULT_COULD_NOT_BE_SET,
+        "Result could not be set"},
+
+    { ER_NO_OUTPUT_SPECIFIED,
+        "No output specified"},
+
+    { ER_CANNOT_TRANSFORM_TO_RESULT_TYPE,
+        "Can''t transform to a Result of type {0}"},
+
+    { ER_CANNOT_TRANSFORM_SOURCE_TYPE,
+        "Can''t transform a Source of type {0}"},
+
+    { ER_NULL_CONTENT_HANDLER,
+        "Null content handler"},
+
+    { ER_NULL_ERROR_HANDLER,
+        "Null error handler"},
+
+    { ER_CANNOT_CALL_PARSE,
+        "parse can not be called if the ContentHandler has not been set"},
+
+    { ER_NO_PARENT_FOR_FILTER,
+        "No parent for filter"},
+
+    { ER_NO_STYLESHEET_IN_MEDIA,
+         "No stylesheet found in: {0}, media= {1}"},
+
+    { ER_NO_STYLESHEET_PI,
+         "No xml-stylesheet PI found in: {0}"},
+
+    { ER_NOT_SUPPORTED,
+       "Not supported: {0}"},
+
+    { ER_PROPERTY_VALUE_BOOLEAN,
+       "Value for property {0} should be a Boolean instance"},
+
+    { ER_COULD_NOT_FIND_EXTERN_SCRIPT,
+         "Could not get to external script at {0}"},
+
+    { ER_RESOURCE_COULD_NOT_FIND,
+        "The resource [ {0} ] could not be found.\n {1}"},
+
+    { ER_OUTPUT_PROPERTY_NOT_RECOGNIZED,
+        "Output property not recognized: {0}"},
+
+    { ER_FAILED_CREATING_ELEMLITRSLT,
+        "Failed creating ElemLiteralResult instance"},
+
+  //Earlier (JDK 1.4 XALAN 2.2-D11) at key code '204' the key name was ER_PRIORITY_NOT_PARSABLE
+  // In latest Xalan code base key name is  ER_VALUE_SHOULD_BE_NUMBER. This should also be taken care
+  //in locale specific files like XSLTErrorResources_de.java, XSLTErrorResources_fr.java etc.
+  //NOTE: Not only the key name but message has also been changed. 
+    { ER_VALUE_SHOULD_BE_NUMBER,
+        "Value for {0} should contain a parsable number"},
+
+    { ER_VALUE_SHOULD_EQUAL,
+        "Value for {0} should equal yes or no"},
+
+    { ER_FAILED_CALLING_METHOD,
+        "Failed calling {0} method"},
+
+    { ER_FAILED_CREATING_ELEMTMPL,
+        "Failed creating ElemTemplateElement instance"},
+
+    { ER_CHARS_NOT_ALLOWED,
+        "Characters are not allowed at this point in the document"},
+
+    { ER_ATTR_NOT_ALLOWED,
+        "\"{0}\" attribute is not allowed on the {1} element!"},
+
+    { ER_BAD_VALUE,
+     "{0} bad value {1} "},
+
+    { ER_ATTRIB_VALUE_NOT_FOUND,
+     "{0} attribute value not found "},
+
+    { ER_ATTRIB_VALUE_NOT_RECOGNIZED,
+     "{0} attribute value not recognized "},
+
+    { ER_NULL_URI_NAMESPACE,
+     "Attempting to generate a namespace prefix with a null URI"},
+
+    { ER_NUMBER_TOO_BIG,
+     "Attempting to format a number bigger than the largest Long integer"},
+
+    { ER_CANNOT_FIND_SAX1_DRIVER,
+     "Cannot find SAX1 driver class {0}"},
+
+    { ER_SAX1_DRIVER_NOT_LOADED,
+     "SAX1 driver class {0} found but cannot be loaded"},
+
+    { ER_SAX1_DRIVER_NOT_INSTANTIATED,
+     "SAX1 driver class {0} loaded but cannot be instantiated"},
+
+    { ER_SAX1_DRIVER_NOT_IMPLEMENT_PARSER,
+     "SAX1 driver class {0} does not implement org.xml.sax.Parser"},
+
+    { ER_PARSER_PROPERTY_NOT_SPECIFIED,
+     "System property org.xml.sax.parser not specified"},
+
+    { ER_PARSER_ARG_CANNOT_BE_NULL,
+     "Parser argument must not be null"},
+
+    { ER_FEATURE,
+     "Feature: {0}"},
+
+    { ER_PROPERTY,
+     "Property: {0}"},
+
+    { ER_NULL_ENTITY_RESOLVER,
+     "Null entity resolver"},
+
+    { ER_NULL_DTD_HANDLER,
+     "Null DTD handler"},
+
+    { ER_NO_DRIVER_NAME_SPECIFIED,
+     "No Driver Name Specified!"},
+
+    { ER_NO_URL_SPECIFIED,
+     "No URL Specified!"},
+
+    { ER_POOLSIZE_LESS_THAN_ONE,
+     "Pool size is less than 1!"},
+
+    { ER_INVALID_DRIVER_NAME,
+     "Invalid Driver Name Specified!"},
+
+    { ER_ERRORLISTENER,
+     "ErrorListener"},
+
+
+// Note to translators:  The following message should not normally be displayed
+//   to users.  It describes a situation in which the processor has detected
+//   an internal consistency problem in itself, and it provides this message
+//   for the developer to help diagnose the problem.  The name
+//   'ElemTemplateElement' is the name of a class, and should not be
+//   translated.
+    { ER_ASSERT_NO_TEMPLATE_PARENT,
+     "Programmer's error! The expression has no ElemTemplateElement parent!"},
+
+
+// Note to translators:  The following message should not normally be displayed
+//   to users.  It describes a situation in which the processor has detected
+//   an internal consistency problem in itself, and it provides this message
+//   for the developer to help diagnose the problem.  The substitution text
+//   provides further information in order to diagnose the problem.  The name
+//   'RedundentExprEliminator' is the name of a class, and should not be
+//   translated.
+    { ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR,
+     "Programmer''s assertion in RedundentExprEliminator: {0}"},
+
+    { ER_NOT_ALLOWED_IN_POSITION,
+     "{0} is not allowed in this position in the stylesheet!"},
+
+    { ER_NONWHITESPACE_NOT_ALLOWED_IN_POSITION,
+     "Non-whitespace text is not allowed in this position in the stylesheet!"},
+
+  // This code is shared with warning codes.
+  // SystemId Unknown
+    { INVALID_TCHAR,
+     "Illegal value: {1} used for CHAR attribute: {0}.  An attribute of type CHAR must be only 1 character!"},
+
+    // Note to translators:  The following message is used if the value of
+    // an attribute in a stylesheet is invalid.  "QNAME" is the XML data-type of
+    // the attribute, and should not be translated.  The substitution text {1} is
+    // the attribute value and {0} is the attribute name.
+  //The following codes are shared with the warning codes...
+    { INVALID_QNAME,
+     "Illegal value: {1} used for QNAME attribute: {0}"},
+
+    // Note to translators:  The following message is used if the value of
+    // an attribute in a stylesheet is invalid.  "ENUM" is the XML data-type of
+    // the attribute, and should not be translated.  The substitution text {1} is
+    // the attribute value, {0} is the attribute name, and {2} is a list of valid
+    // values.
+    { INVALID_ENUM,
+     "Illegal value: {1} used for ENUM attribute: {0}.  Valid values are: {2}."},
+
+// Note to translators:  The following message is used if the value of
+// an attribute in a stylesheet is invalid.  "NMTOKEN" is the XML data-type
+// of the attribute, and should not be translated.  The substitution text {1} is
+// the attribute value and {0} is the attribute name.
+    { INVALID_NMTOKEN,
+     "Illegal value: {1} used for NMTOKEN attribute: {0} "},
+
+// Note to translators:  The following message is used if the value of
+// an attribute in a stylesheet is invalid.  "NCNAME" is the XML data-type
+// of the attribute, and should not be translated.  The substitution text {1} is
+// the attribute value and {0} is the attribute name.
+    { INVALID_NCNAME,
+     "Illegal value: {1} used for NCNAME attribute: {0} "},
+
+// Note to translators:  The following message is used if the value of
+// an attribute in a stylesheet is invalid.  "boolean" is the XSLT data-type
+// of the attribute, and should not be translated.  The substitution text {1} is
+// the attribute value and {0} is the attribute name.
+    { INVALID_BOOLEAN,
+     "Illegal value: {1} used for boolean attribute: {0} "},
+
+// Note to translators:  The following message is used if the value of
+// an attribute in a stylesheet is invalid.  "number" is the XSLT data-type
+// of the attribute, and should not be translated.  The substitution text {1} is
+// the attribute value and {0} is the attribute name.
+     { INVALID_NUMBER,
+     "Illegal value: {1} used for number attribute: {0} "},
+
+
+  // End of shared codes...
+
+// Note to translators:  A "match pattern" is a special form of XPath expression
+// that is used for matching patterns.  The substitution text is the name of
+// a function.  The message indicates that when this function is referenced in
+// a match pattern, its argument must be a string literal (or constant.)
+// ER_ARG_LITERAL - new error message for bugzilla //5202
+    { ER_ARG_LITERAL,
+     "Argument to {0} in match pattern must be a literal."},
+
+// Note to translators:  The following message indicates that two definitions of
+// a variable.  A "global variable" is a variable that is accessible everywher
+// in the stylesheet.
+// ER_DUPLICATE_GLOBAL_VAR - new error message for bugzilla #790
+    { ER_DUPLICATE_GLOBAL_VAR,
+     "Duplicate global variable declaration."},
+
+
+// Note to translators:  The following message indicates that two definitions of
+// a variable were encountered.
+// ER_DUPLICATE_VAR - new error message for bugzilla #790
+    { ER_DUPLICATE_VAR,
+     "Duplicate variable declaration."},
+
+    // Note to translators:  "xsl:template, "name" and "match" are XSLT keywords
+    // which must not be translated.
+    // ER_TEMPLATE_NAME_MATCH - new error message for bugzilla #789
+    { ER_TEMPLATE_NAME_MATCH,
+     "xsl:template must have a name or match attribute (or both)"},
+
+    // Note to translators:  "exclude-result-prefixes" is an XSLT keyword which
+    // should not be translated.  The message indicates that a namespace prefix
+    // encountered as part of the value of the exclude-result-prefixes attribute
+    // was in error.
+    // ER_INVALID_PREFIX - new error message for bugzilla #788
+    { ER_INVALID_PREFIX,
+     "Prefix in exclude-result-prefixes is not valid: {0}"},
+
+    // Note to translators:  An "attribute set" is a set of attributes that can
+    // be added to an element in the output document as a group.  The message
+    // indicates that there was a reference to an attribute set named {0} that
+    // was never defined.
+    // ER_NO_ATTRIB_SET - new error message for bugzilla #782
+    { ER_NO_ATTRIB_SET,
+     "attribute-set named {0} does not exist"},
+     
+    // Note to translators:  This message indicates that there was a reference
+    // to a function named {0} for which no function definition could be found.
+    { ER_FUNCTION_NOT_FOUND,
+     "The function named {0} does not exist"},
+
+    // Note to translators:  This message indicates that the XSLT instruction
+    // that is named by the substitution text {0} must not contain other XSLT
+    // instructions (content) or a "select" attribute.  The word "select" is
+    // an XSLT keyword in this case and must not be translated.
+    { ER_CANT_HAVE_CONTENT_AND_SELECT,
+     "The {0} element must not have both content and a select attribute."},
+
+    // Note to translators:  This message indicates that the value argument
+    // of setParameter must be a valid Java Object.
+    { ER_INVALID_SET_PARAM_VALUE,
+     "The value of param {0} must be a valid Java Object"},
+
+    { ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX_FOR_DEFAULT,
+      "The result-prefix attribute of an xsl:namespace-alias element has the value '#default', but there is no declaration of the default namespace in scope for the element"},
+
+    { ER_INVALID_NAMESPACE_URI_VALUE_FOR_RESULT_PREFIX,
+      "The result-prefix attribute of an xsl:namespace-alias element has the value ''{0}'', but there is no namespace declaration for the prefix ''{0}'' in scope for the element."},
+
+    { ER_SET_FEATURE_NULL_NAME,
+      "The feature name cannot be null in TransformerFactory.setFeature(String name, boolean value)."},
+    
+    { ER_GET_FEATURE_NULL_NAME,
+      "The feature name cannot be null in TransformerFactory.getFeature(String name)."},
+    
+    { ER_UNSUPPORTED_FEATURE,
+      "Cannot set the feature ''{0}'' on this TransformerFactory."},
+    
+    { ER_EXTENSION_ELEMENT_NOT_ALLOWED_IN_SECURE_PROCESSING,
+  	  "Use of the extension element ''{0}'' is not allowed when the secure processing feature is set to true."},
+    
+    { ER_NAMESPACE_CONTEXT_NULL_NAMESPACE, 		
+      "Cannot get the prefix for a null namespace uri."},
+
+    { ER_NAMESPACE_CONTEXT_NULL_PREFIX, 		
+      "Cannot get the namespace uri for null prefix."},
+
+    { ER_XPATH_RESOLVER_NULL_QNAME, 		
+      "The function name cannot be null."},
+
+    { ER_XPATH_RESOLVER_NEGATIVE_ARITY, 		
+      "The arity cannot be negative."},
+  // Warnings...
+
+    { WG_FOUND_CURLYBRACE,
+      "Found '}' but no attribute template open!"},
+
+    { WG_COUNT_ATTRIB_MATCHES_NO_ANCESTOR,
+      "Warning: count attribute does not match an ancestor in xsl:number! Target = {0}"},
+
+    { WG_EXPR_ATTRIB_CHANGED_TO_SELECT,
+      "Old syntax: The name of the 'expr' attribute has been changed to 'select'."},
+
+    { WG_NO_LOCALE_IN_FORMATNUMBER,
+      "Xalan doesn't yet handle the locale name in the format-number function."},
+
+    { WG_LOCALE_NOT_FOUND,
+      "Warning: Could not find locale for xml:lang={0}"},
+
+    { WG_CANNOT_MAKE_URL_FROM,
+      "Can not make URL from: {0}"},
+
+    { WG_CANNOT_LOAD_REQUESTED_DOC,
+      "Can not load requested doc: {0}"},
+
+    { WG_CANNOT_FIND_COLLATOR,
+      "Could not find Collator for <sort xml:lang={0}"},
+
+    { WG_FUNCTIONS_SHOULD_USE_URL,
+      "Old syntax: the functions instruction should use a url of {0}"},
+
+    { WG_ENCODING_NOT_SUPPORTED_USING_UTF8,
+      "encoding not supported: {0}, using UTF-8"},
+
+    { WG_ENCODING_NOT_SUPPORTED_USING_JAVA,
+      "encoding not supported: {0}, using Java {1}"},
+
+    { WG_SPECIFICITY_CONFLICTS,
+      "Specificity conflicts found: {0} Last found in stylesheet will be used."},
+
+    { WG_PARSING_AND_PREPARING,
+      "========= Parsing and preparing {0} =========="},
+
+    { WG_ATTR_TEMPLATE,
+     "Attr Template, {0}"},
+
+    { WG_CONFLICT_BETWEEN_XSLSTRIPSPACE_AND_XSLPRESERVESPACE,
+      "Match conflict between xsl:strip-space and xsl:preserve-space"},
+
+    { WG_ATTRIB_NOT_HANDLED,
+      "Xalan does not yet handle the {0} attribute!"},
+
+    { WG_NO_DECIMALFORMAT_DECLARATION,
+      "No declaration found for decimal format: {0}"},
+
+    { WG_OLD_XSLT_NS,
+     "Missing or incorrect XSLT Namespace. "},
+
+    { WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED,
+      "Only one default xsl:decimal-format declaration is allowed."},
+
+    { WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE,
+      "xsl:decimal-format names must be unique. Name \"{0}\" has been duplicated."},
+
+    { WG_ILLEGAL_ATTRIBUTE,
+      "{0} has an illegal attribute: {1}"},
+
+    { WG_COULD_NOT_RESOLVE_PREFIX,
+      "Could not resolve namespace prefix: {0}. The node will be ignored."},
+
+    { WG_STYLESHEET_REQUIRES_VERSION_ATTRIB,
+      "xsl:stylesheet requires a 'version' attribute!"},
+
+    { WG_ILLEGAL_ATTRIBUTE_NAME,
+      "Illegal attribute name: {0}"},
+
+    { WG_ILLEGAL_ATTRIBUTE_VALUE,
+      "Illegal value used for attribute {0}: {1}"},
+
+    { WG_EMPTY_SECOND_ARG,
+      "Resulting nodeset from second argument of document function is empty. Return an empty node-set."},
+
+  //Following are the new WARNING keys added in XALAN code base after Jdk 1.4 (Xalan 2.2-D11)
+
+    // Note to translators:  "name" and "xsl:processing-instruction" are keywords
+    // and must not be translated.
+    { WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML,
+      "The value of the 'name' attribute of xsl:processing-instruction name must not be 'xml'"},
+
+    // Note to translators:  "name" and "xsl:processing-instruction" are keywords
+    // and must not be translated.  "NCName" is an XML data-type and must not be
+    // translated.
+    { WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME,
+      "The value of the ''name'' attribute of xsl:processing-instruction must be a valid NCName: {0}"},
+
+    // Note to translators:  This message is reported if the stylesheet that is
+    // being processed attempted to construct an XML document with an attribute in a
+    // place other than on an element.  The substitution text specifies the name of
+    // the attribute.
+    { WG_ILLEGAL_ATTRIBUTE_POSITION,
+      "Cannot add attribute {0} after child nodes or before an element is produced.  Attribute will be ignored."},
+
+    { NO_MODIFICATION_ALLOWED_ERR,
+      "An attempt is made to modify an object where modifications are not allowed."
+    },
+
+    //Check: WHY THERE IS A GAP B/W NUMBERS in the XSLTErrorResources properties file?
+
+  // Other miscellaneous text used inside the code...
+  { "ui_language", "en"},
+  {  "help_language",  "en" },
+  {  "language",  "en" },
+  { "BAD_CODE", "Parameter to createMessage was out of bounds"},
+  {  "FORMAT_FAILED", "Exception thrown during messageFormat call"},
+  {  "version", ">>>>>>> Xalan Version "},
+  {  "version2",  "<<<<<<<"},
+  {  "yes", "yes"},
+  { "line", "Line #"},
+  { "column","Column #"},
+  { "xsldone", "XSLProcessor: done"},
+
+
+  // Note to translators:  The following messages provide usage information
+  // for the Xalan Process command line.  "Process" is the name of a Java class,
+  // and should not be translated.
+  { "xslProc_option", "Xalan-J command line Process class options:"},
+  { "xslProc_option", "Xalan-J command line Process class options\u003a"},
+  { "xslProc_invalid_xsltc_option", "The option {0} is not supported in XSLTC mode."},
+  { "xslProc_invalid_xalan_option", "The option {0} can only be used with -XSLTC."},
+  { "xslProc_no_input", "Error: No stylesheet or input xml is specified. Run this command without any option for usage instructions."},
+  { "xslProc_common_options", "-Common Options-"},
+  { "xslProc_xalan_options", "-Options for Xalan-"},
+  { "xslProc_xsltc_options", "-Options for XSLTC-"},
+  { "xslProc_return_to_continue", "(press <return> to continue)"},
+
+   // Note to translators: The option name and the parameter name do not need to
+   // be translated. Only translate the messages in parentheses.  Note also that
+   // leading whitespace in the messages is used to indent the usage information
+   // for each option in the English messages.
+   // Do not translate the keywords: XSLTC, SAX, DOM and DTM.
+  { "optionXSLTC", "   [-XSLTC (use XSLTC for transformation)]"},
+  { "optionIN", "   [-IN inputXMLURL]"},
+  { "optionXSL", "   [-XSL XSLTransformationURL]"},
+  { "optionOUT",  "   [-OUT outputFileName]"},
+  { "optionLXCIN", "   [-LXCIN compiledStylesheetFileNameIn]"},
+  { "optionLXCOUT", "   [-LXCOUT compiledStylesheetFileNameOutOut]"},
+  { "optionPARSER", "   [-PARSER fully qualified class name of parser liaison]"},
+  {  "optionE", "   [-E (Do not expand entity refs)]"},
+  {  "optionV",  "   [-E (Do not expand entity refs)]"},
+  {  "optionQC", "   [-QC (Quiet Pattern Conflicts Warnings)]"},
+  {  "optionQ", "   [-Q  (Quiet Mode)]"},
+  {  "optionLF", "   [-LF (Use linefeeds only on output {default is CR/LF})]"},
+  {  "optionCR", "   [-CR (Use carriage returns only on output {default is CR/LF})]"},
+  { "optionESCAPE", "   [-ESCAPE (Which characters to escape {default is <>&\"\'\\r\\n}]"},
+  { "optionINDENT", "   [-INDENT (Control how many spaces to indent {default is 0})]"},
+  { "optionTT", "   [-TT (Trace the templates as they are being called.)]"},
+  { "optionTG", "   [-TG (Trace each generation event.)]"},
+  { "optionTS", "   [-TS (Trace each selection event.)]"},
+  {  "optionTTC", "   [-TTC (Trace the template children as they are being processed.)]"},
+  { "optionTCLASS", "   [-TCLASS (TraceListener class for trace extensions.)]"},
+  { "optionVALIDATE", "   [-VALIDATE (Set whether validation occurs.  Validation is off by default.)]"},
+  { "optionEDUMP", "   [-EDUMP {optional filename} (Do stackdump on error.)]"},
+  {  "optionXML", "   [-XML (Use XML formatter and add XML header.)]"},
+  {  "optionTEXT", "   [-TEXT (Use simple Text formatter.)]"},
+  {  "optionHTML", "   [-HTML (Use HTML formatter.)]"},
+  {  "optionPARAM", "   [-PARAM name expression (Set a stylesheet parameter)]"},
+  {  "noParsermsg1", "XSL Process was not successful."},
+  {  "noParsermsg2", "** Could not find parser **"},
+  { "noParsermsg3",  "Please check your classpath."},
+  { "noParsermsg4", "If you don't have IBM's XML Parser for Java, you can download it from"},
+  { "noParsermsg5", "IBM's AlphaWorks: http://www.alphaworks.ibm.com/formula/xml"},
+  { "optionURIRESOLVER", "   [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]"},
+  { "optionENTITYRESOLVER",  "   [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]"},
+  { "optionCONTENTHANDLER",  "   [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]"},
+  {  "optionLINENUMBERS",  "   [-L use line numbers for source document]"},
+  { "optionSECUREPROCESSING", "   [-SECURE (set the secure processing feature to true.)]"},
+
+    // Following are the new options added in XSLTErrorResources.properties files after Jdk 1.4 (Xalan 2.2-D11)
+
+
+  {  "optionMEDIA",  "   [-MEDIA mediaType (use media attribute to find stylesheet associated with a document.)]"},
+  {  "optionFLAVOR",  "   [-FLAVOR flavorName (Explicitly use s2s=SAX or d2d=DOM to do transform.)] "}, // Added by sboag/scurcuru; experimental
+  { "optionDIAG", "   [-DIAG (Print overall milliseconds transform took.)]"},
+  { "optionINCREMENTAL",  "   [-INCREMENTAL (request incremental DTM construction by setting http://xml.apache.org/xalan/features/incremental true.)]"},
+  {  "optionNOOPTIMIMIZE",  "   [-NOOPTIMIMIZE (request no stylesheet optimization processing by setting http://xml.apache.org/xalan/features/optimize false.)]"},
+  { "optionRL",  "   [-RL recursionlimit (assert numeric limit on stylesheet recursion depth.)]"},
+  {   "optionXO",  "   [-XO [transletName] (assign the name to the generated translet)]"},
+  {  "optionXD", "   [-XD destinationDirectory (specify a destination directory for translet)]"},
+  {  "optionXJ",  "   [-XJ jarfile (packages translet classes into a jar file of name <jarfile>)]"},
+  {   "optionXP",  "   [-XP package (specifies a package name prefix for all generated translet classes)]"},
+
+  //AddITIONAL  STRINGS that need L10n
+  // Note to translators:  The following message describes usage of a particular
+  // command-line option that is used to enable the "template inlining"
+  // optimization.  The optimization involves making a copy of the code
+  // generated for a template in another template that refers to it.
+  { "optionXN",  "   [-XN (enables template inlining)]" },
+  { "optionXX",  "   [-XX (turns on additional debugging message output)]"},
+  { "optionXT" , "   [-XT (use translet to transform if possible)]"},
+  { "diagTiming"," --------- Transform of {0} via {1} took {2} ms" },
+  { "recursionTooDeep","Template nesting too deep. nesting = {0}, template {1} {2}" },
+  { "nameIs", "name is" },
+  { "matchPatternIs", "match pattern is" }
+
+  };
+  }
+  // ================= INFRASTRUCTURE ======================
+
+  /** String for use when a bad error code was encountered.    */
+  public static final String BAD_CODE = "BAD_CODE";
+
+  /** String for use when formatting of the error string failed.   */
+  public static final String FORMAT_FAILED = "FORMAT_FAILED";
+
+  /** General error string.   */
+  public static final String ERROR_STRING = "#error";
+
+  /** String to prepend to error messages.  */
+  public static final String ERROR_HEADER = "Error: ";
+
+  /** String to prepend to warning messages.    */
+  public static final String WARNING_HEADER = "Warning: ";
+
+  /** String to specify the XSLT module.  */
+  public static final String XSL_HEADER = "XSLT ";
+
+  /** String to specify the XML parser module.  */
+  public static final String XML_HEADER = "XML ";
+
+  /** I don't think this is used any more.
+   * @deprecated  */
+  public static final String QUERY_HEADER = "PATTERN ";
+
+
+  /**
+   *   Return a named ResourceBundle for a particular locale.  This method mimics the behavior
+   *   of ResourceBundle.getBundle().
+   *
+   *   @param className the name of the class that implements the resource bundle.
+   *   @return the ResourceBundle
+   *   @throws MissingResourceException
+   */
+  public static final XSLTErrorResources loadResourceBundle(String className)
+          throws MissingResourceException
+  {
+
+    Locale locale = Locale.getDefault();
+    String suffix = getResourceSuffix(locale);
+
+    try
+    {
+
+      // first try with the given locale
+      return (XSLTErrorResources) ResourceBundle.getBundle(className
+              + suffix, locale);
+    }
+    catch (MissingResourceException e)
+    {
+      try  // try to fall back to en_US if we can't load
+      {
+
+        // Since we can't find the localized property file,
+        // fall back to en_US.
+        return (XSLTErrorResources) ResourceBundle.getBundle(className,
+                new Locale("en", "US"));
+      }
+      catch (MissingResourceException e2)
+      {
+
+        // Now we are really in trouble.
+        // very bad, definitely very bad...not going to get very far
+        throw new MissingResourceException(
+          "Could not load any resource bundles.", className, "");
+      }
+    }
+  }
+
+  /**
+   * Return the resource file suffic for the indicated locale
+   * For most locales, this will be based the language code.  However
+   * for Chinese, we do distinguish between Taiwan and PRC
+   *
+   * @param locale the locale
+   * @return an String suffix which canbe appended to a resource name
+   */
+  private static final String getResourceSuffix(Locale locale)
+  {
+
+    String suffix = "_" + locale.getLanguage();
+    String country = locale.getCountry();
+
+    if (country.equals("TW"))
+      suffix += "_" + country;
+
+    return suffix;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xalan/res/XSLTInfo.properties b/src/main/java/org/apache/xalan/res/XSLTInfo.properties
new file mode 100644
index 0000000..309ac32
--- /dev/null
+++ b/src/main/java/org/apache/xalan/res/XSLTInfo.properties
@@ -0,0 +1,30 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: XSLTInfo.properties 468641 2006-10-28 06:54:42Z minchau $
+#
+#  XSLT Resource File
+#
+
+vendor=Apache Software Foundation
+vendor-url=http://xml.apache.org/xalan-j
+
+# Product Version: Xalan-Java @impl.version@
+
+# W3C XSL Transformations (XSLT) Version 1.0
+version=1.0
diff --git a/src/main/java/org/apache/xalan/res/package.html b/src/main/java/org/apache/xalan/res/package.html
new file mode 100644
index 0000000..b4acbad
--- /dev/null
+++ b/src/main/java/org/apache/xalan/res/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468641 2006-10-28 06:54:42Z minchau $ -->
+<html>
+  <title>Xalan resource Package.</title>
+  <body>
+    <p>Contains strings that require internationalization.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xalan/serialize/SerializerUtils.java b/src/main/java/org/apache/xalan/serialize/SerializerUtils.java
new file mode 100644
index 0000000..5127989
--- /dev/null
+++ b/src/main/java/org/apache/xalan/serialize/SerializerUtils.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerUtils.java 468642 2006-10-28 06:55:10Z minchau $
+ */
+package org.apache.xalan.serialize;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.serializer.NamespaceMappings;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.xml.sax.SAXException;
+
+/**
+ * Class that contains only static methods that are used to "serialize",
+ * these methods are used by Xalan and are not in org.apache.xml.serializer
+ * because they have dependancies on the packages org.apache.xpath or org.
+ * apache.xml.dtm or org.apache.xalan.transformer. The package org.apache.xml.
+ * serializer should not depend on Xalan or XSLTC.
+ * @xsl.usage internal
+ */
+public class SerializerUtils
+{
+
+    /**
+     * Copy an DOM attribute to the created output element, executing
+     * attribute templates as need be, and processing the xsl:use
+     * attribute.
+     *
+     * @param handler SerializationHandler to which the attributes are added.
+     * @param attr Attribute node to add to SerializationHandler.
+     *
+     * @throws TransformerException
+     */
+    public static void addAttribute(SerializationHandler handler, int attr)
+        throws TransformerException
+    {
+
+        TransformerImpl transformer =
+            (TransformerImpl) handler.getTransformer();
+        DTM dtm = transformer.getXPathContext().getDTM(attr);
+
+        if (SerializerUtils.isDefinedNSDecl(handler, attr, dtm))
+            return;
+
+        String ns = dtm.getNamespaceURI(attr);
+
+        if (ns == null)
+            ns = "";
+
+        // %OPT% ...can I just store the node handle?
+        try
+        {
+            handler.addAttribute(
+                ns,
+                dtm.getLocalName(attr),
+                dtm.getNodeName(attr),
+                "CDATA",
+                dtm.getNodeValue(attr), false);
+        }
+        catch (SAXException e)
+        {
+            // do something?
+        }
+    } // end copyAttributeToTarget method
+
+    /**
+     * Copy DOM attributes to the result element.
+     *
+     * @param src Source node with the attributes
+     *
+     * @throws TransformerException
+     */
+    public static void addAttributes(SerializationHandler handler, int src)
+        throws TransformerException
+    {
+
+        TransformerImpl transformer =
+            (TransformerImpl) handler.getTransformer();
+        DTM dtm = transformer.getXPathContext().getDTM(src);
+
+        for (int node = dtm.getFirstAttribute(src);
+            DTM.NULL != node;
+            node = dtm.getNextAttribute(node))
+        {
+            addAttribute(handler, node);
+        }
+    }
+
+    /**
+     * Given a result tree fragment, walk the tree and
+     * output it to the SerializationHandler.
+     *
+     * @param obj Result tree fragment object
+     * @param support XPath context for the result tree fragment
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public static void outputResultTreeFragment(
+        SerializationHandler handler,
+        XObject obj,
+        XPathContext support)
+        throws org.xml.sax.SAXException
+    {
+
+        int doc = obj.rtf();
+        DTM dtm = support.getDTM(doc);
+
+        if (null != dtm)
+        {
+            for (int n = dtm.getFirstChild(doc);
+                DTM.NULL != n;
+                n = dtm.getNextSibling(n))
+            {
+                handler.flushPending();
+
+                // I think. . . . This used to have a (true) arg
+                // to flush prefixes, will that cause problems ???
+                if (dtm.getNodeType(n) == DTM.ELEMENT_NODE
+                        && dtm.getNamespaceURI(n) == null)
+                    handler.startPrefixMapping("", "");
+                dtm.dispatchToEvents(n, handler);
+            }
+        }
+    }
+
+    /**
+     * Copy <KBD>xmlns:</KBD> attributes in if not already in scope.
+     *
+     * As a quick hack to support ClonerToResultTree, this can also be used
+     * to copy an individual namespace node.
+     *
+     * @param src Source Node
+     * NEEDSDOC @param type
+     * NEEDSDOC @param dtm
+     *
+     * @throws TransformerException
+     */
+    public static void processNSDecls(
+        SerializationHandler handler,
+        int src,
+        int type,
+        DTM dtm)
+        throws TransformerException
+    {
+
+        try
+        {
+            if (type == DTM.ELEMENT_NODE)
+            {
+                for (int namespace = dtm.getFirstNamespaceNode(src, true);
+                    DTM.NULL != namespace;
+                    namespace = dtm.getNextNamespaceNode(src, namespace, true))
+                {
+
+                    // String prefix = dtm.getPrefix(namespace);
+                    String prefix = dtm.getNodeNameX(namespace);
+                    String desturi = handler.getNamespaceURIFromPrefix(prefix);
+                    //            String desturi = getURI(prefix);
+                    String srcURI = dtm.getNodeValue(namespace);
+
+                    if (!srcURI.equalsIgnoreCase(desturi))
+                    {
+                        handler.startPrefixMapping(prefix, srcURI, false);
+                    }
+                }
+            }
+            else if (type == DTM.NAMESPACE_NODE)
+            {
+                String prefix = dtm.getNodeNameX(src);
+                // Brian M. - some changes here to get desturi
+                String desturi = handler.getNamespaceURIFromPrefix(prefix);
+                String srcURI = dtm.getNodeValue(src);
+
+                if (!srcURI.equalsIgnoreCase(desturi))
+                {
+                    handler.startPrefixMapping(prefix, srcURI, false);
+                }
+            }
+        }
+        catch (org.xml.sax.SAXException se)
+        {
+            throw new TransformerException(se);
+        }
+    }
+
+    /**
+     * Returns whether a namespace is defined
+     *
+     *
+     * @param attr Namespace attribute node
+     * @param dtm The DTM that owns attr.
+     *
+     * @return True if the namespace is already defined in
+     * list of namespaces
+     */
+    public static boolean isDefinedNSDecl(
+        SerializationHandler serializer,
+        int attr,
+        DTM dtm)
+    {
+
+        if (DTM.NAMESPACE_NODE == dtm.getNodeType(attr))
+        {
+
+            // String prefix = dtm.getPrefix(attr);
+            String prefix = dtm.getNodeNameX(attr);
+            String uri = serializer.getNamespaceURIFromPrefix(prefix);
+            //      String uri = getURI(prefix);
+
+            if ((null != uri) && uri.equals(dtm.getStringValue(attr)))
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * This function checks to make sure a given prefix is really
+     * declared.  It might not be, because it may be an excluded prefix.
+     * If it's not, it still needs to be declared at this point.
+     * TODO: This needs to be done at an earlier stage in the game... -sb
+     *
+     * NEEDSDOC @param dtm
+     * NEEDSDOC @param namespace
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public static void ensureNamespaceDeclDeclared(
+        SerializationHandler handler,
+        DTM dtm,
+        int namespace)
+        throws org.xml.sax.SAXException
+    {
+
+        String uri = dtm.getNodeValue(namespace);
+        String prefix = dtm.getNodeNameX(namespace);
+
+        if ((uri != null && uri.length() > 0) && (null != prefix))
+        {
+            String foundURI;
+            NamespaceMappings ns = handler.getNamespaceMappings();
+            if (ns != null)
+            {
+
+                foundURI = ns.lookupNamespace(prefix);
+                if ((null == foundURI) || !foundURI.equals(uri))
+                {
+                    handler.startPrefixMapping(prefix, uri, false);
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xalan/templates/AVT.java b/src/main/java/org/apache/xalan/templates/AVT.java
new file mode 100644
index 0000000..a8247e1
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/AVT.java
@@ -0,0 +1,614 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AVT.java 469221 2006-10-30 18:26:44Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.processor.StylesheetHandler;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.StringBufferPool;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Class to hold an Attribute Value Template.
+ * @xsl.usage advanced
+ */
+public class AVT implements java.io.Serializable, XSLTVisitable
+{
+    static final long serialVersionUID = 5167607155517042691L;
+  
+  /**
+    *We are not going to use the object pool if USE_OBJECT_POOL == false.
+  */
+  private final static boolean USE_OBJECT_POOL = false; 
+  
+  /**
+    * INIT_BUFFER_CHUNK_BITS is used to set initial size of
+    * of the char m_array in FastStringBuffer if USE_OBJECT_POOL == false. 
+    * size = 2^ INIT_BUFFER_CHUNK_BITS, INIT_BUFFER_CHUNK_BITS = 7 
+    * corresponds size = 256. 
+  */
+  private final static int INIT_BUFFER_CHUNK_BITS = 8; 
+  
+  /**
+   * If the AVT is not complex, just hold the simple string.
+   * @serial
+   */
+  private String m_simpleString = null;
+
+  /**
+   * If the AVT is complex, hold a Vector of AVTParts.
+   * @serial
+   */
+  private Vector m_parts = null;
+  
+   
+
+  /**
+   * The name of the attribute.
+   * @serial
+   */
+  private String m_rawName;
+
+  /**
+   * Get the raw name of the attribute, with the prefix unprocessed.
+   *
+   * @return non-null reference to prefixed name.
+   */
+  public String getRawName()
+  {
+    return m_rawName;
+  }
+
+  /**
+   * Get the raw name of the attribute, with the prefix unprocessed.
+   *
+   * @param rawName non-null reference to prefixed name.
+   */
+  public void setRawName(String rawName)
+  {
+    m_rawName = rawName;
+  }
+
+  /**
+   * The name of the attribute.
+   * @serial
+   */
+  private String m_name;
+
+  /**
+   * Get the local name of the attribute.
+   *
+   * @return non-null reference to name string.
+   */
+  public String getName()
+  {
+    return m_name;
+  }
+
+  /**
+   * Set the local name of the attribute.
+   *
+   * @param name non-null reference to name string.
+   */
+  public void setName(String name)
+  {
+    m_name = name;
+  }
+
+  /**
+   * The namespace URI of the owning attribute.
+   * @serial
+   */
+  private String m_uri;
+
+  /**
+   * Get the namespace URI of the attribute.
+   *
+   * @return non-null reference to URI, "" if null namespace.
+   */
+  public String getURI()
+  {
+    return m_uri;
+  }
+
+  /**
+   * Get the namespace URI of the attribute.
+   *
+   * @param uri non-null reference to URI, "" if null namespace.
+   */
+  public void setURI(String uri)
+  {
+    m_uri = uri;
+  }
+
+  /**
+   * Construct an AVT by parsing the string, and either
+   * constructing a vector of AVTParts, or simply hold
+   * on to the string if the AVT is simple.
+   *
+   * @param handler non-null reference to StylesheetHandler that is constructing.
+   * @param uri non-null reference to URI, "" if null namespace.
+   * @param name  non-null reference to name string.
+   * @param rawName prefixed name.
+   * @param stringedValue non-null raw string value.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public AVT(StylesheetHandler handler, String uri, String name, 
+             String rawName, String stringedValue,
+             ElemTemplateElement owner)
+          throws javax.xml.transform.TransformerException
+  {
+
+    m_uri = uri;
+    m_name = name;
+    m_rawName = rawName;
+
+    StringTokenizer tokenizer = new StringTokenizer(stringedValue, "{}\"\'",
+                                  true);
+    int nTokens = tokenizer.countTokens();
+
+    if (nTokens < 2)
+    {
+      m_simpleString = stringedValue;  // then do the simple thing
+    }
+    else
+    {
+      FastStringBuffer buffer = null;
+      FastStringBuffer exprBuffer = null;
+      if(USE_OBJECT_POOL){
+        buffer = StringBufferPool.get(); 
+        exprBuffer = StringBufferPool.get();
+      }else{
+        buffer = new FastStringBuffer(6);
+        exprBuffer = new FastStringBuffer(6);
+      }
+      try
+      {
+        m_parts = new Vector(nTokens + 1);
+
+        String t = null;  // base token
+        String lookahead = null;  // next token
+        String error = null;  // if non-null, break from loop
+
+        while (tokenizer.hasMoreTokens())
+        {
+          if (lookahead != null)
+          {
+            t = lookahead;
+            lookahead = null;
+          }
+          else
+            t = tokenizer.nextToken();
+
+          if (t.length() == 1)
+          {
+            switch (t.charAt(0))
+            {
+            case ('\"') :
+            case ('\'') :
+            {
+
+              // just keep on going, since we're not in an attribute template
+              buffer.append(t);
+
+              break;
+            }
+            case ('{') :
+            {
+
+              try
+              {
+                // Attribute Value Template start
+                lookahead = tokenizer.nextToken();
+
+                if (lookahead.equals("{"))
+                {
+
+                  // Double curlys mean escape to show curly
+                  buffer.append(lookahead);
+
+                  lookahead = null;
+
+                  break;  // from switch
+                }
+
+                /*
+                else if(lookahead.equals("\"") || lookahead.equals("\'"))
+                {
+                // Error. Expressions can not begin with quotes.
+                error = "Expressions can not begin with quotes.";
+                break; // from switch
+                }
+                */
+                else
+                {
+                  if (buffer.length() > 0)
+                  {
+                    m_parts.addElement(new AVTPartSimple(buffer.toString()));
+                    buffer.setLength(0);
+                  }
+
+                  exprBuffer.setLength(0);
+
+                  while (null != lookahead)
+                  {
+                    if (lookahead.length() == 1)
+                    {
+                      switch (lookahead.charAt(0))
+                      {
+                      case '\'' :
+                      case '\"' :
+                        {
+
+                          // String start
+                          exprBuffer.append(lookahead);
+
+                          String quote = lookahead;
+
+                          // Consume stuff 'till next quote
+                          lookahead = tokenizer.nextToken();
+
+                          while (!lookahead.equals(quote))
+                          {
+                            exprBuffer.append(lookahead);
+
+                            lookahead = tokenizer.nextToken();
+                          }
+
+                          exprBuffer.append(lookahead);
+
+                          lookahead = tokenizer.nextToken();
+
+                          break;
+                        }
+                      case '{' :
+                        {
+
+                          // What's another curly doing here?
+                          error = XSLMessages.createMessage(
+                                                            XSLTErrorResources.ER_NO_CURLYBRACE, null);  //"Error: Can not have \"{\" within expression.";
+                          
+                          lookahead = null;  // breaks out of inner while loop
+
+                          break;
+                        }
+                      case '}' :
+                        {
+
+                          // Proper close of attribute template.
+                          // Evaluate the expression.
+                          buffer.setLength(0);
+
+                          XPath xpath =
+                                       handler.createXPath(exprBuffer.toString(), owner);
+
+                          m_parts.addElement(new AVTPartXPath(xpath));
+
+                          lookahead = null;  // breaks out of inner while loop
+
+                          break;
+                        }
+                      default :
+                        {
+
+                          // part of the template stuff, just add it.
+                          exprBuffer.append(lookahead);
+
+                          lookahead = tokenizer.nextToken();
+                        }
+                      }  // end inner switch
+                    }  // end if lookahead length == 1
+                    else
+                    {
+
+                      // part of the template stuff, just add it.
+                      exprBuffer.append(lookahead);
+
+                      lookahead = tokenizer.nextToken();
+                    }
+                  }  // end while(!lookahead.equals("}"))
+
+                  if (error != null)
+                  {
+                    break;  // from inner while loop
+                  }
+                }
+
+                break;
+              }
+              catch (java.util.NoSuchElementException ex)
+              {
+                error = XSLMessages.createMessage(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new Object[]{ name, stringedValue }); 
+                break;
+              }
+            }
+            case ('}') :
+            {
+              lookahead = tokenizer.nextToken();
+
+              if (lookahead.equals("}"))
+              {
+
+                // Double curlys mean escape to show curly
+                buffer.append(lookahead);
+
+                lookahead = null;  // swallow
+              }
+              else
+              {
+
+                // Illegal, I think...
+                try
+                {
+                  handler.warn(XSLTErrorResources.WG_FOUND_CURLYBRACE, null);  //"Found \"}\" but no attribute template open!");
+                }
+                catch (org.xml.sax.SAXException se)
+                {
+                  throw new TransformerException(se);
+                }
+
+                buffer.append("}");
+
+                // leave the lookahead to be processed by the next round.
+              }
+
+              break;
+            }
+            default :
+            {
+
+              // Anything else just add to string.
+              buffer.append(t);
+            }
+            }  // end switch t
+          }  // end if length == 1
+          else
+          {
+
+            // Anything else just add to string.
+            buffer.append(t);
+          }
+
+          if (null != error)
+          {
+            try
+            {
+              handler.warn(XSLTErrorResources.WG_ATTR_TEMPLATE,
+                           new Object[]{ error });  //"Attr Template, "+error);
+            }
+            catch (org.xml.sax.SAXException se)
+            {
+              throw new TransformerException(se);
+            }
+
+            break;
+          }
+        }  // end while(tokenizer.hasMoreTokens())
+
+        if (buffer.length() > 0)
+        {
+          m_parts.addElement(new AVTPartSimple(buffer.toString()));
+          buffer.setLength(0);
+        }
+      }
+      finally
+      {
+        if(USE_OBJECT_POOL){
+             StringBufferPool.free(buffer);
+             StringBufferPool.free(exprBuffer);
+         }else{
+            buffer = null;
+            exprBuffer = null;
+         };
+      }
+    }  // end else nTokens > 1
+
+    if (null == m_parts && (null == m_simpleString))
+    {
+
+      // Error?
+      m_simpleString = "";
+    }
+  }
+
+  /**
+   * Get the AVT as the original string.
+   *
+   * @return The AVT as the original string
+   */
+  public String getSimpleString()
+  {
+
+    if (null != m_simpleString){
+      return m_simpleString;
+    }
+    else if (null != m_parts){
+     final FastStringBuffer buf = getBuffer();
+     String out = null;
+
+    int n = m_parts.size();
+    try{
+      for (int i = 0; i < n; i++){
+        AVTPart part = (AVTPart) m_parts.elementAt(i);
+        buf.append(part.getSimpleString());
+      }
+      out = buf.toString();
+    }finally{
+      if(USE_OBJECT_POOL){
+         StringBufferPool.free(buf);
+     }else{
+        buf.setLength(0); 
+     };
+    }
+    return out;
+  }else{
+      return "";
+  }
+}
+
+  /**
+   * Evaluate the AVT and return a String.
+   *
+   * @param xctxt Te XPathContext to use to evaluate this.
+   * @param context The current source tree context.
+   * @param nsNode The current namespace context (stylesheet tree context).
+   *
+   * @return The AVT evaluated as a string
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public String evaluate(
+          XPathContext xctxt, int context, org.apache.xml.utils.PrefixResolver nsNode)
+            throws javax.xml.transform.TransformerException
+  {
+    if (null != m_simpleString){
+        return m_simpleString;
+    }else if (null != m_parts){
+      final FastStringBuffer buf =getBuffer();
+      String out = null;
+      int n = m_parts.size();
+      try{
+        for (int i = 0; i < n; i++){
+          AVTPart part = (AVTPart) m_parts.elementAt(i);  
+          part.evaluate(xctxt, buf, context, nsNode);
+        }
+       out = buf.toString();
+      }finally{
+          if(USE_OBJECT_POOL){
+             StringBufferPool.free(buf);
+         }else{
+           buf.setLength(0); 
+         }
+      }
+     return out;
+    }else{
+      return "";
+    }
+  }
+
+  /**
+   * Test whether the AVT is insensitive to the context in which
+   *  it is being evaluated. This is intended to facilitate
+   *  compilation of templates, by allowing simple AVTs to be
+   *  converted back into strings.
+   *
+   *  Currently the only case we recognize is simple strings.
+   * ADDED 9/5/2000 to support compilation experiment
+   *
+   * @return True if the m_simpleString member of this AVT is not null
+   */
+  public boolean isContextInsensitive()
+  {
+    return null != m_simpleString;
+  }
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+
+    if (null != m_parts)
+    {
+      int n = m_parts.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        AVTPart part = (AVTPart) m_parts.elementAt(i);
+
+        if (part.canTraverseOutsideSubtree())
+          return true;
+      }
+    }
+
+    return false;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    if (null != m_parts)
+    {
+      int n = m_parts.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        AVTPart part = (AVTPart) m_parts.elementAt(i);
+
+        part.fixupVariables(vars, globalsSize);
+      }
+    }
+  }
+  
+  /**
+   * @see XSLTVisitable#callVisitors(XSLTVisitor)
+   */
+  public void callVisitors(XSLTVisitor visitor)
+  {
+  	if(visitor.visitAVT(this) && (null != m_parts))
+  	{
+      int n = m_parts.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        AVTPart part = (AVTPart) m_parts.elementAt(i);
+
+        part.callVisitors(visitor);
+      }  		
+  	}
+  }
+
+
+  /**
+   * Returns true if this AVT is simple
+   */
+  public boolean isSimple() {
+  	return m_simpleString != null;
+  }
+  
+  private final FastStringBuffer getBuffer(){
+    if(USE_OBJECT_POOL){
+      return StringBufferPool.get();
+    }else{
+      return new FastStringBuffer(INIT_BUFFER_CHUNK_BITS);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/AVTPart.java b/src/main/java/org/apache/xalan/templates/AVTPart.java
new file mode 100644
index 0000000..4d9a02d
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/AVTPart.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AVTPart.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Class to hold a part, either a string or XPath,
+ * of an Attribute Value Template.
+ * @xsl.usage internal
+ */
+public abstract class AVTPart implements java.io.Serializable, XSLTVisitable
+{
+    static final long serialVersionUID = -1747749903613916025L;
+
+  /**
+   * Construct a part.
+   */
+  public AVTPart(){}
+
+  /**
+   * Get the AVT part as the original string.
+   *
+   * @return the AVT part as the original string.
+   */
+  public abstract String getSimpleString();
+
+  /**
+   * Write the evaluated value into the given
+   * string buffer.
+   *
+   * @param xctxt The XPath context to use to evaluate this AVT.
+   * @param buf Buffer to write into.
+   * @param context The current source tree context.
+   * @param nsNode The current namespace context (stylesheet tree context).
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public abstract void evaluate(
+    XPathContext xctxt, FastStringBuffer buf, int context,
+      org.apache.xml.utils.PrefixResolver nsNode)
+        throws javax.xml.transform.TransformerException;
+
+  /**
+   * Set the XPath support.
+   *
+   * @param support XPathContext to set. 
+   */
+  public void setXPathSupport(XPathContext support){}
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    return false;
+   }
+   
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public abstract void fixupVariables(java.util.Vector vars, int globalsSize);
+
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/AVTPartSimple.java b/src/main/java/org/apache/xalan/templates/AVTPartSimple.java
new file mode 100644
index 0000000..0e489d3
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/AVTPartSimple.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AVTPartSimple.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Simple string part of a complex AVT.
+ * @xsl.usage internal
+ */
+public class AVTPartSimple extends AVTPart
+{
+    static final long serialVersionUID = -3744957690598727913L;
+
+  /**
+   * Simple string value;
+   * @serial
+   */
+  private String m_val;
+
+  /**
+   * Construct a simple AVT part.
+   * @param val A pure string section of an AVT.
+   */
+  public AVTPartSimple(String val)
+  {
+    m_val = val;
+  }
+
+  /**
+   * Get the AVT part as the original string.
+   *
+   * @return the AVT part as the original string.
+   */
+  public String getSimpleString()
+  {
+    return m_val;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+
+  /**
+   * Write the value into the buffer.
+   *
+   * @param xctxt An XPathContext object, providing infomation specific
+   * to this invocation and this thread. Maintains SAX state, variables, 
+   * error handler and  so on, so the transformation/XPath object itself
+   * can be simultaneously invoked from multiple threads.
+   * @param buf Buffer to write into.
+   * @param context The current source tree context.
+   * @param nsNode The current namespace context (stylesheet tree context).
+   */
+  public void evaluate(XPathContext xctxt, FastStringBuffer buf,
+                       int context,
+                       org.apache.xml.utils.PrefixResolver nsNode)
+  {
+    buf.append(m_val);
+  }
+  /**
+   * @see XSLTVisitable#callVisitors(XSLTVisitor)
+   */
+  public void callVisitors(XSLTVisitor visitor)
+  {
+  	// Don't do anything for the subpart for right now.
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/AVTPartXPath.java b/src/main/java/org/apache/xalan/templates/AVTPartXPath.java
new file mode 100644
index 0000000..dde5f31
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/AVTPartXPath.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AVTPartXPath.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathFactory;
+import org.apache.xpath.compiler.XPathParser;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Simple string part of a complex AVT.
+ * @xsl.usage internal
+ */
+public class AVTPartXPath extends AVTPart
+{
+    static final long serialVersionUID = -4460373807550527675L;
+
+  /**
+   * The XPath object contained in this part.
+   * @serial
+   */
+  private XPath m_xpath;
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_xpath.fixupVariables(vars, globalsSize);
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    return m_xpath.getExpression().canTraverseOutsideSubtree();
+   }
+
+  /**
+   * Construct a simple AVT part.
+   *
+   * @param xpath Xpath section of AVT 
+   */
+  public AVTPartXPath(XPath xpath)
+  {
+    m_xpath = xpath;
+  }
+
+  /**
+   * Construct a simple AVT part.
+   * 
+   * @param val A pure string section of an AVT.
+   * @param nsNode An object which can be used to determine the
+   * Namespace Name (URI) for any Namespace prefix used in the XPath. 
+   * Usually this is based on the context where the XPath was specified,
+   * such as a node within a Stylesheet.
+   * @param xpathProcessor XPath parser
+   * @param factory XPath factory
+   * @param liaison An XPathContext object, providing infomation specific
+   * to this invocation and this thread. Maintains SAX output state, 
+   * variables, error handler and so on, so the transformation/XPath 
+   * object itself can be simultaneously invoked from multiple threads.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * TODO: Fix or remove this unused c'tor.
+   */
+  public AVTPartXPath(
+          String val, org.apache.xml.utils.PrefixResolver nsNode, 
+          XPathParser xpathProcessor, XPathFactory factory, 
+          XPathContext liaison)
+            throws javax.xml.transform.TransformerException
+  {
+    m_xpath = new XPath(val, null, nsNode, XPath.SELECT, liaison.getErrorListener());
+  }
+
+  /**
+   * Get the AVT part as the original string.
+   *
+   * @return the AVT part as the original string.
+   */
+  public String getSimpleString()
+  {
+    return "{" + m_xpath.getPatternString() + "}";
+  }
+
+  /**
+   * Write the value into the buffer.
+   *
+   * @param xctxt An XPathContext object, providing infomation specific
+   * to this invocation and this thread. Maintains SAX state, variables, 
+   * error handler and  so on, so the transformation/XPath object itself
+   * can be simultaneously invoked from multiple threads.
+   * @param buf Buffer to write into.
+   * @param context The current source tree context.
+   * @param nsNode The current namespace context (stylesheet tree context).
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void evaluate(
+          XPathContext xctxt, FastStringBuffer buf, int context, org.apache.xml.utils.PrefixResolver nsNode)
+            throws javax.xml.transform.TransformerException
+  {
+
+    XObject xobj = m_xpath.execute(xctxt, context, nsNode);
+
+    if (null != xobj)
+    {
+      xobj.appendToFsb(buf);
+    }
+  }
+  
+  /**
+   * @see XSLTVisitable#callVisitors(XSLTVisitor)
+   */
+  public void callVisitors(XSLTVisitor visitor)
+  {
+  	m_xpath.getExpression().callVisitors(m_xpath, visitor);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/AbsPathChecker.java b/src/main/java/org/apache/xalan/templates/AbsPathChecker.java
new file mode 100644
index 0000000..9303d30
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/AbsPathChecker.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AbsPathChecker.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.axes.LocPathIterator;
+import org.apache.xpath.functions.FuncCurrent;
+import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * This class runs over a path expression that is assumed to be absolute, and 
+ * checks for variables and the like that may make it context dependent.
+ */
+public class AbsPathChecker extends XPathVisitor
+{
+	private boolean m_isAbs = true;
+	
+	/**
+	 * Process the LocPathIterator to see if it contains variables 
+	 * or functions that may make it context dependent.
+	 * @param path LocPathIterator that is assumed to be absolute, but needs checking.
+	 * @return true if the path is confirmed to be absolute, false if it 
+	 * may contain context dependencies.
+	 */
+	public boolean checkAbsolute(LocPathIterator path)
+	{
+		m_isAbs = true;
+		path.callVisitors(null, this);
+		return m_isAbs;
+	}
+	
+	/**
+	 * Visit a function.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param func The function reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitFunction(ExpressionOwner owner, Function func)
+	{
+		if((func instanceof FuncCurrent) ||
+		   (func instanceof FuncExtFunction))
+			m_isAbs = false;
+		return true;
+	}
+	
+	/**
+	 * Visit a variable reference.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param var The variable reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitVariableRef(ExpressionOwner owner, Variable var)
+	{
+		m_isAbs = false;
+		return true;
+	}
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/Constants.java b/src/main/java/org/apache/xalan/templates/Constants.java
new file mode 100644
index 0000000..717fa35
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/Constants.java
@@ -0,0 +1,399 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Constants.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+
+/**
+ * Primary constants used in the TransformerImpl classes.
+ * @xsl.usage advanced
+ */
+public class Constants extends org.apache.xml.utils.Constants
+{
+
+  /**
+   * IDs for XSL element types. These are associated
+   * with the string literals in the TransformerImpl class.
+   * Don't change the numbers. NOTE THAT THESE ARE NOT IN
+   * ALPHABETICAL ORDER!
+   * (It's a pity Java doesn't have a real Enumerated Mnemonic
+   * datatype... or a C-like preprocessor in lieu thereof which
+   * could be used to generate and maintain synch between these lists.)
+   */
+  public static final int ELEMNAME_UNDEFINED = -1, ELEMNAME_WITHPARAM = 2,
+                          ELEMNAME_ADDATTRIBUTE = 4, ELEMNAME_ANCHOR = 22,
+
+  //  ELEMNAME_ANCHOR_PATTERN = 23,
+  ELEMNAME_APPLY_TEMPLATES = 50, ELEMNAME_USE = 34, ELEMNAME_CHILDREN = 6,
+                                 ELEMNAME_CHOOSE = 37, ELEMNAME_COMMENT = 59,  // my own
+                                 ELEMNAME_CONSTRUCT = 7,  // my own
+                                 ELEMNAME_CONTENTS = 8, ELEMNAME_COPY = 9,
+                                 ELEMNAME_COPY_OF = 74,
+                                 ELEMNAME_DECIMALFORMAT = 83,
+                                 ELEMNAME_DEFINEATTRIBUTESET = 40,
+
+  //  ELEMNAME_DEFINECONSTANT = 29,
+  //  ELEMNAME_DEFINEMACRO = 10,
+  ELEMNAME_DEFINESCRIPT = 11, ELEMNAME_DISPLAYIF = 12,  // my own
+                              ELEMNAME_EMPTY = 14, ELEMNAME_EVAL = 15,
+                              ELEMNAME_EXPECTEDCHILDREN = 16,
+                              ELEMNAME_EXTENSION = 54,
+                              ELEMNAME_EXTENSIONHANDLER = 63,
+                              ELEMNAME_FOREACH = 28, ELEMNAME_KEY = 31,
+                              ELEMNAME_IF = 36, ELEMNAME_IMPORT = 26,
+                              ELEMNAME_INCLUDE = 27,
+                              ELEMNAME_CALLTEMPLATE = 17,
+                              ELEMNAME_PARAMVARIABLE = 41,
+                              ELEMNAME_NUMBER = 35, ELEMNAME_NSALIAS = 84,
+                              ELEMNAME_OTHERWISE = 39, ELEMNAME_PI = 58,
+                              ELEMNAME_PRESERVESPACE = 33,
+                              ELEMNAME_REMOVEATTRIBUTE = 5,
+                              ELEMNAME_TEMPLATE = 19, ELEMNAME_SORT = 64,
+                              ELEMNAME_STRIPSPACE = 32,
+                              ELEMNAME_STYLESHEET = 25, ELEMNAME_TEXT = 42,
+                              ELEMNAME_VALUEOF = 30, ELEMNAME_WHEN = 38,
+
+  // Pattern by example support  
+  ELEMNAME_ROOT = 44, ELEMNAME_ANY = 45, ELEMNAME_ELEMENT = 46,
+                      ELEMNAME_TARGETELEMENT = 47, ELEMNAME_ATTRIBUTE = 48,
+                      ELEMNAME_TARGETATTRIBUTE = 49, ELEMNAME_URL = 52,  // my own
+                      ELEMNAME_CALL = 55,  // my own
+
+  //  ELEMNAME_WITHPARAM = 56,
+  ELEMNAME_FALLBACK = 57,  // my own
+  ELEMNAME_TARGETPI = 60,  // my own
+  ELEMNAME_TARGETCOMMENT = 61,  // my own
+  ELEMNAME_TARGETTEXT = 62,  // my own
+  ELEMNAME_CSSSTYLECONVERSION = 65,  // my own
+  ELEMNAME_COUNTER = 66, ELEMNAME_COUNTERS = 67,
+  ELEMNAME_COUNTERINCREMENT = 68, ELEMNAME_COUNTERRESET = 69,
+  ELEMNAME_COUNTERSCOPE = 71, ELEMNAME_APPLY_IMPORTS = 72,
+  ELEMNAME_VARIABLE = 73, ELEMNAME_MESSAGE = 75, ELEMNAME_LOCALE = 76,
+  ELEMNAME_LITERALRESULT = 77, ELEMNAME_TEXTLITERALRESULT = 78,
+  ELEMNAME_EXTENSIONCALL = 79, ELEMNAME_EXTENSIONDECL = 85,
+  ELEMNAME_EXTENSIONSCRIPT = 86, ELEMNAME_OUTPUT = 80,
+  ELEMNAME_COMPONENT = 81, ELEMNAME_SCRIPT = 82;
+
+  // Next free number: 90 (88 and 89 used for EXSLT elements);
+
+  /**
+   * Literals for XSL element names.  Note that there are more
+   * names than IDs, because some names map to the same ID.
+   */
+  public static final String       
+	  ELEMNAME_ANCHOR_STRING = "anchor",
+      ELEMNAME_ANY_STRING = "any",  // pattern-by-example support
+      ELEMNAME_APPLY_IMPORTS_STRING = "apply-imports",
+      ELEMNAME_APPLY_TEMPLATES_STRING = "apply-templates",
+      ELEMNAME_ARG_STRING = "arg",
+      ELEMNAME_ATTRIBUTESET_STRING = "attribute-set",
+      ELEMNAME_ATTRIBUTE_STRING = "attribute",  // pattern-by-example support
+      ELEMNAME_CALLTEMPLATEARG_STRING = "invoke-arg",
+      ELEMNAME_CALLTEMPLATE_STRING = "call-template",
+      ELEMNAME_CALL_STRING = "call",
+      ELEMNAME_CHILDREN_STRING = "children",
+      ELEMNAME_CHOOSE_STRING = "choose",
+      ELEMNAME_COMMENT_STRING = "comment",
+      ELEMNAME_COMPONENT_STRING = "component",
+      ELEMNAME_CONSTRUCT_STRING = "construct",  // my own
+      ELEMNAME_CONTENTS_STRING = "contents", 
+      ELEMNAME_COPY_OF_STRING ="copy-of",
+      ELEMNAME_COPY_STRING = "copy",
+      ELEMNAME_COUNTERINCREMENT_STRING = "counter-increment",
+      ELEMNAME_COUNTERRESET_STRING = "counter-reset",
+      ELEMNAME_COUNTERSCOPE_STRING = "counter-scope",
+      ELEMNAME_COUNTERS_STRING = "counters",
+      ELEMNAME_COUNTER_STRING = "counter",
+      ELEMNAME_CSSSTYLECONVERSION_STRING = "css-style-conversion",
+      ELEMNAME_DECIMALFORMAT_STRING = "decimal-format",
+      ELEMNAME_DISPLAYIF_STRING = "display-if",  // my own
+      ELEMNAME_ELEMENT_STRING = "element",  // pattern-by-example support
+      ELEMNAME_EMPTY_STRING = "empty",
+      ELEMNAME_EVAL_STRING = "eval",
+      ELEMNAME_EXPECTEDCHILDREN_STRING = "expectedchildren",
+      ELEMNAME_EXTENSIONHANDLER_STRING = "code-dispatcher",
+      ELEMNAME_EXTENSION_STRING = "functions",
+      ELEMNAME_FALLBACK_STRING = "fallback",
+      ELEMNAME_FOREACH_STRING = "for-each",
+      ELEMNAME_IF_STRING = "if",
+      ELEMNAME_IMPORT_STRING = "import",
+      ELEMNAME_INCLUDE_STRING = "include",
+      ELEMNAME_KEY_STRING = "key",
+      ELEMNAME_LOCALE_STRING = "locale",
+      ELEMNAME_MESSAGE_STRING = "message",
+      ELEMNAME_NSALIAS_STRING = "namespace-alias",
+      ELEMNAME_NUMBER_STRING = "number",
+      ELEMNAME_OTHERWISE_STRING = "otherwise",
+      ELEMNAME_OUTPUT_STRING = "output",
+      ELEMNAME_PARAMVARIABLE_STRING = "param",
+      ELEMNAME_PI_OLD_STRING = "pi",
+      ELEMNAME_PI_STRING = "processing-instruction",
+      ELEMNAME_PRESERVESPACE_STRING = "preserve-space",
+      ELEMNAME_ROOT_STRING = "root",  // pattern-by-example support
+      ELEMNAME_SCRIPT_STRING = "script",
+      ELEMNAME_SORT_STRING = "sort",
+      ELEMNAME_STRIPSPACE_STRING = "strip-space",
+      ELEMNAME_STYLESHEET_STRING = "stylesheet",
+      ELEMNAME_TARGETATTRIBUTE_STRING = "target-attribute",  // pattern-by-example support
+      ELEMNAME_TARGETCOMMENT_STRING = "target-comment",
+      ELEMNAME_TARGETELEMENT_STRING = "target-element",  // pattern-by-example support
+      ELEMNAME_TARGETPI_STRING = "target-pi",
+      ELEMNAME_TARGETTEXT_STRING = "target-text",
+      ELEMNAME_TEMPLATE_STRING = "template",
+      ELEMNAME_TEXT_STRING = "text",
+      ELEMNAME_TRANSFORM_STRING = "transform",
+      ELEMNAME_URL_STRING = "uri",  // pattern-by-example support
+      ELEMNAME_USE_STRING = "use",
+      ELEMNAME_VALUEOF_STRING = "value-of",
+      ELEMNAME_VARIABLE_STRING = "variable",
+      ELEMNAME_WHEN_STRING = "when",
+      ELEMNAME_WITHPARAM_STRING = "with-param";
+  
+  /**
+   * Literals for EXSLT function elements.
+   */
+  public static final String
+    EXSLT_ELEMNAME_FUNCTION_STRING = "function",
+    EXSLT_ELEMNAME_FUNCRESULT_STRING = "result";
+  public static final int
+    EXSLT_ELEMNAME_FUNCTION = 88,
+    EXSLT_ELEMNAME_FUNCRESULT = 89;
+  
+  
+  /**
+   * Literals for XSL attribute names.  Note that there may be more
+   * names than IDs, because some names may map to the same ID.
+   */
+  public static final String
+	  ATTRNAME_AMOUNT = "amount",
+      ATTRNAME_ANCESTOR = "ancestor",
+      ATTRNAME_ARCHIVE = "archive",
+      ATTRNAME_ATTRIBUTE = "attribute",
+      ATTRNAME_ATTRIBUTE_SET = "attribute-set",
+      ATTRNAME_CASEORDER = "case-order",
+      ATTRNAME_CLASS = "class",
+      ATTRNAME_CLASSID = "classid",
+      ATTRNAME_CODEBASE = "codebase",
+      ATTRNAME_CODETYPE = "type",
+      ATTRNAME_CONDITION = "condition",
+      ATTRNAME_COPYTYPE = "copy-type",
+      ATTRNAME_COUNT = "count",
+      ATTRNAME_DATATYPE = "data-type",
+      ATTRNAME_DECIMALSEPARATOR = "decimal-separator",
+      ATTRNAME_DEFAULT = "default",
+      ATTRNAME_DEFAULTSPACE = "default-space",
+      ATTRNAME_DEPTH = "with-children",
+      ATTRNAME_DIGIT = "digit",
+      ATTRNAME_DIGITGROUPSEP = "digit-group-sep",
+      ATTRNAME_DISABLE_OUTPUT_ESCAPING = "disable-output-escaping",
+      ATTRNAME_ELEMENT = "element",
+      ATTRNAME_ELEMENTS = "elements",
+      ATTRNAME_EXCLUDE_RESULT_PREFIXES ="exclude-result-prefixes",
+      ATTRNAME_EXPR = "expr",
+      ATTRNAME_EXTENSIONELEMENTPREFIXES = "extension-element-prefixes",
+      ATTRNAME_FORMAT = "format",
+      ATTRNAME_FROM = "from",
+      ATTRNAME_GROUPINGSEPARATOR = "grouping-separator",
+      ATTRNAME_GROUPINGSIZE = "grouping-size",
+      ATTRNAME_HREF = "href",
+      ATTRNAME_ID = "id",
+      ATTRNAME_IMPORTANCE = "importance",
+      ATTRNAME_INDENTRESULT = "indent-result",
+      ATTRNAME_INFINITY = "infinity",
+      ATTRNAME_LANG = "lang",
+      ATTRNAME_LETTERVALUE = "letter-value",
+      ATTRNAME_LEVEL = "level",
+      ATTRNAME_MATCH = "match",
+      ATTRNAME_METHOD = "calls",
+      ATTRNAME_MINUSSIGN = "minus-sign",
+      ATTRNAME_MODE = "mode",
+      ATTRNAME_NAME = "name",
+      ATTRNAME_NAMESPACE = "namespace",
+      ATTRNAME_NAN = "NaN",
+      ATTRNAME_NDIGITSPERGROUP = "n-digits-per-group",
+      ATTRNAME_NS = "ns",
+      ATTRNAME_ONLY = "only",
+      ATTRNAME_ORDER = "order",
+      ATTRNAME_OUTPUT_CDATA_SECTION_ELEMENTS = "cdata-section-elements",
+      ATTRNAME_OUTPUT_DOCTYPE_PUBLIC = "doctype-public",
+      ATTRNAME_OUTPUT_DOCTYPE_SYSTEM = "doctype-system",
+      ATTRNAME_OUTPUT_ENCODING = "encoding",
+      ATTRNAME_OUTPUT_INDENT = "indent",
+      ATTRNAME_OUTPUT_MEDIATYPE = "media-type",
+      ATTRNAME_OUTPUT_METHOD = "method",  // qname, 
+      ATTRNAME_OUTPUT_OMITXMLDECL = "omit-xml-declaration",
+      ATTRNAME_OUTPUT_STANDALONE = "standalone",
+      ATTRNAME_OUTPUT_VERSION = "version",
+      ATTRNAME_PATTERNSEPARATOR = "pattern-separator",
+      ATTRNAME_PERCENT = "percent",
+      ATTRNAME_PERMILLE = "per-mille",
+      ATTRNAME_PRIORITY = "priority",
+      ATTRNAME_REFID = "refID",
+      ATTRNAME_RESULTNS = "result-ns",
+      ATTRNAME_RESULT_PREFIX = "result-prefix",
+      ATTRNAME_SELECT = "select",
+      ATTRNAME_SEQUENCESRC = "sequence-src",
+      ATTRNAME_STYLE = "style",
+      ATTRNAME_STYLESHEET_PREFIX = "stylesheet-prefix",
+      ATTRNAME_TERMINATE = "terminate",
+      ATTRNAME_TEST = "test",
+      ATTRNAME_TOSTRING = "to-string",
+      ATTRNAME_TYPE = "type",
+      ATTRNAME_USE = "use",
+      ATTRNAME_USEATTRIBUTESETS = "use-attribute-sets",
+      ATTRNAME_VALUE = "value",
+      ATTRNAME_VERSION = "version",
+      ATTRNAME_XMLNS = "xmlns:", // namespace declaration prefix -- NOT an attribute by itself
+      ATTRNAME_XMLNSDEF = "xmlns", // default namespace
+      ATTRNAME_XMLSPACE = "xml:space", 
+      ATTRNAME_ZERODIGIT = "zero-digit";
+
+  /** IDs for XSL attribute types. These are associated
+   * with the string literals in the TransformerImpl class.
+   * Don't change the numbers. NOTE THAT THESE ARE NOT IN
+   * ALPHABETICAL ORDER!
+   */
+  public static final int TATTRNAME_OUTPUT_METHOD = 1, TATTRNAME_AMOUNT = 2,
+                          TATTRNAME_ANCESTOR = 3, TATTRNAME_ARCHIVE = 4,
+                          TATTRNAME_ATTRIBUTE = 5,
+                          TATTRNAME_ATTRIBUTE_SET = 6,
+                          TATTRNAME_CASEORDER = 7, TATTRNAME_CLASS = 8,
+                          TATTRNAME_CLASSID = 9, TATTRNAME_CODEBASE = 10,
+                          TATTRNAME_CODETYPE = 11, TATTRNAME_CONDITION = 12,
+                          TATTRNAME_COPYTYPE = 13, TATTRNAME_COUNT = 14,
+                          TATTRNAME_DATATYPE = 15, TATTRNAME_DEFAULT = 16,
+                          TATTRNAME_DEFAULTSPACE = 17, TATTRNAME_DEPTH = 18,
+                          TATTRNAME_DIGITGROUPSEP = 19,
+                          TATTRNAME_DISABLE_OUTPUT_ESCAPING = 20,
+                          TATTRNAME_ELEMENT = 21, TATTRNAME_ELEMENTS = 22,
+                          TATTRNAME_EXPR = 23,
+                          TATTRNAME_EXTENSIONELEMENTPREFIXES = 24,
+                          TATTRNAME_FORMAT = 25, TATTRNAME_FROM = 26,
+                          TATTRNAME_GROUPINGSEPARATOR = 27,
+                          TATTRNAME_GROUPINGSIZE = 28, TATTRNAME_HREF = 29,
+                          TATTRNAME_ID = 30, TATTRNAME_IMPORTANCE = 31,
+                          TATTRNAME_INDENTRESULT = 32, TATTRNAME_LANG = 33,
+                          TATTRNAME_LETTERVALUE = 34, TATTRNAME_LEVEL = 35,
+                          TATTRNAME_MATCH = 36, TATTRNAME_METHOD = 37,
+                          TATTRNAME_MODE = 38, TATTRNAME_NAME = 39,
+                          TATTRNAME_NAMESPACE = 40,
+                          TATTRNAME_NDIGITSPERGROUP = 41, TATTRNAME_NS = 42,
+                          TATTRNAME_ONLY = 43, TATTRNAME_ORDER = 44,
+                          TATTRNAME_OUTPUT_CDATA_SECTION_ELEMENTS = 45,
+                          TATTRNAME_OUTPUT_DOCTYPE_PUBLIC = 46,
+                          TATTRNAME_OUTPUT_DOCTYPE_SYSTEM = 47,
+                          TATTRNAME_OUTPUT_ENCODING = 48,
+                          TATTRNAME_OUTPUT_INDENT = 49,
+                          TATTRNAME_OUTPUT_MEDIATYPE = 50,
+                          TATTRNAME_OUTPUT_STANDALONE = 51,
+                          TATTRNAME_OUTPUT_VERSION = 52,
+                          TATTRNAME_OUTPUT_OMITXMLDECL = 53,
+                          TATTRNAME_PRIORITY = 54, TATTRNAME_REFID = 55,
+                          TATTRNAME_RESULTNS = 56, TATTRNAME_SELECT = 57,
+                          TATTRNAME_SEQUENCESRC = 58, TATTRNAME_STYLE = 59,
+                          TATTRNAME_TEST = 60, TATTRNAME_TOSTRING = 61,
+                          TATTRNAME_TYPE = 62, TATTRNAME_USE = 63,
+                          TATTRNAME_USEATTRIBUTESETS = 64,
+                          TATTRNAME_VALUE = 65, TATTRNAME_XMLNSDEF = 66,
+                          TATTRNAME_XMLNS = 67, TATTRNAME_XMLSPACE = 68,
+                          TATTRNAME_EXCLUDE_RESULT_PREFIXES = 69;
+
+  /** Mnemonics for the possible values of the xsl:output element's
+   * method= attribute:
+   * <ul>
+   * <li>ATTRVAL_OUTPUT_METHOD_XML = Use an XML formatter to
+   * produce the output document (basic XSLT operation).</li>
+   * <li>ATTRVAL_OUTPUT_METHOD_HTML: Use an HTML formatter to
+   * produce the output document. When generating HTML documents,
+   * this may yield better results; it does things like escaping
+   * characters in href attributes.</li>
+   * </li>ATTRVAL_OUTPUT_METHOD_TEXT:  Use a Text formatter to
+   * produce the output document. Generally the right choice if your
+   * stylesheet wants to take over _all_ the details of formatting,
+   * most often when producing something that isn't an XML or HTML
+   * document.</li>
+   * </ul> 
+   * */
+  public static final String ATTRVAL_OUTPUT_METHOD_HTML = "html",
+                             ATTRVAL_OUTPUT_METHOD_XML = "xml",
+                             ATTRVAL_OUTPUT_METHOD_TEXT = "text";
+
+  
+  /* For space-att*/
+  public static final int ATTRVAL_PRESERVE = 1, ATTRVAL_STRIP = 2;
+
+  
+  /** For indent-result          */
+  public static final boolean ATTRVAL_YES = true, ATTRVAL_NO = false;
+
+  
+  /** For letter-value attribute (part of conversion attributes).          */
+  public static final String ATTRVAL_ALPHABETIC = "alphabetic",
+                             ATTRVAL_OTHER = "other",
+                             ATTRVAL_TRADITIONAL = "traditional";
+
+  
+  /** For level attribute in xsl:number.          */
+  public static final String ATTRVAL_SINGLE = "single",
+                             ATTRVAL_MULTI = "multiple", ATTRVAL_ANY = "any";
+
+  
+  /** For Stylesheet-prefix and result-prefix in xsl:namespace-alias          */
+  public static final String ATTRVAL_DEFAULT_PREFIX = "#default";
+
+ /** Integer equivalents for above        */
+  public static final int NUMBERLETTER_ALPHABETIC = 1, NUMBERLETTER_TRADITIONAL = 2;
+  
+  /** Integer equivelents for above        */
+  public static final int NUMBERLEVEL_SINGLE = 1, NUMBERLEVEL_MULTI = 2,
+                          NUMBERLEVEL_ANY = 3, MAX_MULTI_COUNTING_DEPTH = 32;
+
+  
+  /** some stuff for my patterns-by-example         */
+  public static final String ATTRVAL_THIS = ".", ATTRVAL_PARENT = "..",
+                             ATTRVAL_ANCESTOR = "ancestor", ATTRVAL_ID = "id";
+
+  
+  /** Stuff for sorting      */
+  public static final String ATTRVAL_DATATYPE_TEXT = "text",
+                             ATTRVAL_DATATYPE_NUMBER = "number",
+                             ATTRVAL_ORDER_ASCENDING = "ascending",
+                             ATTRVAL_ORDER_DESCENDING = "descending",
+                             ATTRVAL_CASEORDER_UPPER = "upper-first",
+                             ATTRVAL_CASEORDER_LOWER = "lower-first";
+
+ /** Integer equivelents for DATATYPE attribute */
+  public static final int SORTDATATYPE_TEXT = 1, SORTDATATYPE_NUMBER = 2;
+
+  /** Integer equivelents for ORDER attribute */
+  public static final int SORTORDER_ASCENDING = 1, SORTORDER_DESCENDING = 2;
+  
+  /** Integer equivelents for CASE-ORDER attribute */
+  public static final int SORTCASEORDER_UPPERFIRST = 1, SORTCASEORDER_LOWERFIRST = 2;
+  
+  /** some stuff for Decimal-format       */
+  public static final String ATTRVAL_INFINITY = "Infinity",
+                             ATTRVAL_NAN = "NaN",
+                             DEFAULT_DECIMAL_FORMAT = "#default";
+
+  
+  /** temp dummy         */
+  public static final String ATTRNAME_XXXX = "XXXX";
+}
diff --git a/src/main/java/org/apache/xalan/templates/DecimalFormatProperties.java b/src/main/java/org/apache/xalan/templates/DecimalFormatProperties.java
new file mode 100644
index 0000000..7291484
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/DecimalFormatProperties.java
@@ -0,0 +1,404 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DecimalFormatProperties.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.text.DecimalFormatSymbols;
+
+import org.apache.xml.utils.QName;
+
+/**
+ * Implement xsl:decimal-format.
+ * <pre>
+ * <!ELEMENT xsl:decimal-format EMPTY>
+ * <!ATTLIST xsl:decimal-format
+ *   name %qname; #IMPLIED
+ *   decimal-separator %char; "."
+ *   grouping-separator %char; ","
+ *   infinity CDATA "Infinity"
+ *   minus-sign %char; "-"
+ *   NaN CDATA "NaN"
+ *   percent %char; "%"
+ *   per-mille %char; "&#x2030;"
+ *   zero-digit %char; "0"
+ *   digit %char; "#"
+ *   pattern-separator %char; ";"
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class DecimalFormatProperties extends ElemTemplateElement
+{
+    static final long serialVersionUID = -6559409339256269446L;
+
+  /** An instance of DecimalFormatSymbols for this element.
+   *  @serial       */
+  DecimalFormatSymbols m_dfs;
+
+  /**
+   * Constructor DecimalFormatProperties
+   *
+   */
+  public DecimalFormatProperties(int docOrderNumber)
+  {
+
+    m_dfs = new java.text.DecimalFormatSymbols();
+
+    // Set default values, they can be overiden if necessary.  
+    m_dfs.setInfinity(Constants.ATTRVAL_INFINITY);
+    m_dfs.setNaN(Constants.ATTRVAL_NAN);
+
+    m_docOrderNumber = docOrderNumber;
+  }
+
+  /**
+   * Return the decimal format Symbols for this element.
+   * <p>The xsl:decimal-format element declares a decimal-format,
+   * which controls the interpretation of a format pattern used by
+   * the format-number function. If there is a name attribute, then
+   * the element declares a named decimal-format; otherwise, it
+   * declares the default decimal-format. The value of the name
+   * attribute is a QName, which is expanded as described in [2.4 Qualified Names].
+   * It is an error to declare either the default decimal-format or a
+   * decimal-format with a given name more than once (even with different
+   * import precedence), unless it is declared every time with the same
+   * value for all attributes (taking into account any default values).</p>
+   * <p>The other attributes on xsl:decimal-format correspond to the
+   * methods on the JDK 1.1 DecimalFormatSymbols class. For each get/set
+   * method pair there is an attribute defined for the xsl:decimal-format
+   * element.</p>
+   *
+   * @return the decimal format Symbols for this element.
+   */
+  public DecimalFormatSymbols getDecimalFormatSymbols()
+  {
+    return m_dfs;
+  }
+
+  /**
+   * If there is a name attribute, then the element declares a named
+   * decimal-format; otherwise, it declares the default decimal-format.
+   * @serial
+   */
+  private QName m_qname = null;
+
+  /**
+   * Set the "name" attribute.
+   * If there is a name attribute, then the element declares a named
+   * decimal-format; otherwise, it declares the default decimal-format.
+   *
+   * @param qname The name to set as the "name" attribute.
+   */
+  public void setName(QName qname)
+  {
+    m_qname = qname;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * If there is a name attribute, then the element declares a named
+   * decimal-format; otherwise, it declares the default decimal-format.
+   *
+   * @return the value of the "name" attribute.
+   */
+  public QName getName()
+  {
+
+    if (m_qname == null)
+      return new QName("");
+    else
+      return m_qname;
+  }
+
+  /**
+   * Set the "decimal-separator" attribute.
+   * decimal-separator specifies the character used for the decimal sign;
+   * the default value is the period character (.).
+   *
+   * @param ds Character to set as decimal separator 
+   */
+  public void setDecimalSeparator(char ds)
+  {
+    m_dfs.setDecimalSeparator(ds);
+  }
+
+  /**
+   * Get the "decimal-separator" attribute.
+   * decimal-separator specifies the character used for the decimal sign;
+   * the default value is the period character (.).
+   *
+   * @return the character to use as decimal separator
+   */
+  public char getDecimalSeparator()
+  {
+    return m_dfs.getDecimalSeparator();
+  }
+
+  /**
+   * Set the "grouping-separator" attribute.
+   * grouping-separator specifies the character used as a grouping
+   * (e.g. thousands) separator; the default value is the comma character (,).
+   *
+   * @param gs Character to use a grouping separator 
+   */
+  public void setGroupingSeparator(char gs)
+  {
+    m_dfs.setGroupingSeparator(gs);
+  }
+
+  /**
+   * Get the "grouping-separator" attribute.
+   * grouping-separator specifies the character used as a grouping
+   * (e.g. thousands) separator; the default value is the comma character (,).
+   *
+   * @return Character to use a grouping separator 
+   */
+  public char getGroupingSeparator()
+  {
+    return m_dfs.getGroupingSeparator();
+  }
+
+  /**
+   * Set the "infinity" attribute.
+   * infinity specifies the string used to represent infinity;
+   * the default value is the string Infinity.
+   *
+   * @param inf String to use as the "infinity" attribute.
+   */
+  public void setInfinity(String inf)
+  {
+    m_dfs.setInfinity(inf);
+  }
+
+  /**
+   * Get the "infinity" attribute.
+   * infinity specifies the string used to represent infinity;
+   * the default value is the string Infinity.
+   *
+   * @return String to use as the "infinity" attribute.
+   */
+  public String getInfinity()
+  {
+    return m_dfs.getInfinity();
+  }
+
+  /**
+   * Set the "minus-sign" attribute.
+   * minus-sign specifies the character used as the default minus sign; the
+   * default value is the hyphen-minus character (-, #x2D).
+   *
+   * @param v Character to use as minus sign
+   */
+  public void setMinusSign(char v)
+  {
+    m_dfs.setMinusSign(v);
+  }
+
+  /**
+   * Get the "minus-sign" attribute.
+   * minus-sign specifies the character used as the default minus sign; the
+   * default value is the hyphen-minus character (-, #x2D).
+   *
+   * @return Character to use as minus sign
+   */
+  public char getMinusSign()
+  {
+    return m_dfs.getMinusSign();
+  }
+
+  /**
+   * Set the "NaN" attribute.
+   * NaN specifies the string used to represent the NaN value;
+   * the default value is the string NaN.
+   *
+   * @param v String to use as the "NaN" attribute.
+   */
+  public void setNaN(String v)
+  {
+    m_dfs.setNaN(v);
+  }
+
+  /**
+   * Get the "NaN" attribute.
+   * NaN specifies the string used to represent the NaN value;
+   * the default value is the string NaN.
+   *
+   * @return String to use as the "NaN" attribute.
+   */
+  public String getNaN()
+  {
+    return m_dfs.getNaN();
+  }
+  
+  /**
+   * Return the node name.
+   *
+   * @return the element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_DECIMALFORMAT_STRING;
+  }
+
+  /**
+   * Set the "percent" attribute.
+   * percent specifies the character used as a percent sign; the default
+   * value is the percent character (%).
+   *
+   * @param v Character to use as percent 
+   */
+  public void setPercent(char v)
+  {
+    m_dfs.setPercent(v);
+  }
+
+  /**
+   * Get the "percent" attribute.
+   * percent specifies the character used as a percent sign; the default
+   * value is the percent character (%).
+   *
+   * @return Character to use as percent 
+   */
+  public char getPercent()
+  {
+    return m_dfs.getPercent();
+  }
+
+  /**
+   * Set the "per-mille" attribute.
+   * per-mille specifies the character used as a per mille sign; the default
+   * value is the Unicode per-mille character (#x2030).
+   *
+   * @param v Character to use as per-mille
+   */
+  public void setPerMille(char v)
+  {
+    m_dfs.setPerMill(v);
+  }
+
+  /**
+   * Get the "per-mille" attribute.
+   * per-mille specifies the character used as a per mille sign; the default
+   * value is the Unicode per-mille character (#x2030).
+   *
+   * @return Character to use as per-mille 
+   */
+  public char getPerMille()
+  {
+    return m_dfs.getPerMill();
+  }
+  
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_DECIMALFORMAT;
+  }
+  
+  /**
+   * Set the "zero-digit" attribute.
+   * zero-digit specifies the character used as the digit zero; the default
+   * value is the digit zero (0).
+   *
+   * @param v Character to use as the digit zero
+   */
+  public void setZeroDigit(char v)
+  {
+    m_dfs.setZeroDigit(v);
+  }
+
+  /**
+   * Get the "zero-digit" attribute.
+   * zero-digit specifies the character used as the digit zero; the default
+   * value is the digit zero (0).
+   *
+   * @return Character to use as the digit zero
+   */
+  public char getZeroDigit()
+  {
+    return m_dfs.getZeroDigit();
+  }
+
+  /**
+   * Set the "digit" attribute.
+   * digit specifies the character used for a digit in the format pattern;
+   * the default value is the number sign character (#).
+   *
+   * @param v Character to use for a digit in format pattern
+   */
+  public void setDigit(char v)
+  {
+    m_dfs.setDigit(v);
+  }
+
+  /**
+   * Get the "digit" attribute.
+   * digit specifies the character used for a digit in the format pattern;
+   * the default value is the number sign character (#).
+   *
+   * @return Character to use for a digit in format pattern
+   */
+  public char getDigit()
+  {
+    return m_dfs.getDigit();
+  }
+
+  /**
+   * Set the "pattern-separator" attribute.
+   * pattern-separator specifies the character used to separate positive
+   * and negative sub patterns in a pattern; the default value is the
+   * semi-colon character (;).
+   *
+   * @param v Character to use as a pattern separator
+   */
+  public void setPatternSeparator(char v)
+  {
+    m_dfs.setPatternSeparator(v);
+  }
+
+  /**
+   * Get the "pattern-separator" attribute.
+   * pattern-separator specifies the character used to separate positive
+   * and negative sub patterns in a pattern; the default value is the
+   * semi-colon character (;).
+   *
+   * @return Character to use as a pattern separator
+   */
+  public char getPatternSeparator()
+  {
+    return m_dfs.getPatternSeparator();
+  }
+
+  /**
+   * This function is called to recompose() all of the decimal format properties elements.
+   * 
+   * @param root Stylesheet root
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeDecimalFormats(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemApplyImport.java b/src/main/java/org/apache/xalan/templates/ElemApplyImport.java
new file mode 100644
index 0000000..39b9919
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemApplyImport.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemApplyImport.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+
+/**
+ * Implement xsl:apply-imports.
+ * <pre>
+ * <!ELEMENT xsl:apply-imports EMPTY>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#apply-imports">apply-imports in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemApplyImport extends ElemTemplateElement
+{
+    static final long serialVersionUID = 3764728663373024038L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return Token ID for xsl:apply-imports element types
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_APPLY_IMPORTS;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return Element name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_APPLY_IMPORTS_STRING;
+  }
+
+  /**
+   * Execute the xsl:apply-imports transformation.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    if (transformer.currentTemplateRuleIsNull())
+    {
+      transformer.getMsgMgr().error(this,
+        XSLTErrorResources.ER_NO_APPLY_IMPORT_IN_FOR_EACH);  //"xsl:apply-imports not allowed in a xsl:for-each");
+    }
+
+    int sourceNode = transformer.getXPathContext().getCurrentNode();
+    if (DTM.NULL != sourceNode)
+    {
+      // supply the current templated (matched, not named)        
+      ElemTemplate matchTemplate = transformer.getMatchedTemplate();
+      transformer.applyTemplateToNode(this, matchTemplate, sourceNode);
+    }
+    else  // if(null == sourceNode)
+    {
+      transformer.getMsgMgr().error(this,
+        XSLTErrorResources.ER_NULL_SOURCENODE_APPLYIMPORTS);  //"sourceNode is null in xsl:apply-imports!");
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   * <!ELEMENT xsl:apply-imports EMPTY>
+   *
+   * @param newChild New element to append to this element's children list
+   *
+   * @return null, xsl:apply-Imports cannot have children 
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    error(XSLTErrorResources.ER_CANNOT_ADD,
+          new Object[]{ newChild.getNodeName(),
+                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    return null;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
new file mode 100644
index 0000000..e332ff0
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -0,0 +1,421 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemApplyTemplates.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement xsl:apply-templates.
+ * <pre>
+ * &amp;!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
+ * &amp;!ATTLIST xsl:apply-templates
+ *   select %expr; "node()"
+ *   mode %qname; #IMPLIED
+ * &amp;
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Applying-Template-Rules">section-Applying-Template-Rules in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemApplyTemplates extends ElemCallTemplate
+{
+    static final long serialVersionUID = 2903125371542621004L;
+
+  /**
+   * mode %qname; #IMPLIED
+   * @serial
+   */
+  private QName m_mode = null;
+
+  /**
+   * Set the mode attribute for this element.
+   *
+   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
+   */
+  public void setMode(QName mode)
+  {
+    m_mode = mode;
+  }
+
+  /**
+   * Get the mode attribute for this element.
+   *
+   * @return The mode attribute for this element
+   */
+  public QName getMode()
+  {
+    return m_mode;
+  }
+
+  /**
+   * Tells if this belongs to a default template,
+   * in which case it will act different with
+   * regard to processing modes.
+   * @see <a href="http://www.w3.org/TR/xslt#built-in-rule">built-in-rule in XSLT Specification</a>
+   * @serial
+   */
+  private boolean m_isDefaultTemplate = false;
+  
+//  /**
+//   * List of namespace/localname IDs, for identification of xsl:with-param to 
+//   * xsl:params.  Initialized in the compose() method.
+//   */
+//  private int[] m_paramIDs;
+
+  /**
+   * Set if this belongs to a default template,
+   * in which case it will act different with
+   * regard to processing modes.
+   * @see <a href="http://www.w3.org/TR/xslt#built-in-rule">built-in-rule in XSLT Specification</a>
+   *
+   * @param b boolean value to set.
+   */
+  public void setIsDefaultTemplate(boolean b)
+  {
+    m_isDefaultTemplate = b;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return Token ID for this element types
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_APPLY_TEMPLATES;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return Element name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_APPLY_TEMPLATES_STRING;
+  }
+
+  /**
+   * Apply the context node to the matching templates.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Applying-Template-Rules">section-Applying-Template-Rules in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    transformer.pushCurrentTemplateRuleIsNull(false);
+
+    boolean pushMode = false;
+
+    try
+    {
+      // %REVIEW% Do we need this check??
+      //      if (null != sourceNode)
+      //      {
+      // boolean needToTurnOffInfiniteLoopCheck = false;
+      QName mode = transformer.getMode();
+
+      if (!m_isDefaultTemplate)
+      {
+        if (((null == mode) && (null != m_mode))
+                || ((null != mode) &&!mode.equals(m_mode)))
+        {
+          pushMode = true;
+
+          transformer.pushMode(m_mode);
+        }
+      }
+
+      transformSelectedNodes(transformer);
+    }
+    finally
+    {
+      if (pushMode)
+        transformer.popMode();
+
+      transformer.popCurrentTemplateRuleIsNull();
+    }
+  }
+
+  
+  /**
+   * Perform a query if needed, and call transformNode for each child.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException Thrown in a variety of circumstances.
+   * @xsl.usage advanced
+   */
+  public void transformSelectedNodes(TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    final XPathContext xctxt = transformer.getXPathContext();
+    final int sourceNode = xctxt.getCurrentNode();
+    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
+    VariableStack vars = xctxt.getVarStack();
+    int nParams = getParamElemCount();
+    int thisframe = vars.getStackFrame();
+
+    boolean pushContextNodeListFlag = false;
+      
+    try
+    {
+
+            xctxt.pushCurrentNode(DTM.NULL);
+            xctxt.pushCurrentExpressionNode(DTM.NULL);
+            xctxt.pushSAXLocatorNull();
+            transformer.pushElemTemplateElement(null);
+      final Vector keys = (m_sortElems == null)
+                          ? null
+                          : transformer.processSortKeys(this, sourceNode);
+
+      // Sort if we need to.
+      if (null != keys)
+        sourceNodes = sortNodes(xctxt, keys, sourceNodes);
+            
+      final SerializationHandler rth = transformer.getSerializationHandler();
+//      ContentHandler chandler = rth.getContentHandler();
+      final StylesheetRoot sroot = transformer.getStylesheet();
+      final TemplateList tl = sroot.getTemplateListComposed();
+      final boolean quiet = transformer.getQuietConflictWarnings();
+      
+      // Should be able to get this from the iterator but there must be a bug.
+      DTM dtm = xctxt.getDTM(sourceNode);
+      
+      int argsFrame = -1;
+      if(nParams > 0)
+      {
+        // This code will create a section on the stack that is all the 
+        // evaluated arguments.  These will be copied into the real params 
+        // section of each called template.
+        argsFrame = vars.link(nParams);
+        vars.setStackFrame(thisframe);
+        
+        for (int i = 0; i < nParams; i++) 
+        {
+          ElemWithParam ewp = m_paramElems[i];
+          XObject obj = ewp.getValue(transformer, sourceNode);
+
+          vars.setLocalVariable(i, obj, argsFrame);
+        }
+        vars.setStackFrame(argsFrame);
+      }
+      
+      xctxt.pushContextNodeList(sourceNodes);
+      pushContextNodeListFlag = true;
+      
+      IntStack currentNodes = xctxt.getCurrentNodeStack();
+      
+      IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();     
+      
+      // pushParams(transformer, xctxt);
+      
+      int child;
+      while (DTM.NULL != (child = sourceNodes.nextNode()))
+      {
+        currentNodes.setTop(child);
+        currentExpressionNodes.setTop(child);
+
+        if(xctxt.getDTM(child) != dtm)
+        {
+          dtm = xctxt.getDTM(child);
+        }
+        
+        final int exNodeType = dtm.getExpandedTypeID(child);
+
+        final int nodeType = dtm.getNodeType(child);
+
+        final QName mode = transformer.getMode();
+
+        ElemTemplate template = tl.getTemplateFast(xctxt, child, exNodeType, mode, 
+                                      -1, quiet, dtm);
+
+        // If that didn't locate a node, fall back to a default template rule.
+        // See http://www.w3.org/TR/xslt#built-in-rule.
+        if (null == template)
+        {
+          switch (nodeType)
+          {
+          case DTM.DOCUMENT_FRAGMENT_NODE :
+          case DTM.ELEMENT_NODE :
+            template = sroot.getDefaultRule();
+            // %OPT% direct faster?
+            break;
+          case DTM.ATTRIBUTE_NODE :
+          case DTM.CDATA_SECTION_NODE :
+          case DTM.TEXT_NODE :
+            // if(rth.m_elemIsPending || rth.m_docPending)
+            //  rth.flushPending(true);
+            transformer.pushPairCurrentMatched(sroot.getDefaultTextRule(), child);
+            transformer.setCurrentElement(sroot.getDefaultTextRule());
+            // dtm.dispatchCharactersEvents(child, chandler, false);
+            dtm.dispatchCharactersEvents(child, rth, false);
+            transformer.popCurrentMatched();
+            continue;
+          case DTM.DOCUMENT_NODE :
+            template = sroot.getDefaultRootRule();
+            break;
+          default :
+
+            // No default rules for processing instructions and the like.
+            continue;
+          }
+        }
+        else
+        {
+        	transformer.setCurrentElement(template);
+        }
+                
+        transformer.pushPairCurrentMatched(template, child);
+
+        int currentFrameBottom;  // See comment with unlink, below
+        if(template.m_frameSize > 0)
+        {
+          xctxt.pushRTFContext();
+          currentFrameBottom = vars.getStackFrame();  // See comment with unlink, below
+          vars.link(template.m_frameSize);
+          // You can't do the check for nParams here, otherwise the 
+          // xsl:params might not be nulled.
+          if(/* nParams > 0 && */ template.m_inArgsSize > 0)
+          {
+            int paramIndex = 0;
+            for (ElemTemplateElement elem = template.getFirstChildElem(); 
+                 null != elem; elem = elem.getNextSiblingElem()) 
+            {
+              if(Constants.ELEMNAME_PARAMVARIABLE == elem.getXSLToken())
+              {
+                ElemParam ep = (ElemParam)elem;
+                
+                int i;
+                for (i = 0; i < nParams; i++) 
+                {
+                  ElemWithParam ewp = m_paramElems[i];
+                  if(ewp.m_qnameID == ep.m_qnameID)
+                  {
+                    XObject obj = vars.getLocalVariable(i, argsFrame);
+                    vars.setLocalVariable(paramIndex, obj);
+                    break;
+                  }
+                }
+                if(i == nParams)
+                  vars.setLocalVariable(paramIndex, null);
+              }
+              else
+                break;
+              paramIndex++;
+            }
+            
+          }
+        }
+        else
+        	currentFrameBottom = 0;
+
+        // And execute the child templates.
+        // Loop through the children of the template, calling execute on 
+        // each of them.
+        for (ElemTemplateElement t = template.m_firstChild; 
+             t != null; t = t.m_nextSibling)
+        {
+          xctxt.setSAXLocator(t);
+          try
+          {
+          	transformer.pushElemTemplateElement(t);
+          	t.execute(transformer);
+          }
+          finally
+          {
+          	transformer.popElemTemplateElement();
+          }
+        }
+        
+        if(template.m_frameSize > 0)
+        {
+          // See Frank Weiss bug around 03/19/2002 (no Bugzilla report yet).
+          // While unlink will restore to the proper place, the real position 
+          // may have been changed for xsl:with-param, so that variables 
+          // can be accessed.  
+          // of right now.
+          // More:
+          // When we entered this function, the current 
+          // frame buffer (cfb) index in the variable stack may 
+          // have been manually set.  If we just call 
+          // unlink(), however, it will restore the cfb to the 
+          // previous link index from the link stack, rather than 
+          // the manually set cfb.  So, 
+          // the only safe solution is to restore it back 
+          // to the same position it was on entry, since we're 
+          // really not working in a stack context here. (Bug4218)
+          vars.unlink(currentFrameBottom);
+          xctxt.popRTFContext();
+        }
+          
+        transformer.popCurrentMatched();
+        
+      } // end while (DTM.NULL != (child = sourceNodes.nextNode()))
+    }
+    catch (SAXException se)
+    {
+      transformer.getErrorListener().fatalError(new TransformerException(se));
+    }
+    finally
+    {
+      // Unlink to the original stack frame
+      if(nParams > 0)
+        vars.unlink(thisframe);
+      xctxt.popSAXLocator();
+      if (pushContextNodeListFlag) xctxt.popContextNodeList();
+      transformer.popElemTemplateElement();
+      xctxt.popCurrentExpressionNode();
+      xctxt.popCurrentNode();
+      sourceNodes.detach();
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemAttribute.java b/src/main/java/org/apache/xalan/templates/ElemAttribute.java
new file mode 100644
index 0000000..a6ca934
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemAttribute.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemAttribute.java 469304 2006-10-30 22:29:47Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.NamespaceMappings;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.XML11Char;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Implement xsl:attribute.
+ * <pre>
+ * &amp;!ELEMENT xsl:attribute %char-template;>
+ * &amp;!ATTLIST xsl:attribute
+ *   name %avt; #REQUIRED
+ *   namespace %avt; #IMPLIED
+ *   %space-att;
+ * &amp;
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#creating-attributes">creating-attributes in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemAttribute extends ElemElement
+{
+    static final long serialVersionUID = 8817220961566919187L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_ATTRIBUTE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element name 
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_ATTRIBUTE_STRING;
+  }
+
+  /**
+   * Create an attribute in the result tree.
+   * @see <a href="http://www.w3.org/TR/xslt#creating-attributes">creating-attributes in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+//  public void execute(
+//          TransformerImpl transformer)
+//            throws TransformerException
+//  {
+    //SerializationHandler rhandler = transformer.getSerializationHandler();
+
+    // If they are trying to add an attribute when there isn't an 
+    // element pending, it is an error.
+    // I don't think we need this check here because it is checked in 
+    // ResultTreeHandler.addAttribute.  (is)
+//    if (!rhandler.isElementPending())
+//    {
+//      // Make sure the trace event is sent.
+//      if (TransformerImpl.S_DEBUG)
+//        transformer.getTraceManager().fireTraceEvent(this);
+//
+//      XPathContext xctxt = transformer.getXPathContext();
+//      int sourceNode = xctxt.getCurrentNode();
+//      String attrName = m_name_avt.evaluate(xctxt, sourceNode, this);
+//      transformer.getMsgMgr().warn(this,
+//                                   XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_POSITION,
+//                                   new Object[]{ attrName });
+//
+//      if (TransformerImpl.S_DEBUG)
+//        transformer.getTraceManager().fireTraceEndEvent(this);
+//      return;
+//
+//      // warn(templateChild, sourceNode, "Trying to add attribute after element child has been added, ignoring...");
+//    }
+    
+//    super.execute(transformer);
+    
+//  }
+  
+  /**
+   * Resolve the namespace into a prefix.  At this level, if no prefix exists, 
+   * then return a manufactured prefix.
+   *
+   * @param rhandler The current result tree handler.
+   * @param prefix The probable prefix if already known.
+   * @param nodeNamespace  The namespace, which should not be null.
+   *
+   * @return The prefix to be used.
+   */
+  protected String resolvePrefix(SerializationHandler rhandler,
+                                 String prefix, String nodeNamespace)
+    throws TransformerException
+  {
+
+    if (null != prefix && (prefix.length() == 0 || prefix.equals("xmlns")))
+    {
+      // Since we can't use default namespace, in this case we try and 
+      // see if a prefix has already been defined or this namespace.
+      prefix = rhandler.getPrefix(nodeNamespace);
+
+      // System.out.println("nsPrefix: "+nsPrefix);           
+      if (null == prefix || prefix.length() == 0 || prefix.equals("xmlns"))
+      {
+        if(nodeNamespace.length() > 0)
+        {
+            NamespaceMappings prefixMapping = rhandler.getNamespaceMappings();
+            prefix = prefixMapping.generateNextPrefix();
+        }
+        else
+          prefix = "";
+      }
+    }
+    return prefix;
+  }
+  
+  /**
+   * Validate that the node name is good.
+   * 
+   * @param nodeName Name of the node being constructed, which may be null.
+   * 
+   * @return true if the node name is valid, false otherwise.
+   */
+   protected boolean validateNodeName(String nodeName)
+   {
+      if(null == nodeName)
+        return false;
+      if(nodeName.equals("xmlns"))
+        return false;
+      return XML11Char.isXML11ValidQName(nodeName);
+   }
+  
+  /**
+   * Construct a node in the result tree.  This method is overloaded by 
+   * xsl:attribute. At this class level, this method creates an element.
+   *
+   * @param nodeName The name of the node, which may be null.
+   * @param prefix The prefix for the namespace, which may be null.
+   * @param nodeNamespace The namespace of the node, which may be null.
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
+   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
+   *
+   * @throws TransformerException
+   */
+  void constructNode(
+          String nodeName, String prefix, String nodeNamespace, TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    if(null != nodeName && nodeName.length() > 0)
+    {
+      SerializationHandler rhandler = transformer.getSerializationHandler();
+
+      // Evaluate the value of this attribute
+      String val = transformer.transformToString(this);
+      try 
+      {
+        // Let the result tree handler add the attribute and its String value.
+        String localName = QName.getLocalPart(nodeName);
+        if(prefix != null && prefix.length() > 0){
+            rhandler.addAttribute(nodeNamespace, localName, nodeName, "CDATA", val, true);
+        }else{
+            rhandler.addAttribute("", localName, nodeName, "CDATA", val, true);
+        }
+      }
+      catch (SAXException e)
+      {
+      }
+    }
+  }
+
+
+  /**
+   * Add a child to the child list.
+   * <!ELEMENT xsl:attribute %char-template;>
+   * <!ATTLIST xsl:attribute
+   *   name %avt; #REQUIRED
+   *   namespace %avt; #IMPLIED
+   *   %space-att;
+   * >
+   *
+   * @param newChild Child to append to the list of this node's children
+   *
+   * @return The node we just appended to the children list 
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+
+    // char-instructions 
+    case Constants.ELEMNAME_TEXTLITERALRESULT :
+    case Constants.ELEMNAME_APPLY_TEMPLATES :
+    case Constants.ELEMNAME_APPLY_IMPORTS :
+    case Constants.ELEMNAME_CALLTEMPLATE :
+    case Constants.ELEMNAME_FOREACH :
+    case Constants.ELEMNAME_VALUEOF :
+    case Constants.ELEMNAME_COPY_OF :
+    case Constants.ELEMNAME_NUMBER :
+    case Constants.ELEMNAME_CHOOSE :
+    case Constants.ELEMNAME_IF :
+    case Constants.ELEMNAME_TEXT :
+    case Constants.ELEMNAME_COPY :
+    case Constants.ELEMNAME_VARIABLE :
+    case Constants.ELEMNAME_MESSAGE :
+
+      // instructions 
+      // case Constants.ELEMNAME_PI:
+      // case Constants.ELEMNAME_COMMENT:
+      // case Constants.ELEMNAME_ELEMENT:
+      // case Constants.ELEMNAME_ATTRIBUTE:
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+	/**
+	 * @see ElemElement#setName(AVT)
+	 */
+	public void setName(AVT v) {
+        if (v.isSimple())
+        {
+            if (v.getSimpleString().equals("xmlns"))
+            {
+                throw new IllegalArgumentException();
+            }
+        }
+		super.setName(v);
+	}
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemAttributeSet.java b/src/main/java/org/apache/xalan/templates/ElemAttributeSet.java
new file mode 100644
index 0000000..8f85122
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemAttributeSet.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemAttributeSet.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+
+/**
+ * Implement xsl:attribute-set.
+ * <pre>
+ * &amp;!ELEMENT xsl:attribute-set (xsl:attribute)*>
+ * &amp;!ATTLIST xsl:attribute-set
+ *   name %qname; #REQUIRED
+ *   use-attribute-sets %qnames; #IMPLIED
+ * &amp;
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemAttributeSet extends ElemUse
+{
+    static final long serialVersionUID = -426740318278164496L;
+
+  /**
+   * The name attribute specifies the name of the attribute set.
+   * @serial
+   */
+  public QName m_qname = null;
+
+  /**
+   * Set the "name" attribute.
+   * The name attribute specifies the name of the attribute set.
+   *
+   * @param name Name attribute to set
+   */
+  public void setName(QName name)
+  {
+    m_qname = name;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * The name attribute specifies the name of the attribute set.
+   *
+   * @return The name attribute of the attribute set
+   */
+  public QName getName()
+  {
+    return m_qname;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return Token ID of the element 
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_DEFINEATTRIBUTESET;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The name of this element
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_ATTRIBUTESET_STRING;
+  }
+
+  /**
+   * Apply a set of attributes to the element.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    if (transformer.isRecursiveAttrSet(this))
+    {
+      throw new TransformerException(
+        XSLMessages.createMessage(
+          XSLTErrorResources.ER_XSLATTRSET_USED_ITSELF,
+          new Object[]{ m_qname.getLocalPart() }));  //"xsl:attribute-set '"+m_qname.m_localpart+
+    }
+
+    transformer.pushElemAttributeSet(this);
+    super.execute(transformer);
+
+    ElemAttribute attr = (ElemAttribute) getFirstChildElem();
+
+    while (null != attr)
+    {
+      attr.execute(transformer);
+
+      attr = (ElemAttribute) attr.getNextSiblingElem();
+    }
+
+    transformer.popElemAttributeSet();
+  }
+
+  /**
+   * Add a child to the child list.
+   * <!ELEMENT xsl:attribute-set (xsl:attribute)*>
+   * <!ATTLIST xsl:attribute-set
+   *   name %qname; #REQUIRED
+   *   use-attribute-sets %qnames; #IMPLIED
+   * >
+   *
+   * @param newChild Child to be added to this node's list of children
+   *
+   * @return The child that was just added to the list of children
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChildElem(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+    case Constants.ELEMNAME_ATTRIBUTE :
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+
+  /**
+   * This function is called during recomposition to
+   * control how this element is composed.
+   * @param root The root stylesheet for this transformation.
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeAttributeSets(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemCallTemplate.java b/src/main/java/org/apache/xalan/templates/ElemCallTemplate.java
new file mode 100644
index 0000000..8bcb37c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemCallTemplate.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemCallTemplate.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implement xsl:call-template.
+ * <pre>
+ * &amp;!ELEMENT xsl:call-template (xsl:with-param)*>
+ * &amp;!ATTLIST xsl:call-template
+ *   name %qname; #REQUIRED
+ * &amp;
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemCallTemplate extends ElemForEach
+{
+    static final long serialVersionUID = 5009634612916030591L;
+
+  /**
+   * An xsl:call-template element invokes a template by name;
+   * it has a required name attribute that identifies the template to be invoked.
+   * @serial
+   */
+  public QName m_templateName = null;
+
+  /**
+   * Set the "name" attribute.
+   * An xsl:call-template element invokes a template by name;
+   * it has a required name attribute that identifies the template to be invoked.
+   *
+   * @param name Name attribute to set
+   */
+  public void setName(QName name)
+  {
+    m_templateName = name;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * An xsl:call-template element invokes a template by name;
+   * it has a required name attribute that identifies the template to be invoked.
+   *
+   * @return Name attribute of this element
+   */
+  public QName getName()
+  {
+    return m_templateName;
+  }
+
+  /**
+   * The template which is named by QName.
+   * @serial
+   */
+  private ElemTemplate m_template = null;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element 
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_CALLTEMPLATE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The name of this element
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_CALLTEMPLATE_STRING;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    
+    // Call compose on each param no matter if this is apply-templates 
+    // or call templates.
+    int length = getParamElemCount();
+    for (int i = 0; i < length; i++) 
+    {
+      ElemWithParam ewp = getParamElem(i);
+      ewp.compose(sroot);
+    }
+    
+	if ((null != m_templateName) && (null == m_template)) {
+		m_template =
+			this.getStylesheetRoot().getTemplateComposed(m_templateName);
+
+		if (null == m_template) {
+			String themsg =
+				XSLMessages.createMessage(
+					XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
+					new Object[] { m_templateName });
+
+			throw new TransformerException(themsg, this);
+			//"Could not find template named: '"+templateName+"'");
+		}
+    
+      length = getParamElemCount();
+      for (int i = 0; i < length; i++) 
+      {
+        ElemWithParam ewp = getParamElem(i);
+        ewp.m_index = -1;
+        // Find the position of the param in the template being called, 
+        // and set the index of the param slot.
+        int etePos = 0;
+        for (ElemTemplateElement ete = m_template.getFirstChildElem(); 
+             null != ete; ete = ete.getNextSiblingElem()) 
+        {
+          if(ete.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE)
+          {
+            ElemParam ep = (ElemParam)ete;
+            if(ep.getName().equals(ewp.getName()))
+            {
+              ewp.m_index = etePos;
+            }
+          }
+          else
+            break;
+          etePos++;
+        }
+        
+      }
+    }
+  }
+  
+  /**
+   * This after the template's children have been composed.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+    int length = getParamElemCount();
+    for (int i = 0; i < length; i++) 
+    {
+      ElemWithParam ewp = getParamElem(i);
+      ewp.endCompose(sroot);
+    }    
+    
+    super.endCompose(sroot);
+  }
+
+  /**
+   * Invoke a named template.
+   * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    if (null != m_template)
+    {
+      XPathContext xctxt = transformer.getXPathContext();
+      VariableStack vars = xctxt.getVarStack();
+
+      int thisframe = vars.getStackFrame();
+      int nextFrame = vars.link(m_template.m_frameSize);
+      
+      // We have to clear the section of the stack frame that has params 
+      // so that the default param evaluation will work correctly.
+      if(m_template.m_inArgsSize > 0)
+      {
+        vars.clearLocalSlots(0, m_template.m_inArgsSize);
+      
+        if(null != m_paramElems)
+        {
+          int currentNode = xctxt.getCurrentNode();
+          vars.setStackFrame(thisframe);
+          int size = m_paramElems.length;
+          
+          for (int i = 0; i < size; i++) 
+          {
+            ElemWithParam ewp = m_paramElems[i];
+            if(ewp.m_index >= 0)
+            {
+              XObject obj = ewp.getValue(transformer, currentNode);
+
+              // Note here that the index for ElemWithParam must have been
+              // statically made relative to the xsl:template being called, 
+              // NOT this xsl:template.
+              vars.setLocalVariable(ewp.m_index, obj, nextFrame);
+            }
+          }
+          vars.setStackFrame(nextFrame);
+        }
+      }
+      
+      SourceLocator savedLocator = xctxt.getSAXLocator();
+
+      try
+      {
+        xctxt.setSAXLocator(m_template);
+
+        // template.executeChildTemplates(transformer, sourceNode, mode, true);
+        transformer.pushElemTemplateElement(m_template);
+        m_template.execute(transformer);
+      }
+      finally
+      {
+        transformer.popElemTemplateElement();
+        xctxt.setSAXLocator(savedLocator);
+        // When we entered this function, the current 
+        // frame buffer (cfb) index in the variable stack may 
+        // have been manually set.  If we just call 
+        // unlink(), however, it will restore the cfb to the 
+        // previous link index from the link stack, rather than 
+        // the manually set cfb.  So, 
+        // the only safe solution is to restore it back 
+        // to the same position it was on entry, since we're 
+        // really not working in a stack context here. (Bug4218)
+        vars.unlink(thisframe);
+      }
+    }
+    else
+    {
+      transformer.getMsgMgr().error(this, XSLTErrorResources.ER_TEMPLATE_NOT_FOUND,
+                                    new Object[]{ m_templateName });  //"Could not find template named: '"+templateName+"'");
+    }
+    
+  }
+  
+  /** Vector of xsl:param elements associated with this element. 
+   *  @serial */
+  protected ElemWithParam[] m_paramElems = null;
+
+  /**
+   * Get the count xsl:param elements associated with this element.
+   * @return The number of xsl:param elements.
+   */
+  public int getParamElemCount()
+  {
+    return (m_paramElems == null) ? 0 : m_paramElems.length;
+  }
+
+  /**
+   * Get a xsl:param element associated with this element.
+   *
+   * @param i Index of element to find
+   *
+   * @return xsl:param element at given index
+   */
+  public ElemWithParam getParamElem(int i)
+  {
+    return m_paramElems[i];
+  }
+
+  /**
+   * Set a xsl:param element associated with this element.
+   *
+   * @param ParamElem xsl:param element to set. 
+   */
+  public void setParamElem(ElemWithParam ParamElem)
+  {
+    if (null == m_paramElems)
+    {
+      m_paramElems = new ElemWithParam[1];
+      m_paramElems[0] = ParamElem;
+    }
+    else
+    {
+      // Expensive 1 at a time growth, but this is done at build time, so 
+      // I think it's OK.
+      int length = m_paramElems.length;
+      ElemWithParam[] ewp = new ElemWithParam[length + 1];
+      System.arraycopy(m_paramElems, 0, ewp, 0, length);
+      m_paramElems = ewp;
+      ewp[length] = ParamElem;
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   * <!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
+   * <!ATTLIST xsl:apply-templates
+   *   select %expr; "node()"
+   *   mode %qname; #IMPLIED
+   * >
+   *
+   * @param newChild Child to add to this node's children list
+   *
+   * @return The child that was just added the children list 
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    if (Constants.ELEMNAME_WITHPARAM == type)
+    {
+      setParamElem((ElemWithParam) newChild);
+    }
+
+    // You still have to append, because this element can
+    // contain a for-each, and other elements.
+    return super.appendChild(newChild);
+  }
+  
+    /**
+     * Call the children visitors.
+     * @param visitor The visitor whose appropriate method will be called.
+     */
+    public void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+    {
+//      if (null != m_paramElems)
+//      {
+//        int size = m_paramElems.length;
+//
+//        for (int i = 0; i < size; i++)
+//        {
+//          ElemWithParam ewp = m_paramElems[i];
+//          ewp.callVisitors(visitor);
+//        }
+//      }
+
+      super.callChildVisitors(visitor, callAttrs);
+    }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemChoose.java b/src/main/java/org/apache/xalan/templates/ElemChoose.java
new file mode 100644
index 0000000..caa44f3
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemChoose.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemChoose.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implement xsl:choose.
+ * <pre>
+ * <!ELEMENT xsl:choose (xsl:when+, xsl:otherwise?)>
+ * <!ATTLIST xsl:choose %space-att;>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose">XXX in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemChoose extends ElemTemplateElement
+{
+    static final long serialVersionUID = -3070117361903102033L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_CHOOSE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_CHOOSE_STRING;
+  }
+
+  /**
+   * Constructor ElemChoose
+   *
+   */
+  public ElemChoose(){}
+
+  /**
+   * Execute the xsl:choose transformation.
+   *
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    boolean found = false;
+
+    for (ElemTemplateElement childElem = getFirstChildElem();
+            childElem != null; childElem = childElem.getNextSiblingElem())
+    {
+      int type = childElem.getXSLToken();
+
+      if (Constants.ELEMNAME_WHEN == type)
+      {
+        found = true;
+
+        ElemWhen when = (ElemWhen) childElem;
+
+        // must be xsl:when
+        XPathContext xctxt = transformer.getXPathContext();
+        int sourceNode = xctxt.getCurrentNode();
+        
+        // System.err.println("\""+when.getTest().getPatternString()+"\"");
+        
+        // if(when.getTest().getPatternString().equals("COLLECTION/icuser/ictimezone/LITERAL='GMT +13:00 Pacific/Tongatapu'"))
+        // 	System.err.println("Found COLLECTION/icuser/ictimezone/LITERAL");
+
+          if (when.getTest().bool(xctxt, sourceNode, when)) {
+              transformer.executeChildTemplates(when, true);
+
+              return;
+          }
+      }
+      else if (Constants.ELEMNAME_OTHERWISE == type)
+      {
+        found = true;
+
+        // xsl:otherwise
+        transformer.executeChildTemplates(childElem, true);
+
+        return;
+      }
+    }
+
+    if (!found)
+      transformer.getMsgMgr().error(
+        this, XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to this node's child list
+   *
+   * @return The child that was just added to the child list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+    case Constants.ELEMNAME_WHEN :
+    case Constants.ELEMNAME_OTHERWISE :
+
+      // TODO: Positional checking
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+  
+  /**
+   * Tell if this element can accept variable declarations.
+   * @return true if the element can accept and process variable declarations.
+   */
+  public boolean canAcceptVariables()
+  {
+  	return false;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemComment.java b/src/main/java/org/apache/xalan/templates/ElemComment.java
new file mode 100644
index 0000000..49e9311
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemComment.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemComment.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+
+/**
+ * Implement xsl:comment.
+ * <pre>
+ * <!ELEMENT xsl:comment %char-template;>
+ * <!ATTLIST xsl:comment %space-att;>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Comments">section-Creating-Comments in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemComment extends ElemTemplateElement
+{
+    static final long serialVersionUID = -8813199122875770142L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_COMMENT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return This element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_COMMENT_STRING;
+  }
+
+  /**
+   * Execute the xsl:comment transformation 
+   *
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    try
+    {
+      // Note the content model is:
+      // <!ENTITY % instructions "
+      // %char-instructions;
+      // | xsl:processing-instruction
+      // | xsl:comment
+      // | xsl:element
+      // | xsl:attribute
+      // ">
+      String data = transformer.transformToString(this);
+
+      transformer.getResultTreeHandler().comment(data);
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to this node's child list
+   *
+   * @return Child that was just added to child list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+
+    // char-instructions 
+    case Constants.ELEMNAME_TEXTLITERALRESULT :
+    case Constants.ELEMNAME_APPLY_TEMPLATES :
+    case Constants.ELEMNAME_APPLY_IMPORTS :
+    case Constants.ELEMNAME_CALLTEMPLATE :
+    case Constants.ELEMNAME_FOREACH :
+    case Constants.ELEMNAME_VALUEOF :
+    case Constants.ELEMNAME_COPY_OF :
+    case Constants.ELEMNAME_NUMBER :
+    case Constants.ELEMNAME_CHOOSE :
+    case Constants.ELEMNAME_IF :
+    case Constants.ELEMNAME_TEXT :
+    case Constants.ELEMNAME_COPY :
+    case Constants.ELEMNAME_VARIABLE :
+    case Constants.ELEMNAME_MESSAGE :
+
+      // instructions 
+      // case Constants.ELEMNAME_PI:
+      // case Constants.ELEMNAME_COMMENT:
+      // case Constants.ELEMNAME_ELEMENT:
+      // case Constants.ELEMNAME_ATTRIBUTE:
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemCopy.java b/src/main/java/org/apache/xalan/templates/ElemCopy.java
new file mode 100644
index 0000000..344c13d
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemCopy.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemCopy.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.ClonerToResultTree;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xalan.serialize.SerializerUtils;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Implement xsl:copy.
+ * <pre>
+ * <!ELEMENT xsl:copy %template;>
+ * <!ATTLIST xsl:copy
+ *   %space-att;
+ *   use-attribute-sets %qnames; #IMPLIED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#copying">copying in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemCopy extends ElemUse
+{
+    static final long serialVersionUID = 5478580783896941384L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element 
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_COPY;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return This element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_COPY_STRING;
+  }
+
+  /**
+   * The xsl:copy element provides an easy way of copying the current node.
+   * Executing this function creates a copy of the current node into the
+   * result tree.
+   * <p>The namespace nodes of the current node are automatically
+   * copied as well, but the attributes and children of the node are not
+   * automatically copied. The content of the xsl:copy element is a
+   * template for the attributes and children of the created node;
+   * the content is instantiated only for nodes of types that can have
+   * attributes or children (i.e. root nodes and element nodes).</p>
+   * <p>The root node is treated specially because the root node of the
+   * result tree is created implicitly. When the current node is the
+   * root node, xsl:copy will not create a root node, but will just use
+   * the content template.</p>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+                XPathContext xctxt = transformer.getXPathContext();
+      
+    try
+    {
+      int sourceNode = xctxt.getCurrentNode();
+      xctxt.pushCurrentNode(sourceNode);
+      DTM dtm = xctxt.getDTM(sourceNode);
+      short nodeType = dtm.getNodeType(sourceNode);
+
+      if ((DTM.DOCUMENT_NODE != nodeType) && (DTM.DOCUMENT_FRAGMENT_NODE != nodeType))
+      {
+        SerializationHandler rthandler = transformer.getSerializationHandler();
+
+        // TODO: Process the use-attribute-sets stuff
+        ClonerToResultTree.cloneToResultTree(sourceNode, nodeType, dtm, 
+                                             rthandler, false);
+
+        if (DTM.ELEMENT_NODE == nodeType)
+        {
+          super.execute(transformer);
+          SerializerUtils.processNSDecls(rthandler, sourceNode, nodeType, dtm);
+          transformer.executeChildTemplates(this, true);
+          
+          String ns = dtm.getNamespaceURI(sourceNode);
+          String localName = dtm.getLocalName(sourceNode);
+          transformer.getResultTreeHandler().endElement(ns, localName,
+                                                        dtm.getNodeName(sourceNode));
+        }
+      }
+      else
+      {
+        super.execute(transformer);
+        transformer.executeChildTemplates(this, true);
+      }
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemCopyOf.java b/src/main/java/org/apache/xalan/templates/ElemCopyOf.java
new file mode 100644
index 0000000..8423992
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemCopyOf.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemCopyOf.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.transformer.TreeWalker2Result;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.ref.DTMTreeWalker;
+import org.apache.xalan.serialize.SerializerUtils;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implement xsl:copy-of.
+ * <pre>
+ * <!ELEMENT xsl:copy-of EMPTY>
+ * <!ATTLIST xsl:copy-of select %expr; #REQUIRED>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#copy-of">copy-of in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemCopyOf extends ElemTemplateElement
+{
+    static final long serialVersionUID = -7433828829497411127L;
+
+  /**
+   * The required select attribute contains an expression.
+   * @serial
+   */
+  public XPath m_selectExpression = null;
+
+  /**
+   * Set the "select" attribute.
+   * The required select attribute contains an expression.
+   *
+   * @param expr Expression for select attribute 
+   */
+  public void setSelect(XPath expr)
+  {
+    m_selectExpression = expr;
+  }
+
+  /**
+   * Get the "select" attribute.
+   * The required select attribute contains an expression.
+   *
+   * @return Expression for select attribute 
+   */
+  public XPath getSelect()
+  {
+    return m_selectExpression;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    m_selectExpression.fixupVariables(cstate.getVariableNames(), cstate.getGlobalsSize());
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_COPY_OF;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_COPY_OF_STRING;
+  }
+
+  /**
+   * The xsl:copy-of element can be used to insert a result tree
+   * fragment into the result tree, without first converting it to
+   * a string as xsl:value-of does (see [7.6.1 Generating Text with
+   * xsl:value-of]).
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    try
+    {
+      XPathContext xctxt = transformer.getXPathContext();
+      int sourceNode = xctxt.getCurrentNode();
+      XObject value = m_selectExpression.execute(xctxt, sourceNode, this);
+
+      SerializationHandler handler = transformer.getSerializationHandler();
+
+      if (null != value)
+                        {
+        int type = value.getType();
+        String s;
+
+        switch (type)
+        {
+        case XObject.CLASS_BOOLEAN :
+        case XObject.CLASS_NUMBER :
+        case XObject.CLASS_STRING :
+          s = value.str();
+
+          handler.characters(s.toCharArray(), 0, s.length());
+          break;
+        case XObject.CLASS_NODESET :
+
+          // System.out.println(value);
+          DTMIterator nl = value.iter();
+
+          // Copy the tree.
+          DTMTreeWalker tw = new TreeWalker2Result(transformer, handler);
+          int pos;
+
+          while (DTM.NULL != (pos = nl.nextNode()))
+          {
+            DTM dtm = xctxt.getDTMManager().getDTM(pos);
+            short t = dtm.getNodeType(pos);
+
+            // If we just copy the whole document, a startDoc and endDoc get 
+            // generated, so we need to only walk the child nodes.
+            if (t == DTM.DOCUMENT_NODE)
+            {
+              for (int child = dtm.getFirstChild(pos); child != DTM.NULL;
+                   child = dtm.getNextSibling(child))
+              {
+                tw.traverse(child);
+              }
+            }
+            else if (t == DTM.ATTRIBUTE_NODE)
+            {
+              SerializerUtils.addAttribute(handler, pos);
+            }
+            else
+            {
+              tw.traverse(pos);
+            }
+          }
+          // nl.detach();
+          break;
+        case XObject.CLASS_RTREEFRAG :
+          SerializerUtils.outputResultTreeFragment(
+            handler, value, transformer.getXPathContext());
+          break;
+        default :
+          
+          s = value.str();
+
+          handler.characters(s.toCharArray(), 0, s.length());
+          break;
+        }
+      }
+                        
+      // I don't think we want this.  -sb
+      //  if (transformer.getDebug())
+      //  transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
+      //  "endSelect", m_selectExpression, value);
+
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to this node's child list
+   *
+   * @return Child just added to child list
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    error(XSLTErrorResources.ER_CANNOT_ADD,
+          new Object[]{ newChild.getNodeName(),
+                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    return null;
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  		m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemElement.java b/src/main/java/org/apache/xalan/templates/ElemElement.java
new file mode 100644
index 0000000..3f13eb4
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemElement.java
@@ -0,0 +1,372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemElement.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.XML11Char;
+import org.apache.xpath.XPathContext;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement xsl:element
+ * <pre>
+ * <!ELEMENT xsl:element %template;>
+ * <!ATTLIST xsl:element
+ *   name %avt; #REQUIRED
+ *   namespace %avt; #IMPLIED
+ *   use-attribute-sets %qnames; #IMPLIED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element">XXX in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemElement extends ElemUse
+{
+    static final long serialVersionUID = -324619535592435183L;
+
+  /**
+   * The name attribute is interpreted as an attribute value template.
+   * It is an error if the string that results from instantiating the
+   * attribute value template is not a QName.
+   * @serial
+   */
+  protected AVT m_name_avt = null;
+
+  /**
+   * Set the "name" attribute.
+   * The name attribute is interpreted as an attribute value template.
+   * It is an error if the string that results from instantiating the
+   * attribute value template is not a QName.
+   *
+   * @param v Name attribute to set for this element
+   */
+  public void setName(AVT v)
+  {
+    m_name_avt = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * The name attribute is interpreted as an attribute value template.
+   * It is an error if the string that results from instantiating the
+   * attribute value template is not a QName.
+   *
+   * @return Name attribute for this element
+   */
+  public AVT getName()
+  {
+    return m_name_avt;
+  }
+
+  /**
+   * If the namespace attribute is present, then it also is interpreted
+   * as an attribute value template. The string that results from
+   * instantiating the attribute value template should be a URI reference.
+   * It is not an error if the string is not a syntactically legal URI reference.
+   * @serial
+   */
+  protected AVT m_namespace_avt = null;
+
+  /**
+   * Set the "namespace" attribute.
+   * If the namespace attribute is present, then it also is interpreted
+   * as an attribute value template. The string that results from
+   * instantiating the attribute value template should be a URI reference.
+   * It is not an error if the string is not a syntactically legal URI reference.
+   *
+   * @param v NameSpace attribute to set for this element
+   */
+  public void setNamespace(AVT v)
+  {
+    m_namespace_avt = v;
+  }
+
+  /**
+   * Get the "namespace" attribute.
+   * If the namespace attribute is present, then it also is interpreted
+   * as an attribute value template. The string that results from
+   * instantiating the attribute value template should be a URI reference.
+   * It is not an error if the string is not a syntactically legal URI reference.
+   *
+   * @return Namespace attribute for this element
+   */
+  public AVT getNamespace()
+  {
+    return m_namespace_avt;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    java.util.Vector vnames = cstate.getVariableNames();
+    if(null != m_name_avt)
+      m_name_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_namespace_avt)
+      m_namespace_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+  }
+
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_ELEMENT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return This element's name 
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_ELEMENT_STRING;
+  }
+   
+  /**
+   * Resolve the namespace into a prefix.  Meant to be
+   * overidded by elemAttribute if this class is derived.
+   *
+   * @param rhandler The current result tree handler.
+   * @param prefix The probable prefix if already known.
+   * @param nodeNamespace  The namespace.
+   *
+   * @return The prefix to be used.
+   */
+  protected String resolvePrefix(SerializationHandler rhandler,
+                                 String prefix, String nodeNamespace)
+    throws TransformerException
+  {
+
+//    if (null != prefix && prefix.length() == 0)
+//    {
+//      String foundPrefix = rhandler.getPrefix(nodeNamespace);
+//
+//      // System.out.println("nsPrefix: "+nsPrefix);           
+//      if (null == foundPrefix)
+//        foundPrefix = "";
+//    }
+    return prefix;
+  }
+    
+  /**
+   * Create an element in the result tree.
+   * The xsl:element element allows an element to be created with a
+   * computed name. The expanded-name of the element to be created
+   * is specified by a required name attribute and an optional namespace
+   * attribute. The content of the xsl:element element is a template
+   * for the attributes and children of the created element.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+ 	SerializationHandler rhandler = transformer.getSerializationHandler();
+    XPathContext xctxt = transformer.getXPathContext();
+    int sourceNode = xctxt.getCurrentNode();
+    
+    
+    String nodeName = m_name_avt == null ? null : m_name_avt.evaluate(xctxt, sourceNode, this);
+
+    String prefix = null;
+    String nodeNamespace = "";
+
+    // Only validate if an AVT was used.
+    if ((nodeName != null) && (!m_name_avt.isSimple()) && (!XML11Char.isXML11ValidQName(nodeName)))
+    {
+      transformer.getMsgMgr().warn(
+        this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
+        new Object[]{ Constants.ATTRNAME_NAME, nodeName });
+
+      nodeName = null;
+    }
+
+    else if (nodeName != null)
+    {
+      prefix = QName.getPrefixPart(nodeName);
+
+      if (null != m_namespace_avt)
+      {
+        nodeNamespace = m_namespace_avt.evaluate(xctxt, sourceNode, this);
+        if (null == nodeNamespace || 
+            (prefix != null && prefix.length()>0 && nodeNamespace.length()== 0) )
+          transformer.getMsgMgr().error(
+              this, XSLTErrorResources.ER_NULL_URI_NAMESPACE);
+        else
+        {
+        // Determine the actual prefix that we will use for this nodeNamespace
+
+        prefix = resolvePrefix(rhandler, prefix, nodeNamespace);
+        if (null == prefix)
+          prefix = "";
+
+        if (prefix.length() > 0)
+          nodeName = (prefix + ":" + QName.getLocalPart(nodeName));
+        else
+          nodeName = QName.getLocalPart(nodeName);
+        }
+      }
+
+      // No namespace attribute was supplied. Use the namespace declarations
+      // currently in effect for the xsl:element element.
+      else    
+      {
+        try
+        {
+          // Maybe temporary, until I get this worked out.  test: axes59
+          nodeNamespace = getNamespaceForPrefix(prefix);
+
+          // If we get back a null nodeNamespace, that means that this prefix could
+          // not be found in the table.  This is okay only for a default namespace
+          // that has never been declared.
+
+          if ( (null == nodeNamespace) && (prefix.length() == 0) )
+            nodeNamespace = "";
+          else if (null == nodeNamespace)
+          {
+            transformer.getMsgMgr().warn(
+              this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
+              new Object[]{ prefix });
+
+            nodeName = null;
+          }
+
+        }
+        catch (Exception ex)
+        {
+          transformer.getMsgMgr().warn(
+            this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
+            new Object[]{ prefix });
+
+          nodeName = null;
+        }
+      }
+    }
+
+    constructNode(nodeName, prefix, nodeNamespace, transformer);
+  }
+  
+  /**
+   * Construct a node in the result tree.  This method is overloaded by 
+   * xsl:attribute. At this class level, this method creates an element.
+   * If the node is null, we instantiate only the content of the node in accordance
+   * with section 7.1.2 of the XSLT 1.0 Recommendation.
+   *
+   * @param nodeName The name of the node, which may be <code>null</code>.  If <code>null</code>,
+   *                 only the non-attribute children of this node will be processed.
+   * @param prefix The prefix for the namespace, which may be <code>null</code>.
+   *               If not <code>null</code>, this prefix will be mapped and unmapped.
+   * @param nodeNamespace The namespace of the node, which may be not be <code>null</code>.
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  void constructNode(
+          String nodeName, String prefix, String nodeNamespace, TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    boolean shouldAddAttrs;
+
+    try
+    {
+      SerializationHandler rhandler = transformer.getResultTreeHandler();
+
+      if (null == nodeName)
+      {
+        shouldAddAttrs = false;
+      }
+      else
+      {
+        if (null != prefix)
+        {
+          rhandler.startPrefixMapping(prefix, nodeNamespace, true);
+        }
+
+        rhandler.startElement(nodeNamespace, QName.getLocalPart(nodeName),
+                              nodeName);
+
+        super.execute(transformer);
+
+        shouldAddAttrs = true;
+      }
+
+      transformer.executeChildTemplates(this, shouldAddAttrs);
+
+      // Now end the element if name was valid
+      if (null != nodeName)
+      {
+        rhandler.endElement(nodeNamespace, QName.getLocalPart(nodeName),
+                            nodeName);
+        if (null != prefix)
+        {
+          rhandler.endPrefixMapping(prefix);
+        }
+      }
+    }
+    catch (SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  	{
+  	  if(null != m_name_avt)
+  		m_name_avt.callVisitors(visitor);
+  		
+  	  if(null != m_namespace_avt)
+  		m_namespace_avt.callVisitors(visitor);
+  	}
+  		
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemEmpty.java b/src/main/java/org/apache/xalan/templates/ElemEmpty.java
new file mode 100644
index 0000000..ea4662f
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemEmpty.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemEmpty.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+
+/**
+ * Simple empty elem to push on the stack when nothing
+ * else got pushed, so that pop() works correctly.
+ * @xsl.usage internal
+ */
+public class ElemEmpty extends ElemTemplateElement
+{
+    static final long serialVersionUID = 7544753713671472252L;
+
+  /**
+   * Constructor ElemEmpty
+   *
+   */
+  public ElemEmpty(){}
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemExsltFuncResult.java b/src/main/java/org/apache/xalan/templates/ElemExsltFuncResult.java
new file mode 100644
index 0000000..32bdbf0
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemExsltFuncResult.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemExsltFuncResult.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Handles the EXSLT result element within an EXSLT function element.
+ */
+public class ElemExsltFuncResult extends ElemVariable
+{
+    static final long serialVersionUID = -3478311949388304563L;
+    /*
+     * To keep the binary compatibility put those three private global 
+     * variables back, although they are never used in this verison
+     */
+    // A flag indicating whether the return result is set
+    private boolean m_isResultSet = false;
+  
+    // The return result
+    private XObject m_result = null;
+  
+    // The frame size of the current caller
+    private int m_callerFrameSize = 0;
+ 
+  /**
+   * Generate the EXSLT function return value, and assign it to the variable
+   * index slot assigned for it in ElemExsltFunction compose().
+   * 
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {    
+    XPathContext context = transformer.getXPathContext();
+
+    // Verify that result has not already been set by another result
+    // element. Recursion is allowed: intermediate results are cleared 
+    // in the owner ElemExsltFunction execute().
+    if (transformer.currentFuncResultSeen()) {
+        throw new TransformerException("An EXSLT function cannot set more than one result!");
+    }
+
+    int sourceNode = context.getCurrentNode();
+
+    // Set the return value;
+    XObject var = getValue(transformer, sourceNode);
+    transformer.popCurrentFuncResult();
+    transformer.pushCurrentFuncResult(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.EXSLT_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.EXSLT_ELEMNAME_FUNCRESULT_STRING;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemExsltFunction.java b/src/main/java/org/apache/xalan/templates/ElemExsltFunction.java
new file mode 100644
index 0000000..acf3374
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemExsltFunction.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemExsltFunction.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.extensions.ExtensionNamespaceSupport;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Implement func:function.
+ * @xsl.usage advanced
+ */
+public class ElemExsltFunction extends ElemTemplate
+{
+    static final long serialVersionUID = 272154954793534771L;
+  /**
+   * 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.EXSLT_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.EXSLT_ELEMNAME_FUNCTION_STRING;
+  }
+  
+  public void execute(TransformerImpl transformer, XObject[] args)
+          throws TransformerException
+  {
+    XPathContext xctxt = transformer.getXPathContext();
+    VariableStack vars = xctxt.getVarStack();
+    
+    // Increment the frame bottom of the variable stack by the
+    // frame size
+    int thisFrame = vars.getStackFrame();
+    int nextFrame = vars.link(m_frameSize);
+
+    if (m_inArgsSize < args.length) {
+      throw new TransformerException ("function called with too many args");
+    }
+    
+    // Set parameters,
+    // have to clear the section of the stack frame that has params.
+    if (m_inArgsSize > 0) {
+      vars.clearLocalSlots(0, m_inArgsSize);
+
+      if (args.length > 0) {
+        vars.setStackFrame(thisFrame);
+        NodeList children = this.getChildNodes();
+        
+        for (int i = 0; i < args.length; i ++) {
+          Node child = children.item(i);
+          if (children.item(i) instanceof ElemParam) {
+            ElemParam param = (ElemParam)children.item(i);
+            vars.setLocalVariable(param.getIndex(), args[i], nextFrame);
+          }
+        }
+        
+        vars.setStackFrame(nextFrame);
+      }
+    }
+
+    //  Removed ElemTemplate 'push' and 'pop' of RTFContext, in order to avoid losing the RTF context 
+    //  before a value can be returned. ElemExsltFunction operates in the scope of the template that called 
+    //  the function.
+    //  xctxt.pushRTFContext();
+    
+    vars.setStackFrame(nextFrame);
+    transformer.executeChildTemplates(this, true);
+    
+    // Reset the stack frame after the function call
+    vars.unlink(thisFrame);
+
+    // Following ElemTemplate 'pop' removed -- see above.
+    // xctxt.popRTFContext(); 
+    
+  }
+        
+  /**
+   * 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.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    
+    // Register the function namespace (if not already registered).
+    String namespace = getName().getNamespace();
+    String handlerClass = sroot.getExtensionHandlerClass();
+    Object[] args ={namespace, sroot};
+    ExtensionNamespaceSupport extNsSpt = 
+                         new ExtensionNamespaceSupport(namespace, handlerClass, args);
+    sroot.getExtensionNamespacesManager().registerExtension(extNsSpt);
+    // Make sure there is a handler for the EXSLT functions namespace
+    // -- for isElementAvailable().    
+    if (!(namespace.equals(Constants.S_EXSLT_FUNCTIONS_URL)))
+    {
+      namespace = Constants.S_EXSLT_FUNCTIONS_URL;
+      args = new Object[]{namespace, sroot};
+      extNsSpt = new ExtensionNamespaceSupport(namespace, handlerClass, args);
+      sroot.getExtensionNamespacesManager().registerExtension(extNsSpt);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemExtensionCall.java b/src/main/java/org/apache/xalan/templates/ElemExtensionCall.java
new file mode 100644
index 0000000..cdbd069
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemExtensionCall.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemExtensionCall.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.extensions.ExtensionHandler;
+import org.apache.xalan.extensions.ExtensionsTable;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.XPathContext;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement an extension element.
+ * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemExtensionCall extends ElemLiteralResult
+{
+    static final long serialVersionUID = 3171339708500216920L;
+
+  /** The Namespace URI for this extension call element.
+   *  @serial          */
+  String m_extns;
+
+  /** Language used by extension.
+   *  @serial          */
+  String m_lang;
+
+  /** URL pointing to extension.
+   *  @serial          */
+  String m_srcURL;
+
+  /** Source for script.
+   *  @serial          */
+  String m_scriptSrc;
+
+  /** Declaration for Extension element. 
+   *  @serial          */
+  ElemExtensionDecl m_decl = null;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   *@return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_EXTENSIONCALL;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+
+  // public String getNodeName()
+  // {
+  // TODO: Need prefix.
+  // return localPart;
+  // }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    m_extns = this.getNamespace();   
+    m_decl = getElemExtensionDecl(sroot, m_extns);
+    // Register the extension namespace if the extension does not have
+    // an ElemExtensionDecl ("component").
+    if (m_decl == null)
+      sroot.getExtensionNamespacesManager().registerExtension(m_extns);
+  }
+ 
+  /**
+   * Return the ElemExtensionDecl for this extension element 
+   *
+   *
+   * @param stylesheet Stylesheet root associated with this extension element
+   * @param namespace Namespace associated with this extension element
+   *
+   * @return the ElemExtensionDecl for this extension element. 
+   */
+  private ElemExtensionDecl getElemExtensionDecl(StylesheetRoot stylesheet,
+          String namespace)
+  {
+
+    ElemExtensionDecl decl = null;
+    int n = stylesheet.getGlobalImportCount();
+
+    for (int i = 0; i < n; i++)
+    {
+      Stylesheet imported = stylesheet.getGlobalImport(i);
+
+      for (ElemTemplateElement child = imported.getFirstChildElem();
+              child != null; child = child.getNextSiblingElem())
+      {
+        if (Constants.ELEMNAME_EXTENSIONDECL == child.getXSLToken())
+        {
+          decl = (ElemExtensionDecl) child;
+
+          String prefix = decl.getPrefix();
+          String declNamespace = child.getNamespaceForPrefix(prefix);
+
+          if (namespace.equals(declNamespace))
+          {
+            return decl;
+          }
+        }
+      }
+    }
+
+    return null;
+  }
+  
+  /**
+   * Execute the fallbacks when an extension is not available.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  private void executeFallbacks(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    for (ElemTemplateElement child = m_firstChild; child != null;
+             child = child.m_nextSibling)
+    {
+      if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
+      {
+        try
+        {
+          transformer.pushElemTemplateElement(child);
+          ((ElemFallback) child).executeFallback(transformer);
+        }
+        finally
+        {
+          transformer.popElemTemplateElement();
+        }
+      }
+    }
+
+  }
+  
+  /**
+   * Return true if this extension element has a <xsl:fallback> child element.
+   *
+   * @return true if this extension element has a <xsl:fallback> child element.
+   */
+  private boolean hasFallbackChildren()
+  {
+    for (ElemTemplateElement child = m_firstChild; child != null;
+             child = child.m_nextSibling)
+    {
+      if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
+        return true;
+    }
+    
+    return false;
+  }
+
+
+  /**
+   * Execute an extension.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer)
+            throws TransformerException
+  {
+    if (transformer.getStylesheet().isSecureProcessing())
+      throw new TransformerException(
+        XSLMessages.createMessage(
+          XSLTErrorResources.ER_EXTENSION_ELEMENT_NOT_ALLOWED_IN_SECURE_PROCESSING,
+          new Object[] {getRawName()}));
+          
+    try
+    {
+      transformer.getResultTreeHandler().flushPending();
+
+      ExtensionsTable etable = transformer.getExtensionsTable();
+      ExtensionHandler nsh = etable.get(m_extns);
+
+      if (null == nsh)
+      {
+        if (hasFallbackChildren())
+        {
+          executeFallbacks(transformer);
+        }
+        else
+        {
+	  TransformerException te = new TransformerException(XSLMessages.createMessage(
+	  	XSLTErrorResources.ER_CALL_TO_EXT_FAILED, new Object[]{getNodeName()}));
+	  transformer.getErrorListener().fatalError(te);
+        }
+        
+        return;
+      }
+
+      try
+      {
+        nsh.processElement(this.getLocalName(), this, transformer,
+                           getStylesheet(), this);
+      }
+      catch (Exception e)
+      {
+
+	if (hasFallbackChildren())
+	  executeFallbacks(transformer);
+	else
+	{
+          if(e instanceof TransformerException)
+          {
+            TransformerException te = (TransformerException)e;
+            if(null == te.getLocator())
+              te.setLocator(this);
+            
+            transformer.getErrorListener().fatalError(te);            
+          }
+          else if (e instanceof RuntimeException)
+          {
+            transformer.getErrorListener().fatalError(new TransformerException(e));
+          }
+          else
+          {
+            transformer.getErrorListener().warning(new TransformerException(e));
+          }
+        }
+      }
+    }
+    catch(TransformerException e)
+    {
+      transformer.getErrorListener().fatalError(e);
+    }
+    catch(SAXException se) {
+      throw new TransformerException(se);
+    }
+  }
+
+  /**
+   * Return the value of the attribute interpreted as an Attribute
+   * Value Template (in other words, you can use curly expressions
+   * such as href="http://{website}".
+   *
+   * @param rawName Raw name of the attribute to get
+   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @return the value of the attribute
+   *
+   * @throws TransformerException
+   */
+  public String getAttribute(
+          String rawName, org.w3c.dom.Node sourceNode, TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    AVT avt = getLiteralResultAttribute(rawName);
+
+    if ((null != avt) && avt.getRawName().equals(rawName))
+    {
+      XPathContext xctxt = transformer.getXPathContext();
+
+      return avt.evaluate(xctxt, 
+            xctxt.getDTMHandleFromNode(sourceNode), 
+            this);
+    }
+
+    return null;
+  }
+  
+  /**
+   * Accept a visitor and call the appropriate method 
+   * for this class.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   * @return true if the children of the object should be visited.
+   */
+  protected boolean accept(XSLTVisitor visitor)
+  {
+  	return visitor.visitExtensionElement(this);
+  }
+
+  
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemExtensionDecl.java b/src/main/java/org/apache/xalan/templates/ElemExtensionDecl.java
new file mode 100644
index 0000000..0e09bfd
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemExtensionDecl.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemExtensionDecl.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.extensions.ExtensionNamespaceSupport;
+import org.apache.xalan.extensions.ExtensionNamespacesManager;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.StringVector;
+
+/**
+ * Implement the declaration of an extension element 
+ * @xsl.usage internal
+ */
+public class ElemExtensionDecl extends ElemTemplateElement
+{
+    static final long serialVersionUID = -4692738885172766789L;
+
+  /**
+   * Constructor ElemExtensionDecl
+   *
+   */
+  public ElemExtensionDecl()
+  {
+
+    // System.out.println("ElemExtensionDecl ctor");
+  }
+
+  /** Prefix string for this extension element.
+   *  @serial         */
+  private String m_prefix = null;
+
+  /**
+   * Set the prefix for this extension element  
+   *
+   *
+   * @param v Prefix to set for this extension element
+   */
+  public void setPrefix(String v)
+  {
+    m_prefix = v;
+  }
+
+  /**
+   * Get the prefix for this extension element
+   *
+   *
+   * @return Prefix for this extension element
+   */
+  public String getPrefix()
+  {
+    return m_prefix;
+  }
+
+  /** StringVector holding the names of functions defined in this extension.
+   *  @serial     */
+  private StringVector m_functions = new StringVector();
+
+  /**
+   * Set the names of functions defined in this extension  
+   *
+   *
+   * @param v StringVector holding the names of functions defined in this extension
+   */
+  public void setFunctions(StringVector v)
+  {
+    m_functions = v;
+  }
+
+  /**
+   * Get the names of functions defined in this extension
+   *
+   *
+   * @return StringVector holding the names of functions defined in this extension
+   */
+  public StringVector getFunctions()
+  {
+    return m_functions;
+  }
+
+  /**
+   * Get a function at a given index in this extension element 
+   *
+   *
+   * @param i Index of function to get
+   *
+   * @return Name of Function at given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public String getFunction(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_functions)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (String) m_functions.elementAt(i);
+  }
+
+  /**
+   * Get count of functions defined in this extension element
+   *
+   *
+   * @return count of functions defined in this extension element
+   */
+  public int getFunctionCount()
+  {
+    return (null != m_functions) ? m_functions.size() : 0;
+  }
+
+  /** StringVector of elements defined in this extension.
+   *  @serial         */
+  private StringVector m_elements = null;
+
+  /**
+   * Set StringVector of elements for this extension
+   *
+   *
+   * @param v StringVector of elements to set
+   */
+  public void setElements(StringVector v)
+  {
+    m_elements = v;
+  }
+
+  /**
+   * Get StringVector of elements defined for this extension  
+   *
+   *
+   * @return StringVector of elements defined for this extension
+   */
+  public StringVector getElements()
+  {
+    return m_elements;
+  }
+
+  /**
+   * Get the element at the given index
+   *
+   *
+   * @param i Index of element to get
+   *
+   * @return The element at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public String getElement(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_elements)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (String) m_elements.elementAt(i);
+  }
+
+  /**
+   * Return the count of elements defined for this extension element 
+   *
+   *
+   * @return the count of elements defined for this extension element
+   */
+  public int getElementCount()
+  {
+    return (null != m_elements) ? m_elements.size() : 0;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_EXTENSIONDECL;
+  }
+  
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    String prefix = getPrefix();
+    String declNamespace = getNamespaceForPrefix(prefix);
+    String lang = null;
+    String srcURL = null;
+    String scriptSrc = null;
+    if (null == declNamespace)
+      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix})); 
+      //"Prefix " + prefix does not have a corresponding namespace declaration");
+    for (ElemTemplateElement child = getFirstChildElem(); child != null;
+          child = child.getNextSiblingElem())
+    {
+      if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken())
+      {
+        ElemExtensionScript sdecl = (ElemExtensionScript) child;
+        lang = sdecl.getLang();
+        srcURL = sdecl.getSrc();
+        ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem();
+        if (null != childOfSDecl)
+        {
+          if (Constants.ELEMNAME_TEXTLITERALRESULT
+                  == childOfSDecl.getXSLToken())
+          {
+            ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl;
+            char[] chars = tl.getChars();
+            scriptSrc = new String(chars);
+            if (scriptSrc.trim().length() == 0)
+              scriptSrc = null;
+          }
+        }
+      }
+    }
+    if (null == lang)
+      lang = "javaclass";
+    if (lang.equals("javaclass") && (scriptSrc != null))
+        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc})); 
+        //"Element content not allowed for lang=javaclass " + scriptSrc);
+
+    // Register the extension namespace if it has not already been registered.
+    ExtensionNamespaceSupport extNsSpt = null;
+    ExtensionNamespacesManager extNsMgr = sroot.getExtensionNamespacesManager();
+    if (extNsMgr.namespaceIndex(declNamespace,
+                                extNsMgr.getExtensions()) == -1)
+    {
+      if (lang.equals("javaclass"))
+      {
+        if (null == srcURL)
+        {
+           extNsSpt = extNsMgr.defineJavaNamespace(declNamespace);
+        }
+        else if (extNsMgr.namespaceIndex(srcURL,
+                                         extNsMgr.getExtensions()) == -1)
+        {
+          extNsSpt = extNsMgr.defineJavaNamespace(declNamespace, srcURL);
+        }
+      }
+      else  // not java
+      {
+        String handler = "org.apache.xalan.extensions.ExtensionHandlerGeneral";
+        Object [] args = {declNamespace, this.m_elements, this.m_functions,
+                          lang, srcURL, scriptSrc, getSystemId()};
+        extNsSpt = new ExtensionNamespaceSupport(declNamespace, handler, args);
+      }
+    }
+    if (extNsSpt != null)
+      extNsMgr.registerExtension(extNsSpt);
+  }
+
+  
+  /**
+   * This function will be called on top-level elements
+   * only, just before the transform begins.
+   *
+   * @param transformer The XSLT TransformerFactory.
+   *
+   * @throws TransformerException
+   */  
+  public void runtimeInit(TransformerImpl transformer) throws TransformerException
+  {
+/*    //System.out.println("ElemExtensionDecl.runtimeInit()");
+    String lang = null;
+    String srcURL = null;
+    String scriptSrc = null;
+    String prefix = getPrefix();
+    String declNamespace = getNamespaceForPrefix(prefix);
+
+    if (null == declNamespace)
+      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix})); 
+      //"Prefix " + prefix does not have a corresponding namespace declaration");
+
+    for (ElemTemplateElement child = getFirstChildElem(); child != null;
+            child = child.getNextSiblingElem())
+    {
+      if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken())
+      {
+        ElemExtensionScript sdecl = (ElemExtensionScript) child;
+
+        lang = sdecl.getLang();
+        srcURL = sdecl.getSrc();
+
+        ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem();
+
+        if (null != childOfSDecl)
+        {
+          if (Constants.ELEMNAME_TEXTLITERALRESULT
+                  == childOfSDecl.getXSLToken())
+          {
+            ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl;
+            char[] chars = tl.getChars();
+
+            scriptSrc = new String(chars);
+
+            if (scriptSrc.trim().length() == 0)
+              scriptSrc = null;
+          }
+        }
+      }
+    }
+
+    if (null == lang)
+      lang = "javaclass";
+
+    if (lang.equals("javaclass") && (scriptSrc != null))
+      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc})); 
+      //"Element content not allowed for lang=javaclass " + scriptSrc);
+    
+    // Instantiate a handler for this extension namespace.
+    ExtensionsTable etable = transformer.getExtensionsTable();    
+    ExtensionHandler nsh = etable.get(declNamespace);
+
+    // If we have no prior ExtensionHandler for this namespace, we need to
+    // create one.
+    // If the script element is for javaclass, this is our special compiled java.
+    // Element content is not supported for this so we throw an exception if
+    // it is provided.  Otherwise, we look up the srcURL to see if we already have
+    // an ExtensionHandler.
+    if (null == nsh)
+    {
+      if (lang.equals("javaclass"))
+      {
+        if (null == srcURL)
+        {
+          nsh = etable.makeJavaNamespace(declNamespace);
+        }
+        else
+        {
+          nsh = etable.get(srcURL);
+
+          if (null == nsh)
+          {
+            nsh = etable.makeJavaNamespace(srcURL);
+          }
+        }
+      }
+      else  // not java
+      {
+        nsh = new ExtensionHandlerGeneral(declNamespace, this.m_elements,
+                                          this.m_functions, lang, srcURL,
+                                          scriptSrc, getSystemId());
+
+        // System.out.println("Adding NS Handler: declNamespace = "+
+        //                   declNamespace+", lang = "+lang+", srcURL = "+
+        //                   srcURL+", scriptSrc="+scriptSrc);
+      }
+
+      etable.addExtensionNamespace(declNamespace, nsh);
+    }*/
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemExtensionScript.java b/src/main/java/org/apache/xalan/templates/ElemExtensionScript.java
new file mode 100644
index 0000000..0233768
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemExtensionScript.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemExtensionScript.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+/**
+ * Implement Script extension element
+ * @xsl.usage internal
+ */
+public class ElemExtensionScript extends ElemTemplateElement
+{
+    static final long serialVersionUID = -6995978265966057744L;
+
+  /**
+   * Constructor ElemExtensionScript
+   *
+   */
+  public ElemExtensionScript()
+  {
+
+    // System.out.println("ElemExtensionScript ctor");
+  }
+
+  /** Language used in extension.
+   *  @serial          */
+  private String m_lang = null;
+
+  /**
+   * Set language used by extension
+   *
+   *
+   * @param v Language used by extension
+   */
+  public void setLang(String v)
+  {
+    m_lang = v;
+  }
+
+  /**
+   * Get language used by extension
+   *
+   *
+   * @return Language used by extension
+   */
+  public String getLang()
+  {
+    return m_lang;
+  }
+
+  /** Extension handler.
+   *  @serial          */
+  private String m_src = null;
+
+  /**
+   * Set Extension handler name for this extension
+   *
+   *
+   * @param v Extension handler name to set
+   */
+  public void setSrc(String v)
+  {
+    m_src = v;
+  }
+
+  /**
+   * Get Extension handler name for this extension
+   *
+   *
+   * @return Extension handler name
+   */
+  public String getSrc()
+  {
+    return m_src;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element 
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_EXTENSIONSCRIPT;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemFallback.java b/src/main/java/org/apache/xalan/templates/ElemFallback.java
new file mode 100644
index 0000000..914cdf5
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemFallback.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemFallback.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+
+/**
+ * Implement xsl:fallback.
+ * <pre>
+ * <!ELEMENT xsl:fallback %template;>
+ * <!ATTLIST xsl:fallback %space-att;>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#fallback">fallback in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemFallback extends ElemTemplateElement
+{
+    static final long serialVersionUID = 1782962139867340703L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_FALLBACK;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The Element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_FALLBACK_STRING;
+  }
+
+  /**
+   * This is the normal call when xsl:fallback is instantiated.
+   * In accordance with the XSLT 1.0 Recommendation, chapter 15,
+   * "Normally, instantiating an xsl:fallback element does nothing."
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+  }
+
+  /**
+   * Execute the fallback elements.  This must be explicitly called to
+   * instantiate the content of an xsl:fallback element.
+   * When an XSLT transformer performs fallback for an instruction
+   * element, if the instruction element has one or more xsl:fallback
+   * children, then the content of each of the xsl:fallback children
+   * must be instantiated in sequence; otherwise, an error must
+   * be signaled. The content of an xsl:fallback element is a template.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void executeFallback(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    int parentElemType = m_parentNode.getXSLToken();
+    if (Constants.ELEMNAME_EXTENSIONCALL == parentElemType 
+        || Constants.ELEMNAME_UNDEFINED == parentElemType)
+    {
+
+      transformer.executeChildTemplates(this, true);
+
+    }
+    else
+    {
+
+      // Should never happen
+      System.out.println(
+        "Error!  parent of xsl:fallback must be an extension or unknown element!");
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemForEach.java b/src/main/java/org/apache/xalan/templates/ElemForEach.java
new file mode 100644
index 0000000..72b3d7a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemForEach.java
@@ -0,0 +1,494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemForEach.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.NodeSorter;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.IntStack;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+
+import java.io.ObjectInputStream;
+import java.io.IOException;
+
+/**
+ * Implement xsl:for-each.
+ * <pre>
+ * <!ELEMENT xsl:for-each
+ *  (#PCDATA
+ *   %instructions;
+ *   %result-elements;
+ *   | xsl:sort)
+ * >
+ *
+ * <!ATTLIST xsl:for-each
+ *   select %expr; #REQUIRED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#for-each">for-each in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
+{
+    static final long serialVersionUID = 6018140636363583690L;
+  /** Set true to request some basic status reports */
+  static final boolean DEBUG = false;
+  
+  /**
+   * This is set by an "xalan-doc-cache-off" pi, or the old "xalan:doc-cache-off" pi.
+   * The old form of the PI only works for XML parsers that are not namespace aware.
+   * It tells the engine that
+   * documents created in the location paths executed by this element
+   * will not be reparsed. It's set by StylesheetHandler during
+   * construction. Note that this feature applies _only_ to xsl:for-each
+   * elements in its current incarnation; a more general cache management
+   * solution is desperately needed.
+   */
+  public boolean m_doc_cache_off=false;
+  
+  /**
+   * Construct a element representing xsl:for-each.
+   */
+  public ElemForEach(){}
+
+  /**
+   * The "select" expression.
+   * @serial
+   */
+  protected Expression m_selectExpression = null;
+  
+  
+  /**
+   * Used to fix bug#16889
+   * Store XPath away for later processing.
+   */
+  protected XPath m_xpath = null;  
+
+  /**
+   * Set the "select" attribute.
+   *
+   * @param xpath The XPath expression for the "select" attribute.
+   */
+  public void setSelect(XPath xpath)
+  {
+    m_selectExpression = xpath.getExpression();
+    
+    // The following line is part of the codes added to fix bug#16889
+    // Store xpath which will be needed when firing Selected Event
+    m_xpath = xpath;    
+  }
+
+  /**
+   * Get the "select" attribute.
+   *
+   * @return The XPath expression for the "select" attribute.
+   */
+  public Expression getSelect()
+  {
+    return m_selectExpression;
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   *
+   * NEEDSDOC @param sroot
+   *
+   * @throws TransformerException
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+
+    super.compose(sroot);
+
+    int length = getSortElemCount();
+
+    for (int i = 0; i < length; i++)
+    {
+      getSortElem(i).compose(sroot);
+    }
+
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+    if (null != m_selectExpression)
+      m_selectExpression.fixupVariables(
+        vnames, sroot.getComposeState().getGlobalsSize());
+    else
+    {
+      m_selectExpression =
+        getStylesheetRoot().m_selectDefault.getExpression();
+    }
+  }
+  
+  /**
+   * This after the template's children have been composed.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+    int length = getSortElemCount();
+
+    for (int i = 0; i < length; i++)
+    {
+      getSortElem(i).endCompose(sroot);
+    }
+    
+    super.endCompose(sroot);
+  }
+
+
+  //  /**
+  //   * This function is called after everything else has been
+  //   * recomposed, and allows the template to set remaining
+  //   * values that may be based on some other property that
+  //   * depends on recomposition.
+  //   *
+  //   * @throws TransformerException
+  //   */
+  //  public void compose() throws TransformerException
+  //  {
+  //
+  //    if (null == m_selectExpression)
+  //    {
+  //      m_selectExpression =
+  //        getStylesheetRoot().m_selectDefault.getExpression();
+  //    }
+  //  }
+
+  /**
+   * Vector containing the xsl:sort elements associated with this element.
+   *  @serial
+   */
+  protected Vector m_sortElems = null;
+
+  /**
+   * Get the count xsl:sort elements associated with this element.
+   * @return The number of xsl:sort elements.
+   */
+  public int getSortElemCount()
+  {
+    return (m_sortElems == null) ? 0 : m_sortElems.size();
+  }
+
+  /**
+   * Get a xsl:sort element associated with this element.
+   *
+   * @param i Index of xsl:sort element to get
+   *
+   * @return xsl:sort element at given index
+   */
+  public ElemSort getSortElem(int i)
+  {
+    return (ElemSort) m_sortElems.elementAt(i);
+  }
+
+  /**
+   * Set a xsl:sort element associated with this element.
+   *
+   * @param sortElem xsl:sort element to set
+   */
+  public void setSortElem(ElemSort sortElem)
+  {
+
+    if (null == m_sortElems)
+      m_sortElems = new Vector();
+
+    m_sortElems.addElement(sortElem);
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_FOREACH;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_FOREACH_STRING;
+  }
+
+  /**
+   * Execute the xsl:for-each transformation
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    transformer.pushCurrentTemplateRuleIsNull(true);    
+    try
+    {
+      transformSelectedNodes(transformer);
+    }
+    finally
+    {
+      transformer.popCurrentTemplateRuleIsNull();
+    }
+  }
+
+  /**
+   * Get template element associated with this
+   *
+   *
+   * @return template element associated with this (itself)
+   */
+  protected ElemTemplateElement getTemplateMatch()
+  {
+    return this;
+  }
+
+  /**
+   * Sort given nodes
+   *
+   *
+   * @param xctxt The XPath runtime state for the sort.
+   * @param keys Vector of sort keyx
+   * @param sourceNodes Iterator of nodes to sort
+   *
+   * @return iterator of sorted nodes
+   *
+   * @throws TransformerException
+   */
+  public DTMIterator sortNodes(
+          XPathContext xctxt, Vector keys, DTMIterator sourceNodes)
+            throws TransformerException
+  {
+
+    NodeSorter sorter = new NodeSorter(xctxt);
+    sourceNodes.setShouldCacheNodes(true);
+    sourceNodes.runTo(-1);
+    xctxt.pushContextNodeList(sourceNodes);
+
+    try
+    {
+      sorter.sort(sourceNodes, keys, xctxt);
+      sourceNodes.setCurrentPos(0);
+    }
+    finally
+    {
+      xctxt.popContextNodeList();
+    }
+
+    return sourceNodes;
+  }
+
+  /**
+   * Perform a query if needed, and call transformNode for each child.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException Thrown in a variety of circumstances.
+   * @xsl.usage advanced
+   */
+  public void transformSelectedNodes(TransformerImpl transformer)
+          throws TransformerException
+  {
+
+    final XPathContext xctxt = transformer.getXPathContext();
+    final int sourceNode = xctxt.getCurrentNode();
+    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt,
+            sourceNode);
+
+    try
+    {
+
+      final Vector keys = (m_sortElems == null)
+              ? null
+              : transformer.processSortKeys(this, sourceNode);
+
+      // Sort if we need to.
+      if (null != keys)
+        sourceNodes = sortNodes(xctxt, keys, sourceNodes);
+
+      xctxt.pushCurrentNode(DTM.NULL);
+
+      IntStack currentNodes = xctxt.getCurrentNodeStack();
+
+      xctxt.pushCurrentExpressionNode(DTM.NULL);
+
+      IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
+
+      xctxt.pushSAXLocatorNull();
+      xctxt.pushContextNodeList(sourceNodes);
+      transformer.pushElemTemplateElement(null);
+
+      // pushParams(transformer, xctxt);
+      // Should be able to get this from the iterator but there must be a bug.
+      DTM dtm = xctxt.getDTM(sourceNode);
+      int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
+      int child;
+
+      while (DTM.NULL != (child = sourceNodes.nextNode()))
+      {
+        currentNodes.setTop(child);
+        currentExpressionNodes.setTop(child);
+
+        if ((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
+        {
+          dtm = xctxt.getDTM(child);
+          docID = child & DTMManager.IDENT_DTM_DEFAULT;
+        }
+
+        //final int exNodeType = dtm.getExpandedTypeID(child);
+        final int nodeType = dtm.getNodeType(child); 
+
+        // And execute the child templates.
+        // Loop through the children of the template, calling execute on 
+        // each of them.
+        for (ElemTemplateElement t = this.m_firstChild; t != null;
+             t = t.m_nextSibling)
+        {
+          xctxt.setSAXLocator(t);
+          transformer.setCurrentElement(t);
+          t.execute(transformer);
+        }
+
+        // KLUGE: Implement <?xalan:doc_cache_off?>
+	 	// ASSUMPTION: This will be set only when the XPath was indeed
+	 	// a call to the Document() function. Calling it in other
+	 	// situations is likely to fry Xalan.
+	 	//
+	 	// %REVIEW% We need a MUCH cleaner solution -- one that will
+	 	// handle cleaning up after document() and getDTM() in other
+		// contexts. The whole SourceTreeManager mechanism should probably
+	 	// be moved into DTMManager rather than being explicitly invoked in
+	 	// FuncDocument and here.
+	 	if(m_doc_cache_off)
+		{
+	 	  if(DEBUG)
+	 	    System.out.println("JJK***** CACHE RELEASE *****\n"+
+				       "\tdtm="+dtm.getDocumentBaseURI());
+	  	// NOTE: This will work because this is _NOT_ a shared DTM, and thus has
+	  	// only a single Document node. If it could ever be an RTF or other
+	 	// shared DTM, this would require substantial rework.
+	 	  xctxt.getSourceTreeManager().removeDocumentFromCache(dtm.getDocument());
+	 	  xctxt.release(dtm,false);
+	 	}
+      }
+    }
+    finally
+    {
+      xctxt.popSAXLocator();
+      xctxt.popContextNodeList();
+      transformer.popElemTemplateElement();
+      xctxt.popCurrentExpressionNode();
+      xctxt.popCurrentNode();
+      sourceNodes.detach();
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   * <!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
+   * <!ATTLIST xsl:apply-templates
+   *   select %expr; "node()"
+   *   mode %qname; #IMPLIED
+   * >
+   *
+   * @param newChild Child to add to child list
+   *
+   * @return Child just added to child list
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    if (Constants.ELEMNAME_SORT == type)
+    {
+      setSortElem((ElemSort) newChild);
+
+      return newChild;
+    }
+    else
+      return super.appendChild(newChild);
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)
+  {
+  	if(callAttributes && (null != m_selectExpression))
+  		m_selectExpression.callVisitors(this, visitor);
+  		
+    int length = getSortElemCount();
+
+    for (int i = 0; i < length; i++)
+    {
+      getSortElem(i).callVisitors(visitor);
+    }
+
+    super.callChildVisitors(visitor, callAttributes);
+  }
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_selectExpression;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_selectExpression = exp;
+  }
+
+  /*
+   * to keep the binary compatibility, assign a default value for newly added
+   * globel varialbe m_xpath during deserialization of an object which was 
+   * serialized using an older version
+   */
+   private void readObject(ObjectInputStream os) throws 
+        IOException, ClassNotFoundException {
+           os.defaultReadObject();
+           m_xpath = null;
+   }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemIf.java b/src/main/java/org/apache/xalan/templates/ElemIf.java
new file mode 100644
index 0000000..27814d9
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemIf.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemIf.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implement xsl:if.
+ * <pre>
+ * <!ELEMENT xsl:if %template;>
+ * <!ATTLIST xsl:if
+ *   test %expr; #REQUIRED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:if">XXX in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemIf extends ElemTemplateElement
+{
+    static final long serialVersionUID = 2158774632427453022L;
+
+  /**
+   * The xsl:if element must have a test attribute, which specifies an expression.
+   * @serial
+   */
+  private XPath m_test = null;
+
+  /**
+   * Set the "test" attribute.
+   * The xsl:if element must have a test attribute, which specifies an expression.
+   *
+   * @param v test attribute to set
+   */
+  public void setTest(XPath v)
+  {
+    m_test = v;
+  }
+
+  /**
+   * Get the "test" attribute.
+   * The xsl:if element must have a test attribute, which specifies an expression.
+   *
+   * @return the "test" attribute for this element.
+   */
+  public XPath getTest()
+  {
+    return m_test;
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   *
+   * @param sroot The root stylesheet.
+   *
+   * @throws TransformerException
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+
+    super.compose(sroot);
+
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+    if (null != m_test)
+      m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_IF;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return the element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_IF_STRING;
+  }
+
+  /**
+   * Conditionally execute a sub-template.
+   * The expression is evaluated and the resulting object is converted
+   * to a boolean as if by a call to the boolean function. If the result
+   * is true, then the content template is instantiated; otherwise, nothing
+   * is created.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    XPathContext xctxt = transformer.getXPathContext();
+    int sourceNode = xctxt.getCurrentNode();
+
+      if (m_test.bool(xctxt, sourceNode, this)) {
+          transformer.executeChildTemplates(this, true);
+      }
+
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  		m_test.getExpression().callVisitors(m_test, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemLiteralResult.java b/src/main/java/org/apache/xalan/templates/ElemLiteralResult.java
new file mode 100644
index 0000000..3fc7db2
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemLiteralResult.java
@@ -0,0 +1,1478 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemLiteralResult.java 476350 2006-11-17 22:53:23Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.StringVector;
+import org.apache.xpath.XPathContext;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.TypeInfo;
+import org.w3c.dom.UserDataHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement a Literal Result Element.
+ * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemLiteralResult extends ElemUse
+{
+    static final long serialVersionUID = -8703409074421657260L;
+
+    /** The return value as Empty String. */
+    private static final String EMPTYSTRING = "";
+
+  /**
+   * Tells if this element represents a root element
+   * that is also the stylesheet element.
+   * TODO: This should be a derived class.
+   * @serial
+   */
+  private boolean isLiteralResultAsStylesheet = false;
+
+  /**
+   * Set whether this element represents a root element
+   * that is also the stylesheet element.
+   *
+   *
+   * @param b boolean flag indicating whether this element
+   * represents a root element that is also the stylesheet element.
+   */
+  public void setIsLiteralResultAsStylesheet(boolean b)
+  {
+    isLiteralResultAsStylesheet = b;
+  }
+
+  /**
+   * Return whether this element represents a root element
+   * that is also the stylesheet element.
+   *
+   *
+   * @return boolean flag indicating whether this element
+   * represents a root element that is also the stylesheet element.
+   */
+  public boolean getIsLiteralResultAsStylesheet()
+  {
+    return isLiteralResultAsStylesheet;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    java.util.Vector vnames = cstate.getVariableNames();
+    if (null != m_avts)
+    {
+      int nAttrs = m_avts.size();
+
+      for (int i = (nAttrs - 1); i >= 0; i--)
+      {
+        AVT avt = (AVT) m_avts.get(i);
+        avt.fixupVariables(vnames, cstate.getGlobalsSize());
+      } 
+    }   
+  }
+  
+  /**
+   * The created element node will have the attribute nodes
+   * that were present on the element node in the stylesheet tree,
+   * other than attributes with names in the XSLT namespace.
+   * @serial
+   */
+  private List m_avts = null;
+
+  /** List of attributes with the XSLT namespace.
+   *  @serial */
+  private List m_xslAttr = null;
+
+  /**
+   * Set a literal result attribute (AVTs only).
+   *
+   * @param avt literal result attribute to add (AVT only)
+   */
+  public void addLiteralResultAttribute(AVT avt)
+  {
+
+    if (null == m_avts)
+      m_avts = new ArrayList();
+
+    m_avts.add(avt);
+  }
+
+  /**
+   * Set a literal result attribute (used for xsl attributes).
+   *
+   * @param att literal result attribute to add
+   */
+  public void addLiteralResultAttribute(String att)
+  {
+
+    if (null == m_xslAttr)
+      m_xslAttr = new ArrayList();
+
+    m_xslAttr.add(att);
+  }
+  
+  /**
+   * Set the "xml:space" attribute.
+   * A text node is preserved if an ancestor element of the text node
+   * has an xml:space attribute with a value of preserve, and
+   * no closer ancestor element has xml:space with a value of default.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text in XSLT Specification</a>
+   *
+   * @param avt  Enumerated value, either Constants.ATTRVAL_PRESERVE 
+   * or Constants.ATTRVAL_STRIP.
+   */
+  public void setXmlSpace(AVT avt)
+  {
+    // This function is a bit-o-hack, I guess...
+    addLiteralResultAttribute(avt);
+    String val = avt.getSimpleString();
+    if(val.equals("default"))
+    {
+      super.setXmlSpace(Constants.ATTRVAL_STRIP);
+    }
+    else if(val.equals("preserve"))
+    {
+      super.setXmlSpace(Constants.ATTRVAL_PRESERVE);
+    }
+    // else maybe it's a real AVT, so we can't resolve it at this time.
+  }
+
+  /**
+   * Get a literal result attribute by name.
+   *
+   * @param namespaceURI Namespace URI of attribute node to get
+   * @param localName Local part of qualified name of attribute node to get
+   *
+   * @return literal result attribute (AVT)
+   */
+  public AVT getLiteralResultAttributeNS(String namespaceURI, String localName)
+  {
+
+    if (null != m_avts)
+    {
+      int nAttrs = m_avts.size();
+
+      for (int i = (nAttrs - 1); i >= 0; i--)
+      {
+        AVT avt = (AVT) m_avts.get(i);
+
+        if (avt.getName().equals(localName) && 
+                avt.getURI().equals(namespaceURI))
+        {
+          return avt;
+        }
+      }  // end for
+    }
+
+    return null;
+  }
+
+  /**
+   * Return the raw value of the attribute.
+   *
+   * @param namespaceURI Namespace URI of attribute node to get
+   * @param localName Local part of qualified name of attribute node to get
+   *
+   * @return The Attr value as a string, or the empty string if that attribute 
+   * does not have a specified or default value
+   */
+  public String getAttributeNS(String namespaceURI, String localName)
+  {
+
+    AVT avt = getLiteralResultAttributeNS(namespaceURI, localName);
+
+    if ((null != avt))
+    {
+      return avt.getSimpleString();
+    }
+
+    return EMPTYSTRING;
+  }
+
+  /**
+   * Get a literal result attribute by name. The name is namespaceURI:localname  
+   * if namespace is not null.
+   *
+   * @param name Name of literal result attribute to get
+   *
+   * @return literal result attribute (AVT)
+   */
+  public AVT getLiteralResultAttribute(String name)
+  {
+
+    if (null != m_avts)
+    {
+      int nAttrs = m_avts.size();
+      String namespace = null;
+      for (int i = (nAttrs - 1); i >= 0; i--)
+      {
+        AVT avt = (AVT) m_avts.get(i);
+        namespace = avt.getURI();
+        
+        if ((namespace != null && (!namespace.equals("")) && (namespace 
+                +":"+avt.getName()).equals(name))|| ((namespace == null || 
+                namespace.equals(""))&& avt.getRawName().equals(name)))
+        {
+          return avt;
+        }
+      }  // end for
+    }
+
+    return null;
+  }
+
+  /**
+   * Return the raw value of the attribute.
+   *
+   * @param namespaceURI:localName or localName if the namespaceURI is null of 
+   * the attribute to get
+   *
+   * @return The Attr value as a string, or the empty string if that attribute 
+   * does not have a specified or default value
+   */
+  public String getAttribute(String rawName)
+  {
+
+    AVT avt = getLiteralResultAttribute(rawName);
+
+    if ((null != avt))
+    {
+      return avt.getSimpleString();
+    }
+
+    return EMPTYSTRING;
+  }
+  
+  /**
+   * Get whether or not the passed URL is flagged by
+   * the "extension-element-prefixes" or "exclude-result-prefixes"
+   * properties.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param prefix non-null reference to prefix that might be excluded.(not currently used)
+   * @param uri reference to namespace that prefix maps to
+   *
+   * @return true if the prefix should normally be excluded.
+   */
+  public boolean containsExcludeResultPrefix(String prefix, String uri)
+  {
+    if (uri == null ||
+                (null == m_excludeResultPrefixes &&
+                 null == m_ExtensionElementURIs)
+                )
+      return super.containsExcludeResultPrefix(prefix, uri);
+
+    if (prefix.length() == 0)
+      prefix = Constants.ATTRVAL_DEFAULT_PREFIX;
+
+    // This loop is ok here because this code only runs during
+    // stylesheet compile time.    
+        if(m_excludeResultPrefixes!=null)
+            for (int i =0; i< m_excludeResultPrefixes.size(); i++)
+            {
+                if (uri.equals(getNamespaceForPrefix(m_excludeResultPrefixes.elementAt(i))))
+                    return true;
+            }    
+        
+        // JJK Bugzilla 1133: Also check locally-scoped extensions
+    if(m_ExtensionElementURIs!=null && m_ExtensionElementURIs.contains(uri))
+       return true;
+
+        return super.containsExcludeResultPrefix(prefix, uri);
+  }
+
+  /**
+   * Augment resolvePrefixTables, resolving the namespace aliases once
+   * the superclass has resolved the tables.
+   *
+   * @throws TransformerException
+   */
+  public void resolvePrefixTables() throws TransformerException
+  {
+
+    super.resolvePrefixTables();
+
+    StylesheetRoot stylesheet = getStylesheetRoot();
+
+    if ((null != m_namespace) && (m_namespace.length() > 0))
+    {
+      NamespaceAlias nsa = stylesheet.getNamespaceAliasComposed(m_namespace);
+
+      if (null != nsa)
+      {
+        m_namespace = nsa.getResultNamespace();
+
+        // String resultPrefix = nsa.getResultPrefix();
+        String resultPrefix = nsa.getStylesheetPrefix();  // As per xsl WG, Mike Kay
+
+        if ((null != resultPrefix) && (resultPrefix.length() > 0))
+          m_rawName = resultPrefix + ":" + m_localName;
+        else
+          m_rawName = m_localName;
+      }
+    }
+
+    if (null != m_avts)
+    {
+      int n = m_avts.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        AVT avt = (AVT) m_avts.get(i);
+
+        // Should this stuff be a method on AVT?
+        String ns = avt.getURI();
+
+        if ((null != ns) && (ns.length() > 0))
+        {
+          NamespaceAlias nsa =
+            stylesheet.getNamespaceAliasComposed(m_namespace); // %REVIEW% ns?
+
+          if (null != nsa)
+          {
+            String namespace = nsa.getResultNamespace();
+
+            // String resultPrefix = nsa.getResultPrefix();
+            String resultPrefix = nsa.getStylesheetPrefix();  // As per XSL WG
+            String rawName = avt.getName();
+
+            if ((null != resultPrefix) && (resultPrefix.length() > 0))
+              rawName = resultPrefix + ":" + rawName;
+
+            avt.setURI(namespace);
+            avt.setRawName(rawName);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Return whether we need to check namespace prefixes
+   * against the exclude result prefixes or extensions lists.
+   * Note that this will create a new prefix table if one
+   * has not been created already.
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  boolean needToCheckExclude()
+  {
+    if (null == m_excludeResultPrefixes && null == getPrefixTable()
+                && m_ExtensionElementURIs==null     // JJK Bugzilla 1133
+                )
+      return false;
+    else
+    {
+
+      // Create a new prefix table if one has not already been created.
+      if (null == getPrefixTable())
+        setPrefixTable(new java.util.ArrayList());
+
+      return true;
+    }
+  }
+
+  /**
+   * The namespace of the element to be created.
+   * @serial
+   */
+  private String m_namespace;
+
+  /**
+   * Set the namespace URI of the result element to be created.
+   * Note that after resolvePrefixTables has been called, this will
+   * return the aliased result namespace, not the original stylesheet
+   * namespace.
+   *
+   * @param ns The Namespace URI, or the empty string if the
+   *        element has no Namespace URI.
+   */
+  public void setNamespace(String ns)
+  {
+    if(null == ns) // defensive, shouldn't have to do this.
+      ns = "";
+    m_namespace = ns;
+  }
+
+  /**
+   * Get the original namespace of the Literal Result Element.
+   * 
+   * %REVIEW% Why isn't this overriding the getNamespaceURI method
+   * rather than introducing a new one?
+   *
+   * @return The Namespace URI, or the empty string if the
+   *        element has no Namespace URI.
+   */
+  public String getNamespace()
+  {
+    return m_namespace;
+  }
+
+  /**
+   * The local name of the element to be created.
+   * @serial
+   */
+  private String m_localName;
+
+  /**
+   * Set the local name of the LRE.
+   *
+   * @param localName The local name (without prefix) of the result element
+   *                  to be created.
+   */
+  public void setLocalName(String localName)
+  {
+    m_localName = localName;
+  }
+
+  /**
+   * Get the local name of the Literal Result Element.
+   * Note that after resolvePrefixTables has been called, this will
+   * return the aliased name prefix, not the original stylesheet
+   * namespace prefix.
+   *
+   * @return The local name (without prefix) of the result element
+   *                  to be created.
+   */
+  public String getLocalName()
+  {
+    return m_localName;
+  }
+
+  /**
+   * The raw name of the element to be created.
+   * @serial
+   */
+  private String m_rawName;
+
+  /**
+   * Set the raw name of the LRE.
+   *
+   * @param rawName The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   */
+  public void setRawName(String rawName)
+  {
+    m_rawName = rawName;
+  }
+
+  /**
+   * Get the raw name of the Literal Result Element.
+   *
+   * @return  The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   */
+  public String getRawName()
+  {
+    return m_rawName;
+  }
+    
+ /**
+   * Get the prefix part of the raw name of the Literal Result Element.
+   *
+   * @return The prefix, or the empty string if noprefix was provided.
+   */
+  public String getPrefix()
+  {
+        int len=m_rawName.length()-m_localName.length()-1;
+    return (len>0)
+            ? m_rawName.substring(0,len)
+            : "";
+  }
+
+
+  /**
+   * The "extension-element-prefixes" property, actually contains URIs.
+   * @serial
+   */
+  private StringVector m_ExtensionElementURIs;
+
+  /**
+   * Set the "extension-element-prefixes" property.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param v Vector of URIs (not prefixes) to set as the "extension-element-prefixes" property
+   */
+  public void setExtensionElementPrefixes(StringVector v)
+  {
+    m_ExtensionElementURIs = v;
+  }
+
+  /**
+   * @see org.w3c.dom.Node
+   *
+   * @return NamedNodeMap
+   */
+  public NamedNodeMap getAttributes()
+  {
+        return new LiteralElementAttributes();
+  }
+
+  public class LiteralElementAttributes implements NamedNodeMap{
+          private int m_count = -1;
+          
+          /**
+           * Construct a NameNodeMap.
+           *
+           */
+          public LiteralElementAttributes(){         
+          }
+          
+          /**
+           * Return the number of Attributes on this Element
+           *
+           * @return The number of nodes in this map. The range of valid child 
+           * node indices is <code>0</code> to <code>length-1</code> inclusive
+           */
+          public int getLength()
+          {
+            if (m_count == -1)
+            {
+               if (null != m_avts) m_count = m_avts.size();
+               else m_count = 0;
+            }
+            return m_count;
+          }
+
+          /**
+           * Retrieves a node specified by name.
+           * @param name The <code>nodeName</code> of a node to retrieve.
+           * @return A <code>Node</code> (of any type) with the specified
+           *   <code>nodeName</code>, or <code>null</code> if it does not 
+           *   identify any node in this map.
+           */
+          public Node getNamedItem(String name)
+          {
+                if (getLength() == 0) return null;
+                String uri = null;
+                String localName = name; 
+                int index = name.indexOf(":"); 
+                if (-1 != index){
+                         uri = name.substring(0, index);
+                         localName = name.substring(index+1);
+                }
+                Node retNode = null;
+                Iterator eum = m_avts.iterator();
+                while (eum.hasNext()){
+                        AVT avt = (AVT) eum.next();
+                        if (localName.equals(avt.getName()))
+                        {
+                          String nsURI = avt.getURI(); 
+                          if ((uri == null && nsURI == null)
+                            || (uri != null && uri.equals(nsURI)))
+                          {
+                            retNode = new Attribute(avt, ElemLiteralResult.this);
+                            break;
+                          }
+                        }
+                }
+                return retNode;
+          }
+
+          /**
+           * Retrieves a node specified by local name and namespace URI.
+           * @param namespaceURI Namespace URI of attribute node to get
+           * @param localName Local part of qualified name of attribute node to 
+           * get
+           * @return A <code>Node</code> (of any type) with the specified
+           *   <code>nodeName</code>, or <code>null</code> if it does not 
+           *   identify any node in this map.
+           */
+          public Node getNamedItemNS(String namespaceURI, String localName)
+          {
+                  if (getLength() == 0) return null;
+                  Node retNode = null;
+                  Iterator eum = m_avts.iterator();
+                  while (eum.hasNext())
+                  {
+                    AVT avt = (AVT) eum.next();      
+                    if (localName.equals(avt.getName()))
+                    {
+                      String nsURI = avt.getURI(); 
+                      if ((namespaceURI == null && nsURI == null)
+                        || (namespaceURI != null && namespaceURI.equals(nsURI)))
+                      {
+                        retNode = new Attribute(avt, ElemLiteralResult.this);
+                        break;
+                      }
+                    }
+                  }
+                  return retNode;
+          }
+          
+          /**
+           * Returns the <code>index</code>th item in the map. If <code>index
+           * </code> is greater than or equal to the number of nodes in this 
+           * map, this returns <code>null</code>.
+           * @param i The index of the requested item.
+           * @return The node at the <code>index</code>th position in the map, 
+           *   or <code>null</code> if that is not a valid index.
+           */
+          public Node item(int i)
+          {
+                if (getLength() == 0 || i >= m_avts.size()) return null;
+                else return 
+                    new Attribute(((AVT)m_avts.get(i)), 
+                        ElemLiteralResult.this);
+          }
+          
+          /**
+           * @see org.w3c.dom.NamedNodeMap
+           *
+           * @param name of the node to remove
+           * 
+           * @return The node removed from this map if a node with such 
+           * a name exists. 
+           *
+           * @throws DOMException
+           */
+          public Node removeNamedItem(String name) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }
+          
+          /**
+           * @see org.w3c.dom.NamedNodeMap
+           *
+           * @param namespaceURI Namespace URI of the node to remove
+           * @param localName Local part of qualified name of the node to remove
+           * 
+           * @return The node removed from this map if a node with such a local
+           *  name and namespace URI exists
+           *
+           * @throws DOMException
+           */
+          public Node removeNamedItemNS(String namespaceURI, String localName) 
+                throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          } 
+          
+          /**
+           * Unimplemented. See org.w3c.dom.NamedNodeMap
+           *
+           * @param A node to store in this map
+           * 
+           * @return If the new Node replaces an existing node the replaced 
+           * Node is returned, otherwise null is returned
+           *
+           * @throws DOMException
+           */
+          public Node setNamedItem(Node arg) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }
+          
+          /**
+           * Unimplemented. See org.w3c.dom.NamedNodeMap
+           *
+           * @param A node to store in this map
+           * 
+           * @return If the new Node replaces an existing node the replaced 
+           * Node is returned, otherwise null is returned
+           *
+           * @throws DOMException
+           */
+          public Node setNamedItemNS(Node arg) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }                                                                         
+  }
+
+  public class Attribute implements Attr{
+          private AVT m_attribute;
+          private Element m_owner = null;
+          /**
+           * Construct a Attr.
+           *
+           */
+          public Attribute(AVT avt, Element elem){
+                m_attribute = avt;
+                m_owner = elem;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param newChild New node to append to the list of this node's 
+           * children
+           *
+           *
+           * @throws DOMException
+           */
+          public Node appendChild(Node newChild) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param deep Flag indicating whether to clone deep 
+           * (clone member variables)
+           *
+           * @return Returns a duplicate of this node
+           */
+          public Node cloneNode(boolean deep)
+          {
+                  return new Attribute(m_attribute, m_owner);
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public NamedNodeMap getAttributes()
+          {
+            return null;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return a NodeList containing no nodes. 
+           */
+          public NodeList getChildNodes()
+          {
+                  return new NodeList(){
+                          public int getLength(){
+                                  return 0;
+                          }
+                          public Node item(int index){
+                                  return null;
+                          }
+                  };
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public Node getFirstChild()
+          {
+                  return null;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public Node getLastChild()
+          {
+                  return null;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return the local part of the qualified name of this node
+           */
+          public String getLocalName()
+          {
+                  return m_attribute.getName();
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return The namespace URI of this node, or null if it is 
+           * unspecified
+           */
+          public String getNamespaceURI()
+          {
+                  String uri = m_attribute.getURI();
+                  return (uri.equals(""))?null:uri;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public Node getNextSibling()
+          {
+                return null;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return The name of the attribute
+           */
+          public String getNodeName()
+          {
+                  String uri = m_attribute.getURI();
+                  String localName = getLocalName();
+                  return (uri.equals(""))?localName:uri+":"+localName;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return The node is an Attr
+           */
+          public short getNodeType()
+          {
+                  return ATTRIBUTE_NODE;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return The value of the attribute
+           *
+           * @throws DOMException
+           */
+          public String getNodeValue() throws DOMException
+          {
+                  return m_attribute.getSimpleString();
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public Document getOwnerDocument()
+          {
+            return m_owner.getOwnerDocument();
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return the containing element node
+           */
+          public Node getParentNode()
+          {
+                  return m_owner;
+          }
+                    
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return The namespace prefix of this node, or null if it is 
+           * unspecified
+           */
+          public String getPrefix()
+          {
+                  String uri = m_attribute.getURI();
+                  String rawName = m_attribute.getRawName();
+                  return (uri.equals(""))? 
+                        null:rawName.substring(0, rawName.indexOf(":"));
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return null
+           */
+          public Node getPreviousSibling()
+          {
+                  return null;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return false
+           */
+          public boolean hasAttributes()
+          {
+                  return false;
+          }
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return false
+           */
+          public boolean hasChildNodes()
+          {
+                  return false;
+          }                    
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param newChild New child node to insert
+           * @param refChild Insert in front of this child
+           *
+           * @return null
+           *
+           * @throws DOMException
+           */
+          public Node insertBefore(Node newChild, Node refChild) 
+                throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
+                  return null;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @return Returns <code>false</code>
+           * @since DOM Level 2
+           */
+          public boolean isSupported(String feature, String version)
+          {
+            return false;
+          }
+
+          /** @see org.w3c.dom.Node */
+          public void normalize(){}
+          
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param oldChild Child to be removed
+           *
+           * @return null
+           *
+           * @throws DOMException
+           */
+          public Node removeChild(Node oldChild) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }         
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param newChild Replace existing child with this one
+           * @param oldChild Existing child to be replaced
+           *
+           * @return null
+           *
+           * @throws DOMException
+           */
+          public Node replaceChild(Node newChild, Node oldChild) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+                  return null;
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param nodeValue Value to set this node to
+           *
+           * @throws DOMException
+           */
+          public void setNodeValue(String nodeValue) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+          }
+
+          /**
+           * @see org.w3c.dom.Node
+           *
+           * @param prefix Prefix to set for this node
+           *
+           * @throws DOMException
+           */
+          public void setPrefix(String prefix) throws DOMException
+          {
+                  throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                      XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
+          }
+                                                                      
+          /**
+           *
+           * @return The name of this attribute
+           */          
+          public String getName(){
+                  return m_attribute.getName();                            
+          }
+
+          /**
+           *
+           * @return The value of this attribute returned as string
+           */          
+          public String getValue(){
+                  return m_attribute.getSimpleString();                            
+          }
+          
+          /**
+           *
+           * @return The Element node this attribute is attached to 
+           * or null if this attribute is not in use
+           */                    
+          public Element getOwnerElement(){
+                  return m_owner;
+          }
+          
+          /**
+           *
+           * @return true
+           */          
+          public boolean getSpecified(){
+                  return true;
+          }
+          
+          /**
+           * @see org.w3c.dom.Attr
+           *
+           * @param value Value to set this node to
+           *
+           * @throws DOMException
+           */
+          public void setValue(String value) throws DOMException
+          {
+            throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 
+                XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); 
+          }
+
+ 	  public TypeInfo getSchemaTypeInfo() { return null; }
+    
+  	  public boolean isId( ) { return false; }
+
+  	  public Object setUserData(String key,
+                                    Object data,
+                                    UserDataHandler handler) {
+        	return getOwnerDocument().setUserData( key, data, handler);
+  	  }
+
+  	  public Object getUserData(String key) {
+        	return getOwnerDocument().getUserData( key);
+  	  } 
+
+  	  public Object getFeature(String feature, String version) {
+        	return isSupported(feature, version) ? this : null;
+   	  }
+          
+          public boolean isEqualNode(Node arg) {
+          	return arg == this;
+          }
+          
+          public String lookupNamespaceURI(String specifiedPrefix) {
+             	return null;
+          }
+          
+          public boolean isDefaultNamespace(String namespaceURI) {
+            	return false;
+          }
+
+	  public String lookupPrefix(String namespaceURI) {
+	    	return null;
+	  }
+	  
+  	  public boolean isSameNode(Node other) {
+        	// we do not use any wrapper so the answer is obvious
+        	return this == other;
+  	  }
+          
+  	  public void setTextContent(String textContent)
+        	throws DOMException {
+        	setNodeValue(textContent);
+  	  }
+
+  	  public String getTextContent() throws DOMException {
+            	return getNodeValue();  // overriden in some subclasses
+   	  }
+
+    	  public short compareDocumentPosition(Node other) throws DOMException {
+            	return 0;
+    	  }
+
+          public String getBaseURI() {
+            	return null;
+    	  }
+  }        
+  
+  /**
+   * Get an "extension-element-prefix" property.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param i Index of URI ("extension-element-prefix" property) to get
+   *
+   * @return URI at given index ("extension-element-prefix" property)
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public String getExtensionElementPrefix(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_ExtensionElementURIs)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return m_ExtensionElementURIs.elementAt(i);
+  }
+
+  /**
+   * Get the number of "extension-element-prefixes" Strings.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @return the number of "extension-element-prefixes" Strings
+   */
+  public int getExtensionElementPrefixCount()
+  {
+    return (null != m_ExtensionElementURIs)
+           ? m_ExtensionElementURIs.size() : 0;
+  }
+
+  /**
+   * Find out if the given "extension-element-prefix" property is defined.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param uri The URI to find
+   *
+   * @return True if the given URI is found
+   */
+  public boolean containsExtensionElementURI(String uri)
+  {
+
+    if (null == m_ExtensionElementURIs)
+      return false;
+
+    return m_ExtensionElementURIs.contains(uri);
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_LITERALRESULT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+
+    // TODO: Need prefix.
+    return m_rawName;
+  }
+
+  /**
+   * The XSLT version as specified by this element.
+   * @serial
+   */
+  private String m_version;
+
+  /**
+   * Set the "version" property.
+   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
+   *
+   * @param v Version property value to set
+   */
+  public void setVersion(String v)
+  {
+    m_version = v;
+  }
+  
+  /**
+   * Get the "version" property.
+   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
+   *
+   * @return Version property value
+   */
+  public String getVersion()
+  {
+    return m_version;
+  }
+
+  /**
+   * The "exclude-result-prefixes" property.
+   * @serial
+   */
+  private StringVector m_excludeResultPrefixes;
+
+  /**
+   * Set the "exclude-result-prefixes" property.
+   * The designation of a namespace as an excluded namespace is
+   * effective within the subtree of the stylesheet rooted at
+   * the element bearing the exclude-result-prefixes or
+   * xsl:exclude-result-prefixes attribute; a subtree rooted
+   * at an xsl:stylesheet element does not include any stylesheets
+   * imported or included by children of that xsl:stylesheet element.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param v vector of prefixes that are resolvable to strings.
+   */
+  public void setExcludeResultPrefixes(StringVector v)
+  {
+    m_excludeResultPrefixes = v;
+  }
+
+  /**
+   * Tell if the result namespace decl should be excluded.  Should be called before
+   * namespace aliasing (I think).
+   *
+   * @param prefix Prefix of namespace to check
+   * @param uri URI of namespace to check
+   *
+   * @return True if the given namespace should be excluded
+   *
+   * @throws TransformerException
+   */
+  private boolean excludeResultNSDecl(String prefix, String uri)
+          throws TransformerException
+  {
+
+    if (null != m_excludeResultPrefixes)
+    {
+      return containsExcludeResultPrefix(prefix, uri);
+    }
+
+    return false;
+  }
+  
+  /**
+   * Copy a Literal Result Element into the Result tree, copy the
+   * non-excluded namespace attributes, copy the attributes not
+   * of the XSLT namespace, and execute the children of the LRE.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+    public void execute(TransformerImpl transformer)
+        throws TransformerException
+    {
+        SerializationHandler rhandler = transformer.getSerializationHandler();
+
+        try
+        {
+
+            // JJK Bugzilla 3464, test namespace85 -- make sure LRE's
+            // namespace is asserted even if default, since xsl:element
+            // may have changed the context.
+            rhandler.startPrefixMapping(getPrefix(), getNamespace());
+
+            // Add namespace declarations.
+            executeNSDecls(transformer);
+            rhandler.startElement(getNamespace(), getLocalName(), getRawName());
+        }
+        catch (SAXException se)
+        {
+            throw new TransformerException(se);
+        }
+
+        /*
+         * If we make it to here we have done a successful startElement()
+         * we will do an endElement() call for balance, no matter what happens
+         * in the middle.  
+         */
+
+        // tException remembers if we had an exception "in the middle"
+        TransformerException tException = null;
+        try
+        {
+
+            // Process any possible attributes from xsl:use-attribute-sets first
+            super.execute(transformer);
+
+            //xsl:version, excludeResultPrefixes???
+            // Process the list of avts next
+            if (null != m_avts)
+            {
+                int nAttrs = m_avts.size();
+
+                for (int i = (nAttrs - 1); i >= 0; i--)
+                {
+                    AVT avt = (AVT) m_avts.get(i);
+                    XPathContext xctxt = transformer.getXPathContext();
+                    int sourceNode = xctxt.getCurrentNode();
+                    String stringedValue =
+                        avt.evaluate(xctxt, sourceNode, this);
+
+                    if (null != stringedValue)
+                    {
+
+                        // Important Note: I'm not going to check for excluded namespace 
+                        // prefixes here.  It seems like it's too expensive, and I'm not 
+                        // even sure this is right.  But I could be wrong, so this needs 
+                        // to be tested against other implementations.
+
+                        rhandler.addAttribute(
+                            avt.getURI(),
+                            avt.getName(),
+                            avt.getRawName(),
+                            "CDATA",
+                            stringedValue, false);
+                    }
+                } // end for
+            }
+
+            // Now process all the elements in this subtree
+            // TODO: Process m_extensionElementPrefixes && m_attributeSetsNames
+            transformer.executeChildTemplates(this, true);
+        }
+        catch (TransformerException te)
+        {
+            // thrown in finally to prevent original exception consumed by subsequent exceptions
+            tException = te;
+        }
+        catch (SAXException se)
+        {
+            tException = new TransformerException(se);
+        }
+
+        try
+        {
+            /* we need to do this endElement() to balance the
+             * successful startElement() call even if 
+             * there was an exception in the middle.
+             * Otherwise an exception in the middle could cause a system to hang.
+             */
+            rhandler.endElement(getNamespace(), getLocalName(), getRawName());
+        }
+        catch (SAXException se)
+        {
+            /* we did call endElement(). If thee was an exception
+             * in the middle throw that one, otherwise if there
+             * was an exception from endElement() throw that one.
+             */
+            if (tException != null)
+                throw tException;
+            else
+                throw new TransformerException(se);
+        }
+        
+        /* If an exception was thrown in the middle but not with startElement() or
+         * or endElement() then its time to let it percolate.
+         */ 
+        if (tException != null)
+            throw tException; 
+        
+        unexecuteNSDecls(transformer);
+
+        // JJK Bugzilla 3464, test namespace85 -- balance explicit start.
+        try
+        {
+            rhandler.endPrefixMapping(getPrefix());
+        }
+        catch (SAXException se)
+        {
+            throw new TransformerException(se);
+        }
+    }
+
+  /**
+   * Compiling templates requires that we be able to list the AVTs
+   * ADDED 9/5/2000 to support compilation experiment
+   *
+   * @return an Enumeration of the literal result attributes associated
+   * with this element.
+   */
+  public Iterator enumerateLiteralResultAttributes()
+  {
+    return (null == m_avts) ? null : m_avts.iterator();
+  }
+  
+    /**
+     * Accept a visitor and call the appropriate method 
+     * for this class.
+     * 
+     * @param visitor The visitor whose appropriate method will be called.
+     * @return true if the children of the object should be visited.
+     */
+    protected boolean accept(XSLTVisitor visitor)
+    {
+      return visitor.visitLiteralResultElement(this);
+    }
+
+    /**
+     * Call the children visitors.
+     * @param visitor The visitor whose appropriate method will be called.
+     */
+    protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+    {
+      if (callAttrs && null != m_avts)
+      {
+        int nAttrs = m_avts.size();
+
+        for (int i = (nAttrs - 1); i >= 0; i--)
+        {
+          AVT avt = (AVT) m_avts.get(i);
+          avt.callVisitors(visitor);
+        }
+      }
+      super.callChildVisitors(visitor, callAttrs);
+    }
+
+    /**
+     * Throw a DOMException
+     *
+     * @param msg key of the error that occured.
+     */
+    public void throwDOMException(short code, String msg)
+    {
+
+      String themsg = XSLMessages.createMessage(msg, null);
+
+      throw new DOMException(code, themsg);
+    }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemMessage.java b/src/main/java/org/apache/xalan/templates/ElemMessage.java
new file mode 100644
index 0000000..1cfdf17
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemMessage.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemMessage.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+
+/**
+ * Implement xsl:message.
+ * <pre>
+ * <!ELEMENT xsl:message %template;>
+ * <!ATTLIST xsl:message
+ *   %space-att;
+ *   terminate (yes|no) "no"
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#message">message in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemMessage extends ElemTemplateElement
+{
+    static final long serialVersionUID = 1530472462155060023L;
+
+  /**
+   * If the terminate attribute has the value yes, then the
+   * XSLT transformer should terminate processing after sending
+   * the message. The default value is no.
+   * @serial
+   */
+  private boolean m_terminate = Constants.ATTRVAL_NO;  // default value 
+
+  /**
+   * Set the "terminate" attribute.
+   * If the terminate attribute has the value yes, then the
+   * XSLT transformer should terminate processing after sending
+   * the message. The default value is no.
+   *
+   * @param v Value to set for "terminate" attribute. 
+   */
+  public void setTerminate(boolean v)
+  {
+    m_terminate = v;
+  }
+
+  /**
+   * Get the "terminate" attribute.
+   * If the terminate attribute has the value yes, then the
+   * XSLT transformer should terminate processing after sending
+   * the message. The default value is no.
+   *
+   * @return value of "terminate" attribute.
+   */
+  public boolean getTerminate()
+  {
+    return m_terminate;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_MESSAGE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return name of the element 
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_MESSAGE_STRING;
+  }
+
+  /**
+   * Send a message to diagnostics.
+   * The xsl:message instruction sends a message in a way that
+   * is dependent on the XSLT transformer. The content of the xsl:message
+   * instruction is a template. The xsl:message is instantiated by
+   * instantiating the content to create an XML fragment. This XML
+   * fragment is the content of the message.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    String data = transformer.transformToString(this);
+
+    transformer.getMsgMgr().message(this, data, m_terminate);
+    
+    if(m_terminate)
+      transformer.getErrorListener().fatalError(new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_STYLESHEET_DIRECTED_TERMINATION, null))); //"Stylesheet directed termination"));
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemNumber.java b/src/main/java/org/apache/xalan/templates/ElemNumber.java
new file mode 100644
index 0000000..1335902
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemNumber.java
@@ -0,0 +1,2157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemNumber.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.CountersTable;
+import org.apache.xalan.transformer.DecimalToRoman;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.NodeVector;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.StringBufferPool;
+import org.apache.xml.utils.res.XResourceBundle;
+import org.apache.xml.utils.res.CharArrayWrapper;
+import org.apache.xml.utils.res.IntArrayWrapper;
+import org.apache.xml.utils.res.LongArrayWrapper;
+import org.apache.xml.utils.res.StringArrayWrapper;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.SAXException;
+
+// import org.apache.xalan.dtm.*;
+
+/**
+ * Implement xsl:number.
+ * <pre>
+ * <!ELEMENT xsl:number EMPTY>
+ * <!ATTLIST xsl:number
+ *    level (single|multiple|any) "single"
+ *    count %pattern; #IMPLIED
+ *    from %pattern; #IMPLIED
+ *    value %expr; #IMPLIED
+ *    format %avt; '1'
+ *    lang %avt; #IMPLIED
+ *    letter-value %avt; #IMPLIED
+ *    grouping-separator %avt; #IMPLIED
+ *    grouping-size %avt; #IMPLIED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#number">number in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemNumber extends ElemTemplateElement 
+{
+    static final long serialVersionUID = 8118472298274407610L;
+
+    /**
+     * Chars for converting integers into alpha counts.
+     * @see TransformerImpl#int2alphaCount
+     */
+    private CharArrayWrapper m_alphaCountTable = null;
+    
+    private class MyPrefixResolver implements PrefixResolver {
+        
+        DTM dtm;
+        int handle;
+        boolean handleNullPrefix;
+        
+		/**
+		 * Constructor for MyPrefixResolver.
+		 * @param xpathExpressionContext
+		 */
+		public MyPrefixResolver(Node xpathExpressionContext, DTM dtm, int handle, boolean handleNullPrefix) {
+            this.dtm = dtm;
+            this.handle = handle;
+            this.handleNullPrefix = handleNullPrefix;
+		}
+
+    	/**
+		 * @see PrefixResolver#getNamespaceForPrefix(String, Node)
+		 */
+		public String getNamespaceForPrefix(String prefix) {
+            return dtm.getNamespaceURI(handle);
+		}
+        
+        /**
+         * @see PrefixResolver#getNamespaceForPrefix(String, Node)
+         * this shouldn't get called.
+         */
+        public String getNamespaceForPrefix(String prefix, Node context) {
+            return getNamespaceForPrefix(prefix);
+        }
+
+		/**
+		 * @see PrefixResolver#getBaseIdentifier()
+		 */
+		public String getBaseIdentifier() {
+			return ElemNumber.this.getBaseIdentifier();
+		}
+
+		/**
+		 * @see PrefixResolver#handlesNullPrefixes()
+		 */
+		public boolean handlesNullPrefixes() {
+			return handleNullPrefix;
+		}
+
+}
+    
+  /**
+   * Only nodes are counted that match this pattern.
+   * @serial
+   */
+  private XPath m_countMatchPattern = null;
+
+  /**
+   * Set the "count" attribute.
+   * The count attribute is a pattern that specifies what nodes
+   * should be counted at those levels. If count attribute is not
+   * specified, then it defaults to the pattern that matches any
+   * node with the same node type as the current node and, if the
+   * current node has an expanded-name, with the same expanded-name
+   * as the current node.
+   *
+   * @param v Value to set for "count" attribute. 
+   */
+  public void setCount(XPath v)
+  {
+    m_countMatchPattern = v;
+  }
+
+  /**
+   * Get the "count" attribute.
+   * The count attribute is a pattern that specifies what nodes
+   * should be counted at those levels. If count attribute is not
+   * specified, then it defaults to the pattern that matches any
+   * node with the same node type as the current node and, if the
+   * current node has an expanded-name, with the same expanded-name
+   * as the current node.
+   *
+   * @return Value of "count" attribute.
+   */
+  public XPath getCount()
+  {
+    return m_countMatchPattern;
+  }
+
+  /**
+   * Specifies where to count from.
+   * For level="single" or level="multiple":
+   * Only ancestors that are searched are
+   * those that are descendants of the nearest ancestor that matches
+   * the from pattern.
+   * For level="any:
+   * Only nodes after the first node before the
+   * current node that match the from pattern are considered.
+   * @serial
+   */
+  private XPath m_fromMatchPattern = null;
+
+  /**
+   * Set the "from" attribute. Specifies where to count from.
+   * For level="single" or level="multiple":
+   * Only ancestors that are searched are
+   * those that are descendants of the nearest ancestor that matches
+   * the from pattern.
+   * For level="any:
+   * Only nodes after the first node before the
+   * current node that match the from pattern are considered.
+   *
+   * @param v Value to set for "from" attribute.
+   */
+  public void setFrom(XPath v)
+  {
+    m_fromMatchPattern = v;
+  }
+
+  /**
+   * Get the "from" attribute.
+   * For level="single" or level="multiple":
+   * Only ancestors that are searched are
+   * those that are descendants of the nearest ancestor that matches
+   * the from pattern.
+   * For level="any:
+   * Only nodes after the first node before the
+   * current node that match the from pattern are considered.
+   *
+   * @return Value of "from" attribute.
+   */
+  public XPath getFrom()
+  {
+    return m_fromMatchPattern;
+  }
+
+  /**
+   * When level="single", it goes up to the first node in the ancestor-or-self axis
+   * that matches the count pattern, and constructs a list of length one containing
+   * one plus the number of preceding siblings of that ancestor that match the count
+   * pattern. If there is no such ancestor, it constructs an empty list. If the from
+   * attribute is specified, then the only ancestors that are searched are those
+   * that are descendants of the nearest ancestor that matches the from pattern.
+   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
+   *
+   * When level="multiple", it constructs a list of all ancestors of the current node
+   * in document order followed by the element itself; it then selects from the list
+   * those nodes that match the count pattern; it then maps each node in the list to
+   * one plus the number of preceding siblings of that node that match the count pattern.
+   * If the from attribute is specified, then the only ancestors that are searched are
+   * those that are descendants of the nearest ancestor that matches the from pattern.
+   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
+   *
+   * When level="any", it constructs a list of length one containing the number of
+   * nodes that match the count pattern and belong to the set containing the current
+   * node and all nodes at any level of the document that are before the current node
+   * in document order, excluding any namespace and attribute nodes (in other words
+   * the union of the members of the preceding and ancestor-or-self axes). If the
+   * from attribute is specified, then only nodes after the first node before the
+   * current node that match the from pattern are considered.
+   * @serial
+   */
+  private int m_level = Constants.NUMBERLEVEL_SINGLE;
+
+  /**
+   * Set the "level" attribute.
+   * The level attribute specifies what levels of the source tree should
+   * be considered; it has the values single, multiple or any. The default
+   * is single.
+   *
+   * @param v Value to set for "level" attribute.
+   */
+  public void setLevel(int v)
+  {
+    m_level = v;
+  }
+
+  /**
+   * Get the "level" attribute.
+   * The level attribute specifies what levels of the source tree should
+   * be considered; it has the values single, multiple or any. The default
+   * is single.
+   *
+   * @return Value of "level" attribute.
+   */
+  public int getLevel()
+  {
+    return m_level;
+  }
+
+  /**
+   * The value attribute contains an expression. The expression is evaluated
+   * and the resulting object is converted to a number as if by a call to the
+   * number function.
+   * @serial
+   */
+  private XPath m_valueExpr = null;
+
+  /**
+   * Set the "value" attribute.
+   * The value attribute contains an expression. The expression is evaluated
+   * and the resulting object is converted to a number as if by a call to the
+   * number function.
+   *
+   * @param v Value to set for "value" attribute.
+   */
+  public void setValue(XPath v)
+  {
+    m_valueExpr = v;
+  }
+
+  /**
+   * Get the "value" attribute.
+   * The value attribute contains an expression. The expression is evaluated
+   * and the resulting object is converted to a number as if by a call to the
+   * number function.
+   *
+   * @return Value of "value" attribute.
+   */
+  public XPath getValue()
+  {
+    return m_valueExpr;
+  }
+
+  /**
+   * The "format" attribute is used to control conversion of a list of
+   * numbers into a string.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   * @serial
+   */
+  private AVT m_format_avt = null;
+
+  /**
+   * Set the "format" attribute.
+   * The "format" attribute is used to control conversion of a list of
+   * numbers into a string.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @param v Value to set for "format" attribute.
+   */
+  public void setFormat(AVT v)
+  {
+    m_format_avt = v;
+  }
+
+  /**
+   * Get the "format" attribute.
+   * The "format" attribute is used to control conversion of a list of
+   * numbers into a string.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @return Value of "format" attribute.
+   */
+  public AVT getFormat()
+  {
+    return m_format_avt;
+  }
+
+  /**
+   * When numbering with an alphabetic sequence, the lang attribute
+   * specifies which language's alphabet is to be used.
+   * @serial
+   */
+  private AVT m_lang_avt = null;
+
+  /**
+   * Set the "lang" attribute.
+   * When numbering with an alphabetic sequence, the lang attribute
+   * specifies which language's alphabet is to be used; it has the same
+   * range of values as xml:lang [XML]; if no lang value is specified,
+   * the language should be determined from the system environment.
+   * Implementers should document for which languages they support numbering.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @param v Value to set for "lang" attribute.
+   */
+  public void setLang(AVT v)
+  {
+    m_lang_avt = v;
+  }
+
+  /**
+   * Get the "lang" attribute.
+   * When numbering with an alphabetic sequence, the lang attribute
+   * specifies which language's alphabet is to be used; it has the same
+   * range of values as xml:lang [XML]; if no lang value is specified,
+   * the language should be determined from the system environment.
+   * Implementers should document for which languages they support numbering.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @return Value ofr "lang" attribute.
+   */
+  public AVT getLang()
+  {
+    return m_lang_avt;
+  }
+
+  /**
+   * The letter-value attribute disambiguates between numbering
+   * sequences that use letters.
+   * @serial
+   */
+  private AVT m_lettervalue_avt = null;
+
+  /**
+   * Set the "letter-value" attribute.
+   * The letter-value attribute disambiguates between numbering sequences
+   * that use letters.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @param v Value to set for "letter-value" attribute.
+   */
+  public void setLetterValue(AVT v)
+  {
+    m_lettervalue_avt = v;
+  }
+
+  /**
+   * Get the "letter-value" attribute.
+   * The letter-value attribute disambiguates between numbering sequences
+   * that use letters.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @return Value to set for "letter-value" attribute.
+   */
+  public AVT getLetterValue()
+  {
+    return m_lettervalue_avt;
+  }
+
+  /**
+   * The grouping-separator attribute gives the separator
+   * used as a grouping (e.g. thousands) separator in decimal
+   * numbering sequences.
+   * @serial
+   */
+  private AVT m_groupingSeparator_avt = null;
+
+  /**
+   * Set the "grouping-separator" attribute.
+   * The grouping-separator attribute gives the separator
+   * used as a grouping (e.g. thousands) separator in decimal
+   * numbering sequences.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @param v Value to set for "grouping-separator" attribute.
+   */
+  public void setGroupingSeparator(AVT v)
+  {
+    m_groupingSeparator_avt = v;
+  }
+
+  /**
+   * Get the "grouping-separator" attribute.
+   * The grouping-separator attribute gives the separator
+   * used as a grouping (e.g. thousands) separator in decimal
+   * numbering sequences.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @return Value of "grouping-separator" attribute.
+   */
+  public AVT getGroupingSeparator()
+  {
+    return m_groupingSeparator_avt;
+  }
+
+  /**
+   * The optional grouping-size specifies the size (normally 3) of the grouping.
+   * @serial
+   */
+  private AVT m_groupingSize_avt = null;
+
+  /**
+   * Set the "grouping-size" attribute.
+   * The optional grouping-size specifies the size (normally 3) of the grouping.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @param v Value to set for "grouping-size" attribute.
+   */
+  public void setGroupingSize(AVT v)
+  {
+    m_groupingSize_avt = v;
+  }
+
+  /**
+   * Get the "grouping-size" attribute.
+   * The optional grouping-size specifies the size (normally 3) of the grouping.
+   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
+   *
+   * @return Value of "grouping-size" attribute.
+   */
+  public AVT getGroupingSize()
+  {
+    return m_groupingSize_avt;
+  }
+
+  /**
+   * Shouldn't this be in the transformer?  Big worries about threads...
+   */
+
+  // private XResourceBundle thisBundle;
+
+  /**
+   * Table to help in converting decimals to roman numerals.
+   * @see org.apache.xalan.transformer.DecimalToRoman
+   */
+  private final static DecimalToRoman m_romanConvertTable[] = {
+    new DecimalToRoman(1000, "M", 900, "CM"),
+    new DecimalToRoman(500, "D", 400, "CD"),
+    new DecimalToRoman(100L, "C", 90L, "XC"),
+    new DecimalToRoman(50L, "L", 40L, "XL"),
+    new DecimalToRoman(10L, "X", 9L, "IX"),
+    new DecimalToRoman(5L, "V", 4L, "IV"),
+    new DecimalToRoman(1L, "I", 1L, "I") };
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    java.util.Vector vnames = cstate.getVariableNames();
+    if(null != m_countMatchPattern)
+      m_countMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_format_avt)
+      m_format_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_fromMatchPattern)
+      m_fromMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_groupingSeparator_avt)
+      m_groupingSeparator_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_groupingSize_avt)
+      m_groupingSize_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_lang_avt)
+      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_lettervalue_avt)
+      m_lettervalue_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_valueExpr)
+      m_valueExpr.fixupVariables(vnames, cstate.getGlobalsSize());
+  }
+
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_NUMBER;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_NUMBER_STRING;
+  }
+
+  /**
+   * Execute an xsl:number instruction. The xsl:number element is
+   * used to insert a formatted number into the result tree.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    int sourceNode = transformer.getXPathContext().getCurrentNode();
+    String countString = getCountString(transformer, sourceNode);
+
+    try
+    {
+      transformer.getResultTreeHandler().characters(countString.toCharArray(),
+                                                    0, countString.length());
+    }
+    catch(SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to child list
+   *
+   * @return Child just added to child list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    error(XSLTErrorResources.ER_CANNOT_ADD,
+          new Object[]{ newChild.getNodeName(),
+                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    return null;
+  }
+
+  /**
+   * Given a 'from' pattern (ala xsl:number), a match pattern
+   * and a context, find the first ancestor that matches the
+   * pattern (including the context handed in).
+   *
+   * @param xctxt The XPath runtime state for this.
+   * @param fromMatchPattern The ancestor must match this pattern.
+   * @param countMatchPattern The ancestor must also match this pattern.
+   * @param context The node that "." expresses.
+   * @param namespaceContext The context in which namespaces in the
+   * queries are supposed to be expanded.
+   *
+   * @return the first ancestor that matches the given pattern
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  int findAncestor(
+          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern, 
+          int context, ElemNumber namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+    DTM dtm = xctxt.getDTM(context);
+    while (DTM.NULL != context)
+    {
+      if (null != fromMatchPattern)
+      {
+        if (fromMatchPattern.getMatchScore(xctxt, context)
+                != XPath.MATCH_SCORE_NONE)
+        {
+
+          //context = null;
+          break;
+        }
+      }
+
+      if (null != countMatchPattern)
+      {
+        if (countMatchPattern.getMatchScore(xctxt, context)
+                != XPath.MATCH_SCORE_NONE)
+        {
+          break;
+        }
+      }
+
+      context = dtm.getParent(context);
+    }
+
+    return context;
+  }
+
+  /**
+   * Given a 'from' pattern (ala xsl:number), a match pattern
+   * and a context, find the first ancestor that matches the
+   * pattern (including the context handed in).
+   * @param xctxt The XPath runtime state for this.
+   * @param fromMatchPattern The ancestor must match this pattern.
+   * @param countMatchPattern The ancestor must also match this pattern.
+   * @param context The node that "." expresses.
+   * @param namespaceContext The context in which namespaces in the
+   * queries are supposed to be expanded.
+   *
+   * @return the first preceding, ancestor or self node that 
+   * matches the given pattern
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private int findPrecedingOrAncestorOrSelf(
+          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern, 
+          int context, ElemNumber namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+    DTM dtm = xctxt.getDTM(context);
+    while (DTM.NULL != context)
+    {
+      if (null != fromMatchPattern)
+      {
+        if (fromMatchPattern.getMatchScore(xctxt, context)
+                != XPath.MATCH_SCORE_NONE)
+        {
+          context = DTM.NULL;
+
+          break;
+        }
+      }
+
+      if (null != countMatchPattern)
+      {
+        if (countMatchPattern.getMatchScore(xctxt, context)
+                != XPath.MATCH_SCORE_NONE)
+        {
+          break;
+        }
+      }
+
+      int prevSibling = dtm.getPreviousSibling(context);
+
+      if (DTM.NULL == prevSibling)
+      {
+        context = dtm.getParent(context);
+      }
+      else
+      {
+
+        // Now go down the chain of children of this sibling 
+        context = dtm.getLastChild(prevSibling);
+
+        if (context == DTM.NULL)
+          context = prevSibling;
+      }
+    }
+
+    return context;
+  }
+
+  /**
+   * Get the count match pattern, or a default value.
+   *
+   * @param support The XPath runtime state for this.
+   * @param contextNode The node that "." expresses.
+   *
+   * @return the count match pattern, or a default value. 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  XPath getCountMatchPattern(XPathContext support, int contextNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    XPath countMatchPattern = m_countMatchPattern;
+    DTM dtm = support.getDTM(contextNode);
+    if (null == countMatchPattern)
+    {
+      switch (dtm.getNodeType(contextNode))
+      {
+      case DTM.ELEMENT_NODE :
+        MyPrefixResolver resolver;
+
+        if (dtm.getNamespaceURI(contextNode) == null) {
+             resolver =  new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, false);
+        } else {
+            resolver = new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, true);
+        }
+
+        countMatchPattern = new XPath(dtm.getNodeName(contextNode), this, resolver,
+                                      XPath.MATCH, support.getErrorListener());
+        break;
+
+      case DTM.ATTRIBUTE_NODE :
+
+        // countMatchPattern = m_stylesheet.createMatchPattern("@"+contextNode.getNodeName(), this);
+        countMatchPattern = new XPath("@" + dtm.getNodeName(contextNode), this,
+                                      this, XPath.MATCH, support.getErrorListener());
+        break;
+      case DTM.CDATA_SECTION_NODE :
+      case DTM.TEXT_NODE :
+
+        // countMatchPattern = m_stylesheet.createMatchPattern("text()", this);
+        countMatchPattern = new XPath("text()", this, this, XPath.MATCH, support.getErrorListener());
+        break;
+      case DTM.COMMENT_NODE :
+
+        // countMatchPattern = m_stylesheet.createMatchPattern("comment()", this);
+        countMatchPattern = new XPath("comment()", this, this, XPath.MATCH, support.getErrorListener());
+        break;
+      case DTM.DOCUMENT_NODE :
+
+        // countMatchPattern = m_stylesheet.createMatchPattern("/", this);
+        countMatchPattern = new XPath("/", this, this, XPath.MATCH, support.getErrorListener());
+        break;
+      case DTM.PROCESSING_INSTRUCTION_NODE :
+
+        // countMatchPattern = m_stylesheet.createMatchPattern("pi("+contextNode.getNodeName()+")", this);
+        countMatchPattern = new XPath("pi(" + dtm.getNodeName(contextNode)
+                                      + ")", this, this, XPath.MATCH, support.getErrorListener());
+        break;
+      default :
+        countMatchPattern = null;
+      }
+    }
+
+    return countMatchPattern;
+  }
+
+  /**
+   * Given an XML source node, get the count according to the
+   * parameters set up by the xsl:number attributes.
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param sourceNode The source node being counted.
+   *
+   * @return The count of nodes
+   *
+   * @throws TransformerException
+   */
+  String getCountString(TransformerImpl transformer, int sourceNode)
+          throws TransformerException
+  {
+
+    long[] list = null;
+    XPathContext xctxt = transformer.getXPathContext();
+    CountersTable ctable = transformer.getCountersTable();
+
+    if (null != m_valueExpr)
+    {
+      XObject countObj = m_valueExpr.execute(xctxt, sourceNode, this);
+      //According to Errata E24
+      double d_count = java.lang.Math.floor(countObj.num()+ 0.5);
+      if (Double.isNaN(d_count)) return "NaN";
+      else if (d_count < 0 && Double.isInfinite(d_count)) return "-Infinity";
+      else if (Double.isInfinite(d_count)) return "Infinity";
+      else if (d_count == 0) return "0";
+      else{
+              long count = (long)d_count;
+              list = new long[1];
+              list[0] = count;              
+      }
+    }
+    else
+    {
+      if (Constants.NUMBERLEVEL_ANY == m_level)
+      {
+        list = new long[1];
+        list[0] = ctable.countNode(xctxt, this, sourceNode);
+      }
+      else
+      {
+        NodeVector ancestors =
+          getMatchingAncestors(xctxt, sourceNode,
+                               Constants.NUMBERLEVEL_SINGLE == m_level);
+        int lastIndex = ancestors.size() - 1;
+
+        if (lastIndex >= 0)
+        {
+          list = new long[lastIndex + 1];
+
+          for (int i = lastIndex; i >= 0; i--)
+          {
+            int target = ancestors.elementAt(i);
+
+            list[lastIndex - i] = ctable.countNode(xctxt, this, target);
+          }
+        }
+      }
+    }
+
+    return (null != list)
+           ? formatNumberList(transformer, list, sourceNode) : "";
+  }
+
+  /**
+   * Get the previous node to be counted.
+   *
+   * @param xctxt The XPath runtime state for this.
+   * @param pos The current node
+   *
+   * @return the previous node to be counted.
+   *
+   * @throws TransformerException
+   */
+  public int getPreviousNode(XPathContext xctxt, int pos)
+          throws TransformerException
+  {
+
+    XPath countMatchPattern = getCountMatchPattern(xctxt, pos);
+    DTM dtm = xctxt.getDTM(pos);
+
+    if (Constants.NUMBERLEVEL_ANY == m_level)
+    {
+      XPath fromMatchPattern = m_fromMatchPattern;
+
+      // Do a backwards document-order walk 'till a node is found that matches 
+      // the 'from' pattern, or a node is found that matches the 'count' pattern, 
+      // or the top of the tree is found.
+      while (DTM.NULL != pos)
+      {
+
+        // Get the previous sibling, if there is no previous sibling, 
+        // then count the parent, but if there is a previous sibling, 
+        // dive down to the lowest right-hand (last) child of that sibling.
+        int next = dtm.getPreviousSibling(pos);
+
+        if (DTM.NULL == next)
+        {
+          next = dtm.getParent(pos);
+
+          if ((DTM.NULL != next) && ((((null != fromMatchPattern) && (fromMatchPattern.getMatchScore(
+                  xctxt, next) != XPath.MATCH_SCORE_NONE))) 
+              || (dtm.getNodeType(next) == DTM.DOCUMENT_NODE)))
+          {
+            pos = DTM.NULL;  // return null from function.
+
+            break;  // from while loop
+          }
+        }
+        else
+        {
+
+          // dive down to the lowest right child.
+          int child = next;
+
+          while (DTM.NULL != child)
+          {
+            child = dtm.getLastChild(next);
+
+            if (DTM.NULL != child)
+              next = child;
+          }
+        }
+
+        pos = next;
+
+        if ((DTM.NULL != pos)
+                && ((null == countMatchPattern)
+                    || (countMatchPattern.getMatchScore(xctxt, pos)
+                        != XPath.MATCH_SCORE_NONE)))
+        {
+          break;
+        }
+      }
+    }
+    else  // NUMBERLEVEL_MULTI or NUMBERLEVEL_SINGLE
+    {
+      while (DTM.NULL != pos)
+      {
+        pos = dtm.getPreviousSibling(pos);
+
+        if ((DTM.NULL != pos)
+                && ((null == countMatchPattern)
+                    || (countMatchPattern.getMatchScore(xctxt, pos)
+                        != XPath.MATCH_SCORE_NONE)))
+        {
+          break;
+        }
+      }
+    }
+
+    return pos;
+  }
+
+  /**
+   * Get the target node that will be counted..
+   *
+   * @param xctxt The XPath runtime state for this.
+   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
+   *
+   * @return the target node that will be counted
+   *
+   * @throws TransformerException
+   */
+  public int getTargetNode(XPathContext xctxt, int sourceNode)
+          throws TransformerException
+  {
+
+    int target = DTM.NULL;
+    XPath countMatchPattern = getCountMatchPattern(xctxt, sourceNode);
+
+    if (Constants.NUMBERLEVEL_ANY == m_level)
+    {
+      target = findPrecedingOrAncestorOrSelf(xctxt, m_fromMatchPattern,
+                                             countMatchPattern, sourceNode,
+                                             this);
+    }
+    else
+    {
+      target = findAncestor(xctxt, m_fromMatchPattern, countMatchPattern,
+                            sourceNode, this);
+    }
+
+    return target;
+  }
+
+  /**
+   * Get the ancestors, up to the root, that match the
+   * pattern.
+   * 
+   * @param xctxt The XPath runtime state for this.
+   * @param node Count this node and it's ancestors.
+   * @param stopAtFirstFound Flag indicating to stop after the
+   * first node is found (difference between level = single
+   * or multiple)
+   * @return The number of ancestors that match the pattern.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  NodeVector getMatchingAncestors(
+          XPathContext xctxt, int node, boolean stopAtFirstFound)
+            throws javax.xml.transform.TransformerException
+  {
+
+    NodeSetDTM ancestors = new NodeSetDTM(xctxt.getDTMManager());
+    XPath countMatchPattern = getCountMatchPattern(xctxt, node);
+    DTM dtm = xctxt.getDTM(node);
+
+    while (DTM.NULL != node)
+    {
+      if ((null != m_fromMatchPattern)
+              && (m_fromMatchPattern.getMatchScore(xctxt, node)
+                  != XPath.MATCH_SCORE_NONE))
+      {
+
+        // The following if statement gives level="single" different 
+        // behavior from level="multiple", which seems incorrect according 
+        // to the XSLT spec.  For now we are leaving this in to replicate 
+        // the same behavior in XT, but, for all intents and purposes we 
+        // think this is a bug, or there is something about level="single" 
+        // that we still don't understand.
+        if (!stopAtFirstFound)
+          break;
+      }
+
+      if (null == countMatchPattern)
+        System.out.println(
+          "Programmers error! countMatchPattern should never be null!");
+
+      if (countMatchPattern.getMatchScore(xctxt, node)
+              != XPath.MATCH_SCORE_NONE)
+      {
+        ancestors.addElement(node);
+
+        if (stopAtFirstFound)
+          break;
+      }
+
+      node = dtm.getParent(node);
+    }
+
+    return ancestors;
+  }  // end getMatchingAncestors method
+
+  /**
+   * Get the locale we should be using.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param contextNode The node that "." expresses.
+   *
+   * @return The locale to use. May be specified by "lang" attribute,
+   * but if not, use default locale on the system. 
+   *
+   * @throws TransformerException
+   */
+  Locale getLocale(TransformerImpl transformer, int contextNode)
+          throws TransformerException
+  {
+
+    Locale locale = null;
+
+    if (null != m_lang_avt)
+    {
+      XPathContext xctxt = transformer.getXPathContext();
+      String langValue = m_lang_avt.evaluate(xctxt, contextNode, this);
+
+      if (null != langValue)
+      {
+
+        // Not really sure what to do about the country code, so I use the
+        // default from the system.
+        // TODO: fix xml:lang handling.
+        locale = new Locale(langValue.toUpperCase(), "");
+
+        //Locale.getDefault().getDisplayCountry());
+        if (null == locale)
+        {
+          transformer.getMsgMgr().warn(this, null, xctxt.getDTM(contextNode).getNode(contextNode),
+                                       XSLTErrorResources.WG_LOCALE_NOT_FOUND,
+                                       new Object[]{ langValue });  //"Warning: Could not find locale for xml:lang="+langValue);
+
+          locale = Locale.getDefault();
+        }
+      }
+    }
+    else
+    {
+      locale = Locale.getDefault();
+    }
+
+    return locale;
+  }
+
+  /**
+   * Get the number formatter to be used the format the numbers
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param contextNode The node that "." expresses.
+   *
+   * ($objectName$) @return The number formatter to be used
+   *
+   * @throws TransformerException
+   */
+  private DecimalFormat getNumberFormatter(
+          TransformerImpl transformer, int contextNode) throws TransformerException
+  {
+    // Patch from Steven Serocki
+    // Maybe we really want to do the clone in getLocale() and return  
+    // a clone of the default Locale??
+    Locale locale = (Locale)getLocale(transformer, contextNode).clone();
+
+    // Helper to format local specific numbers to strings.
+    DecimalFormat formatter = null;
+
+    //synchronized (locale)
+    //{
+    //     formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
+    //}
+
+    String digitGroupSepValue =
+      (null != m_groupingSeparator_avt)
+      ? m_groupingSeparator_avt.evaluate(
+      transformer.getXPathContext(), contextNode, this) : null;
+      
+      
+    // Validate grouping separator if an AVT was used; otherwise this was 
+    // validated statically in XSLTAttributeDef.java.
+    if ((digitGroupSepValue != null) && (!m_groupingSeparator_avt.isSimple()) &&
+        (digitGroupSepValue.length() != 1))
+    {
+            transformer.getMsgMgr().warn(
+               this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
+               new Object[]{ Constants.ATTRNAME_NAME, m_groupingSeparator_avt.getName()});   
+    }                  
+      
+      
+    String nDigitsPerGroupValue =
+      (null != m_groupingSize_avt)
+      ? m_groupingSize_avt.evaluate(
+      transformer.getXPathContext(), contextNode, this) : null;
+
+    // TODO: Handle digit-group attributes
+    if ((null != digitGroupSepValue) && (null != nDigitsPerGroupValue) &&
+        // Ignore if separation value is empty string
+        (digitGroupSepValue.length() > 0))
+    {
+      try
+      {
+        formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
+        formatter.setGroupingSize(
+          Integer.valueOf(nDigitsPerGroupValue).intValue());
+        
+        DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
+        symbols.setGroupingSeparator(digitGroupSepValue.charAt(0));
+        formatter.setDecimalFormatSymbols(symbols);
+        formatter.setGroupingUsed(true);
+      }
+      catch (NumberFormatException ex)
+      {
+        formatter.setGroupingUsed(false);
+      }
+    }
+
+    return formatter;
+  }
+
+  /**
+   * Format a vector of numbers into a formatted string.
+   * 
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param list Array of one or more long integer numbers.
+   * @param contextNode The node that "." expresses.
+   * @return String that represents list according to
+   * %conversion-atts; attributes.
+   * TODO: Optimize formatNumberList so that it caches the last count and
+   * reuses that info for the next count.
+   *
+   * @throws TransformerException
+   */
+  String formatNumberList(
+          TransformerImpl transformer, long[] list, int contextNode)
+            throws TransformerException
+  {
+
+    String numStr;
+    FastStringBuffer formattedNumber = StringBufferPool.get();
+
+    try
+    {
+      int nNumbers = list.length, numberWidth = 1;
+      char numberType = '1';
+      String formatToken, lastSepString = null, formatTokenString = null;
+
+      // If a seperator hasn't been specified, then use "."  
+      // as a default separator. 
+      // For instance: [2][1][5] with a format value of "1 "
+      // should format to "2.1.5 " (I think).
+      // Otherwise, use the seperator specified in the format string.
+      // For instance: [2][1][5] with a format value of "01-001. "
+      // should format to "02-001-005 ".
+      String lastSep = ".";
+      boolean isFirstToken = true;  // true if first token  
+      String formatValue =
+        (null != m_format_avt)
+        ? m_format_avt.evaluate(
+        transformer.getXPathContext(), contextNode, this) : null;
+
+      if (null == formatValue)
+        formatValue = "1";
+
+      NumberFormatStringTokenizer formatTokenizer =
+        new NumberFormatStringTokenizer(formatValue);
+
+      // int sepCount = 0;                  // keep track of seperators
+      // Loop through all the numbers in the list.
+      for (int i = 0; i < nNumbers; i++)
+      {
+
+        // Loop to the next digit, letter, or separator.
+        if (formatTokenizer.hasMoreTokens())
+        {
+          formatToken = formatTokenizer.nextToken();
+
+          // If the first character of this token is a character or digit, then 
+          // it is a number format directive.
+          if (Character.isLetterOrDigit(
+                  formatToken.charAt(formatToken.length() - 1)))
+          {
+            numberWidth = formatToken.length();
+            numberType = formatToken.charAt(numberWidth - 1);
+          }
+
+          // If there is a number format directive ahead, 
+          // then append the formatToken.
+          else if (formatTokenizer.isLetterOrDigitAhead())
+          {
+            formatTokenString = formatToken;
+
+            // Append the formatToken string...
+            // For instance [2][1][5] with a format value of "1--1. "
+            // should format to "2--1--5. " (I guess).
+            while (formatTokenizer.nextIsSep())
+            {
+              formatToken = formatTokenizer.nextToken();
+              formatTokenString += formatToken;
+            }
+
+            // Record this separator, so it can be used as the 
+            // next separator, if the next is the last.
+            // For instance: [2][1][5] with a format value of "1-1 "
+            // should format to "2-1-5 ".
+            if (!isFirstToken)
+              lastSep = formatTokenString;
+
+            // Since we know the next is a number or digit, we get it now.
+            formatToken = formatTokenizer.nextToken();
+            numberWidth = formatToken.length();
+            numberType = formatToken.charAt(numberWidth - 1);
+          }
+          else  // only separators left
+          {
+
+            // Set up the string for the trailing characters after 
+            // the last number is formatted (i.e. after the loop).
+            lastSepString = formatToken;
+
+            // And append any remaining characters to the lastSepString.
+            while (formatTokenizer.hasMoreTokens())
+            {
+              formatToken = formatTokenizer.nextToken();
+              lastSepString += formatToken;
+            }
+          }  // else
+        }  // end if(formatTokenizer.hasMoreTokens())
+
+        // if this is the first token and there was a prefix
+        // append the prefix else, append the separator
+        // For instance, [2][1][5] with a format value of "(1-1.) "
+        // should format to "(2-1-5.) " (I guess).
+        if (null != formatTokenString && isFirstToken)
+        {
+          formattedNumber.append(formatTokenString);
+        }
+        else if (null != lastSep &&!isFirstToken)
+          formattedNumber.append(lastSep);
+
+        getFormattedNumber(transformer, contextNode, numberType, numberWidth,
+                           list[i], formattedNumber);
+
+        isFirstToken = false;  // After the first pass, this should be false
+      }  // end for loop
+
+      // Check to see if we finished up the format string...
+      // Skip past all remaining letters or digits
+      while (formatTokenizer.isLetterOrDigitAhead())
+      {
+        formatTokenizer.nextToken();
+      }
+
+      if (lastSepString != null)
+        formattedNumber.append(lastSepString);
+
+      while (formatTokenizer.hasMoreTokens())
+      {
+        formatToken = formatTokenizer.nextToken();
+
+        formattedNumber.append(formatToken);
+      }
+
+      numStr = formattedNumber.toString();
+    }
+    finally
+    {
+      StringBufferPool.free(formattedNumber);
+    }
+
+    return numStr;
+  }  // end formatNumberList method
+
+  /*
+  * Get Formatted number
+  */
+
+  /**
+   * Format the given number and store it in the given buffer 
+   *
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param contextNode The node that "." expresses.
+   * @param numberType Type to format to
+   * @param numberWidth Maximum length of formatted number
+   * @param listElement Number to format
+   * @param formattedNumber Buffer to store formatted number
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private void getFormattedNumber(
+          TransformerImpl transformer, int contextNode, 
+          char numberType, int numberWidth, long listElement, 
+          FastStringBuffer formattedNumber)
+            throws javax.xml.transform.TransformerException
+  {
+
+
+    String letterVal =
+      (m_lettervalue_avt != null)
+      ? m_lettervalue_avt.evaluate(
+      transformer.getXPathContext(), contextNode, this) : null;
+
+    /**
+     * Wrapper of Chars for converting integers into alpha counts.
+     */
+    CharArrayWrapper alphaCountTable = null;
+    
+    XResourceBundle thisBundle = null;
+     
+    switch (numberType)
+    {
+    case 'A' :
+        if (null == m_alphaCountTable){
+                thisBundle =
+                  (XResourceBundle) XResourceBundle.loadResourceBundle(
+                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
+                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);                
+        }
+      int2alphaCount(listElement, m_alphaCountTable, formattedNumber);
+      break;
+    case 'a' :
+        if (null == m_alphaCountTable){
+                thisBundle =
+                  (XResourceBundle) XResourceBundle.loadResourceBundle(
+                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
+                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);                
+        }
+      FastStringBuffer stringBuf = StringBufferPool.get();
+
+      try
+      {
+        int2alphaCount(listElement, m_alphaCountTable, stringBuf);
+        formattedNumber.append(
+          stringBuf.toString().toLowerCase(
+            getLocale(transformer, contextNode)));
+      }
+      finally
+      {
+        StringBufferPool.free(stringBuf);
+      }
+      break;
+    case 'I' :
+      formattedNumber.append(long2roman(listElement, true));
+      break;
+    case 'i' :
+      formattedNumber.append(
+        long2roman(listElement, true).toLowerCase(
+          getLocale(transformer, contextNode)));
+      break;
+    case 0x3042 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HA"));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        formattedNumber.append(
+          int2singlealphaCount(
+            listElement,
+            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
+
+      break;
+    }
+    case 0x3044 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HI"));
+
+      if ((letterVal != null)
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        formattedNumber.append(
+          int2singlealphaCount(
+            listElement,
+            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
+
+      break;
+    }
+    case 0x30A2 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "A"));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        formattedNumber.append(
+          int2singlealphaCount(
+            listElement,
+            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
+
+      break;
+    }
+    case 0x30A4 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "I"));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        formattedNumber.append(
+          int2singlealphaCount(
+            listElement,
+            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
+
+      break;
+    }
+    case 0x4E00 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "CN"));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+      {
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      }
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x58F9 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "TW"));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x0E51 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("th", ""));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x05D0 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("he", ""));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x10D0 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ka", ""));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x03B1 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("el", ""));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    case 0x0430 :
+    {
+
+      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
+        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("cy", ""));
+
+      if (letterVal != null
+              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
+        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
+      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
+        int2alphaCount(listElement,
+                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
+                       formattedNumber);
+
+      break;
+    }
+    default :  // "1"
+      DecimalFormat formatter = getNumberFormatter(transformer, contextNode);
+      String padString = formatter == null ? String.valueOf(0) : formatter.format(0);    
+      String numString = formatter == null ? String.valueOf(listElement) : formatter.format(listElement);
+      int nPadding = numberWidth - numString.length();
+
+      for (int k = 0; k < nPadding; k++)
+      {
+        formattedNumber.append(padString);
+      }
+
+      formattedNumber.append(numString);
+    }
+  }
+  
+  /**
+   * Get a string value for zero, which is not really defined by the 1.0 spec, 
+   * thought I think it might be cleared up by the erreta.
+   */
+   String getZeroString()
+   {
+     return ""+0;
+   }
+
+  /**
+   * Convert a long integer into alphabetic counting, in other words
+   * count using the sequence A B C ... Z.
+   * 
+   * @param val Value to convert -- must be greater than zero.
+   * @param table a table containing one character for each digit in the radix
+   * @return String representing alpha count of number.
+   * @see TransformerImpl#DecimalToRoman
+   *
+   * Note that the radix of the conversion is inferred from the size
+   * of the table.
+   */
+  protected String int2singlealphaCount(long val, CharArrayWrapper table)
+  {
+
+    int radix = table.getLength();
+
+    // TODO:  throw error on out of range input
+    if (val > radix)
+    {
+      return getZeroString();
+    }
+    else
+      return (new Character(table.getChar((int)val - 1))).toString();  // index into table is off one, starts at 0
+  }
+
+  /**
+   * Convert a long integer into alphabetic counting, in other words
+   * count using the sequence A B C ... Z AA AB AC.... etc.
+   * 
+   * @param val Value to convert -- must be greater than zero.
+   * @param table a table containing one character for each digit in the radix
+   * @param aTable Array of alpha characters representing numbers
+   * @param stringBuf Buffer where to save the string representing alpha count of number.
+   * 
+   * @see TransformerImpl#DecimalToRoman
+   *
+   * Note that the radix of the conversion is inferred from the size
+   * of the table.
+   */
+  protected void int2alphaCount(long val, CharArrayWrapper aTable,
+                                FastStringBuffer stringBuf)
+  {
+
+    int radix = aTable.getLength();
+    char[] table = new char[radix];
+
+    // start table at 1, add last char at index 0. Reason explained above and below.
+    int i;
+
+    for (i = 0; i < radix - 1; i++)
+    {
+      table[i + 1] = aTable.getChar(i);
+    }
+
+    table[0] = aTable.getChar(i);
+
+    // Create a buffer to hold the result
+    // TODO:  size of the table can be detereined by computing
+    // logs of the radix.  For now, we fake it.
+    char buf[] = new char[100];
+
+    //some languages go left to right(ie. english), right to left (ie. Hebrew),
+    //top to bottom (ie.Japanese), etc... Handle them differently
+    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
+    // next character to set in the buffer
+    int charPos;
+
+    charPos = buf.length - 1;  // work backward through buf[]  
+
+    // index in table of the last character that we stored
+    int lookupIndex = 1;  // start off with anything other than zero to make correction work
+
+    //                                          Correction number
+    //
+    //  Correction can take on exactly two values:
+    //
+    //          0       if the next character is to be emitted is usual
+    //
+    //      radix - 1
+    //                  if the next char to be emitted should be one less than
+    //                  you would expect
+    //                  
+    // For example, consider radix 10, where 1="A" and 10="J"
+    //
+    // In this scheme, we count: A, B, C ...   H, I, J (not A0 and certainly
+    // not AJ), A1
+    //
+    // So, how do we keep from emitting AJ for 10?  After correctly emitting the
+    // J, lookupIndex is zero.  We now compute a correction number of 9 (radix-1).
+    // In the following line, we'll compute (val+correction) % radix, which is,
+    // (val+9)/10.  By this time, val is 1, so we compute (1+9) % 10, which
+    // is 10 % 10 or zero.  So, we'll prepare to emit "JJ", but then we'll
+    // later suppress the leading J as representing zero (in the mod system,
+    // it can represent either 10 or zero).  In summary, the correction value of
+    // "radix-1" acts like "-1" when run through the mod operator, but with the
+    // desireable characteristic that it never produces a negative number.
+    long correction = 0;
+
+    // TODO:  throw error on out of range input
+    do
+    {
+
+      // most of the correction calculation is explained above,  the reason for the
+      // term after the "|| " is that it correctly propagates carries across
+      // multiple columns.
+      correction =
+        ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
+        ? (radix - 1) : 0;
+
+      // index in "table" of the next char to emit
+      lookupIndex = (int)(val + correction) % radix;
+
+      // shift input by one "column"
+      val = (val / radix);
+
+      // if the next value we'd put out would be a leading zero, we're done.
+      if (lookupIndex == 0 && val == 0)
+        break;
+
+      // put out the next character of output
+      buf[charPos--] = table[lookupIndex];  // left to right or top to bottom   
+    }
+    while (val > 0);
+
+    stringBuf.append(buf, charPos + 1, (buf.length - charPos - 1));
+  }
+
+  /**
+   * Convert a long integer into traditional alphabetic counting, in other words
+   * count using the traditional numbering.
+   * 
+   * @param val Value to convert -- must be greater than zero.
+   * @param thisBundle Resource bundle to use
+   * 
+   * @return String representing alpha count of number.
+   * @see XSLProcessor#DecimalToRoman
+   *
+   * Note that the radix of the conversion is inferred from the size
+   * of the table.
+   */
+  protected String tradAlphaCount(long val, XResourceBundle thisBundle)
+  {
+
+    // if this number is larger than the largest number we can represent, error!
+    if (val > Long.MAX_VALUE)
+    {
+      this.error(XSLTErrorResources.ER_NUMBER_TOO_BIG);
+      return XSLTErrorResources.ERROR_STRING;
+    }
+    char[] table = null;
+
+    // index in table of the last character that we stored
+    int lookupIndex = 1;  // start off with anything other than zero to make correction work
+
+    // Create a buffer to hold the result
+    // TODO:  size of the table can be detereined by computing
+    // logs of the radix.  For now, we fake it.
+    char buf[] = new char[100];
+
+    //some languages go left to right(ie. english), right to left (ie. Hebrew),
+    //top to bottom (ie.Japanese), etc... Handle them differently
+    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
+    // next character to set in the buffer
+    int charPos;
+
+    charPos = 0;  //start at 0
+
+    // array of number groups: ie.1000, 100, 10, 1
+    IntArrayWrapper groups = (IntArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERGROUPS);
+
+    // array of tables of hundreds, tens, digits...
+    StringArrayWrapper tables =
+      (StringArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUM_TABLES));
+
+    //some languages have additive alphabetical notation,
+    //some multiplicative-additive, etc... Handle them differently.
+    String numbering = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERING);
+
+    // do multiplicative part first
+    if (numbering.equals(org.apache.xml.utils.res.XResourceBundle.LANG_MULT_ADD))
+    {
+      String mult_order = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.MULT_ORDER);
+      LongArrayWrapper multiplier =
+        (LongArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER));
+      CharArrayWrapper zeroChar = (CharArrayWrapper) thisBundle.getObject("zero");
+      int i = 0;
+
+      // skip to correct multiplier
+      while (i < multiplier.getLength() && val < multiplier.getLong(i))
+      {
+        i++;
+      }
+
+      do
+      {
+        if (i >= multiplier.getLength())
+          break;  //number is smaller than multipliers
+
+        // some languages (ie chinese) put a zero character (and only one) when
+        // the multiplier is multiplied by zero. (ie, 1001 is 1X1000 + 0X100 + 0X10 + 1)
+        // 0X100 is replaced by the zero character, we don't need one for 0X10
+        if (val < multiplier.getLong(i))
+        {
+          if (zeroChar.getLength() == 0)
+          {
+            i++;
+          }
+          else
+          {
+            if (buf[charPos - 1] != zeroChar.getChar(0))
+              buf[charPos++] = zeroChar.getChar(0);
+
+            i++;
+          }
+        }
+        else if (val >= multiplier.getLong(i))
+        {
+          long mult = val / multiplier.getLong(i);
+
+          val = val % multiplier.getLong(i);  // save this.
+
+          int k = 0;
+
+          while (k < groups.getLength())
+          {
+            lookupIndex = 1;  // initialize for each table
+
+            if (mult / groups.getInt(k) <= 0)  // look for right table
+              k++;
+            else
+            {
+
+              // get the table
+              CharArrayWrapper THEletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(k));
+
+              table = new char[THEletters.getLength() + 1];
+
+              int j;
+
+              for (j = 0; j < THEletters.getLength(); j++)
+              {
+                table[j + 1] = THEletters.getChar(j);
+              }
+
+              table[0] = THEletters.getChar(j - 1);  // don't need this                                                                         
+
+              // index in "table" of the next char to emit
+              lookupIndex = (int)mult / groups.getInt(k);
+
+              //this should not happen
+              if (lookupIndex == 0 && mult == 0)
+                break;
+
+              char multiplierChar = ((CharArrayWrapper) (thisBundle.getObject(
+                org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER_CHAR))).getChar(i);
+
+              // put out the next character of output   
+              if (lookupIndex < table.length)
+              {
+                if (mult_order.equals(org.apache.xml.utils.res.XResourceBundle.MULT_PRECEDES))
+                {
+                  buf[charPos++] = multiplierChar;
+                  buf[charPos++] = table[lookupIndex];
+                }
+                else
+                {
+
+                  // don't put out 1 (ie 1X10 is just 10)
+                  if (lookupIndex == 1 && i == multiplier.getLength() - 1){}
+                  else
+                    buf[charPos++] = table[lookupIndex];
+
+                  buf[charPos++] = multiplierChar;
+                }
+
+                break;  // all done!
+              }
+              else
+                return XSLTErrorResources.ERROR_STRING;
+            }  //end else
+          }  // end while        
+
+          i++;
+        }  // end else if
+      }  // end do while
+      while (i < multiplier.getLength());
+    }
+
+    // Now do additive part...
+    int count = 0;
+    String tableName;
+
+    // do this for each table of hundreds, tens, digits...
+    while (count < groups.getLength())
+    {
+      if (val / groups.getInt(count) <= 0)  // look for correct table
+        count++;
+      else
+      {
+        CharArrayWrapper theletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(count));
+
+        table = new char[theletters.getLength() + 1];
+
+        int j;
+
+        // need to start filling the table up at index 1
+        for (j = 0; j < theletters.getLength(); j++)
+        {
+          table[j + 1] = theletters.getChar(j);
+        }
+
+        table[0] = theletters.getChar(j - 1);  // don't need this
+
+        // index in "table" of the next char to emit
+        lookupIndex = (int)val / groups.getInt(count);
+
+        // shift input by one "column"
+        val = val % groups.getInt(count);
+
+        // this should not happen
+        if (lookupIndex == 0 && val == 0)
+          break;
+
+        if (lookupIndex < table.length)
+        {
+
+          // put out the next character of output       
+          buf[charPos++] = table[lookupIndex];  // left to right or top to bottom                                       
+        }
+        else
+          return XSLTErrorResources.ERROR_STRING;
+
+        count++;
+      }
+    }  // end while
+
+    // String s = new String(buf, 0, charPos);
+    return new String(buf, 0, charPos);
+  }
+
+  /**
+   * Convert a long integer into roman numerals.
+   * @param val Value to convert.
+   * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
+   * false_ to disable prefix notation (e.g. 4 = "IIII").
+   * @return Roman numeral string.
+   * @see DecimalToRoman
+   * @see m_romanConvertTable
+   */
+  protected String long2roman(long val, boolean prefixesAreOK)
+  {
+
+    if (val <= 0)
+    {
+      return getZeroString();
+    }
+
+    String roman = "";
+    int place = 0;
+
+    if (val <= 3999L)
+    {
+      do
+      {
+        while (val >= m_romanConvertTable[place].m_postValue)
+        {
+          roman += m_romanConvertTable[place].m_postLetter;
+          val -= m_romanConvertTable[place].m_postValue;
+        }
+
+        if (prefixesAreOK)
+        {
+          if (val >= m_romanConvertTable[place].m_preValue)
+          {
+            roman += m_romanConvertTable[place].m_preLetter;
+            val -= m_romanConvertTable[place].m_preValue;
+          }
+        }
+
+        place++;
+      }
+      while (val > 0);
+    }
+    else
+    {
+      roman = XSLTErrorResources.ERROR_STRING;
+    }
+
+    return roman;
+  }  // end long2roman
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  	{
+	  	if(null != m_countMatchPattern)
+	  		m_countMatchPattern.getExpression().callVisitors(m_countMatchPattern, visitor);
+	  	if(null != m_fromMatchPattern)
+	  		m_fromMatchPattern.getExpression().callVisitors(m_fromMatchPattern, visitor);
+	  	if(null != m_valueExpr)
+	  		m_valueExpr.getExpression().callVisitors(m_valueExpr, visitor);
+	
+	  	if(null != m_format_avt)
+	  		m_format_avt.callVisitors(visitor);
+	  	if(null != m_groupingSeparator_avt)
+	  		m_groupingSeparator_avt.callVisitors(visitor);
+	  	if(null != m_groupingSize_avt)
+	  		m_groupingSize_avt.callVisitors(visitor);
+	  	if(null != m_lang_avt)
+	  		m_lang_avt.callVisitors(visitor);
+	  	if(null != m_lettervalue_avt)
+	  		m_lettervalue_avt.callVisitors(visitor);
+  	}
+
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+
+  /**
+   * This class returns tokens using non-alphanumberic
+   * characters as delimiters.
+   */
+  class NumberFormatStringTokenizer
+  {
+
+    /** Current position in the format string          */
+    private int currentPosition;
+
+    /** Index of last character in the format string      */
+    private int maxPosition;
+
+    /** Format string to be tokenized        */
+    private String str;
+
+    /**
+     * Construct a NumberFormatStringTokenizer.
+     *
+     * @param str Format string to be tokenized
+     */
+    public NumberFormatStringTokenizer(String str)
+    {
+      this.str = str;
+      maxPosition = str.length();
+    }
+
+    /**
+     * Reset tokenizer so that nextToken() starts from the beginning.
+     */
+    public void reset()
+    {
+      currentPosition = 0;
+    }
+
+    /**
+     * Returns the next token from this string tokenizer.
+     *
+     * @return     the next token from this string tokenizer.
+     * @throws  NoSuchElementException  if there are no more tokens in this
+     *               tokenizer's string.
+     */
+    public String nextToken()
+    {
+
+      if (currentPosition >= maxPosition)
+      {
+        throw new NoSuchElementException();
+      }
+
+      int start = currentPosition;
+
+      while ((currentPosition < maxPosition)
+             && Character.isLetterOrDigit(str.charAt(currentPosition)))
+      {
+        currentPosition++;
+      }
+
+      if ((start == currentPosition)
+              && (!Character.isLetterOrDigit(str.charAt(currentPosition))))
+      {
+        currentPosition++;
+      }
+
+      return str.substring(start, currentPosition);
+    }
+
+    /**
+     * Tells if there is a digit or a letter character ahead.
+     *
+     * @return     true if there is a number or character ahead.
+     */
+    public boolean isLetterOrDigitAhead()
+    {
+
+      int pos = currentPosition;
+
+      while (pos < maxPosition)
+      {
+        if (Character.isLetterOrDigit(str.charAt(pos)))
+          return true;
+
+        pos++;
+      }
+
+      return false;
+    }
+
+    /**
+     * Tells if there is a digit or a letter character ahead.
+     *
+     * @return     true if there is a number or character ahead.
+     */
+    public boolean nextIsSep()
+    {
+
+      if (Character.isLetterOrDigit(str.charAt(currentPosition)))
+        return false;
+      else
+        return true;
+    }
+
+    /**
+     * Tells if <code>nextToken</code> will throw an exception
+     * if it is called.
+     *
+     * @return true if <code>nextToken</code> can be called
+     * without throwing an exception.
+     */
+    public boolean hasMoreTokens()
+    {
+      return (currentPosition >= maxPosition) ? false : true;
+    }
+
+    /**
+     * Calculates the number of times that this tokenizer's
+     * <code>nextToken</code> method can be called before it generates an
+     * exception.
+     *
+     * @return  the number of tokens remaining in the string using the current
+     *          delimiter set.
+     * @see     java.util.StringTokenizer#nextToken()
+     */
+    public int countTokens()
+    {
+
+      int count = 0;
+      int currpos = currentPosition;
+
+      while (currpos < maxPosition)
+      {
+        int start = currpos;
+
+        while ((currpos < maxPosition)
+               && Character.isLetterOrDigit(str.charAt(currpos)))
+        {
+          currpos++;
+        }
+
+        if ((start == currpos)
+                && (Character.isLetterOrDigit(str.charAt(currpos)) == false))
+        {
+          currpos++;
+        }
+
+        count++;
+      }
+
+      return count;
+    }
+  }  // end NumberFormatStringTokenizer
+
+
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemOtherwise.java b/src/main/java/org/apache/xalan/templates/ElemOtherwise.java
new file mode 100644
index 0000000..c2a137a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemOtherwise.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemOtherwise.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+
+/**
+ * Implement xsl:otherwise.
+ * <pre>
+ * <!ELEMENT xsl:otherwise %template;>
+ * <!ATTLIST xsl:otherwise %space-att;>
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose">XXX in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemOtherwise extends ElemTemplateElement
+{
+    static final long serialVersionUID = 1863944560970181395L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_OTHERWISE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_OTHERWISE_STRING;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemPI.java b/src/main/java/org/apache/xalan/templates/ElemPI.java
new file mode 100644
index 0000000..449a6b7
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemPI.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemPI.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.XML11Char;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Implement xsl:processing-instruction.
+ * <pre>
+ * <!ELEMENT xsl:processing-instruction %char-template;>
+ * <!ATTLIST xsl:processing-instruction
+ *   name %avt; #REQUIRED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemPI extends ElemTemplateElement
+{
+    static final long serialVersionUID = 5621976448020889825L;
+
+  /**
+   * The xsl:processing-instruction element has a required name
+   * attribute that specifies the name of the processing instruction node.
+   * The value of the name attribute is interpreted as an
+   * attribute value template.
+   * @serial
+   */
+  private AVT m_name_atv = null;
+
+  /**
+   * Set the "name" attribute.
+   * DJD
+   *
+   * @param v Value for the name attribute
+   */
+  public void setName(AVT v)
+  {
+    m_name_atv = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * DJD
+   *
+   * @return The value of the "name" attribute 
+   */
+  public AVT getName()
+  {
+    return m_name_atv;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+    if(null != m_name_atv)
+      m_name_atv.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+  }
+
+
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for the element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_PI;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_PI_STRING;
+  }
+
+  /**
+   * Create a processing instruction in the result tree.
+   * The content of the xsl:processing-instruction element is a
+   * template for the string-value of the processing instruction node.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    XPathContext xctxt = transformer.getXPathContext();
+    int sourceNode = xctxt.getCurrentNode();
+    
+    String piName = m_name_atv == null ? null : m_name_atv.evaluate(xctxt, sourceNode, this);
+    
+    // Ignore processing instruction if name is null
+    if (piName == null) return;
+
+    if (piName.equalsIgnoreCase("xml"))
+    {
+     	transformer.getMsgMgr().warn(
+        this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML,
+              new Object[]{ Constants.ATTRNAME_NAME, piName });
+		return;
+    }
+    
+    // Only check if an avt was used (ie. this wasn't checked at compose time.)
+    // Ignore processing instruction, if invalid
+    else if ((!m_name_atv.isSimple()) && (!XML11Char.isXML11ValidNCName(piName)))
+    {
+     	transformer.getMsgMgr().warn(
+        this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME,
+              new Object[]{ Constants.ATTRNAME_NAME, piName });
+		return;    	
+    }
+
+    // Note the content model is:
+    // <!ENTITY % instructions "
+    // %char-instructions;
+    // | xsl:processing-instruction
+    // | xsl:comment
+    // | xsl:element
+    // | xsl:attribute
+    // ">
+    String data = transformer.transformToString(this);
+
+    try
+    {
+      transformer.getResultTreeHandler().processingInstruction(piName, data);
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to child list
+   *
+   * @return The child just added to the child list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+
+    // char-instructions 
+    case Constants.ELEMNAME_TEXTLITERALRESULT :
+    case Constants.ELEMNAME_APPLY_TEMPLATES :
+    case Constants.ELEMNAME_APPLY_IMPORTS :
+    case Constants.ELEMNAME_CALLTEMPLATE :
+    case Constants.ELEMNAME_FOREACH :
+    case Constants.ELEMNAME_VALUEOF :
+    case Constants.ELEMNAME_COPY_OF :
+    case Constants.ELEMNAME_NUMBER :
+    case Constants.ELEMNAME_CHOOSE :
+    case Constants.ELEMNAME_IF :
+    case Constants.ELEMNAME_TEXT :
+    case Constants.ELEMNAME_COPY :
+    case Constants.ELEMNAME_VARIABLE :
+    case Constants.ELEMNAME_MESSAGE :
+
+      // instructions 
+      // case Constants.ELEMNAME_PI:
+      // case Constants.ELEMNAME_COMMENT:
+      // case Constants.ELEMNAME_ELEMENT:
+      // case Constants.ELEMNAME_ATTRIBUTE:
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemParam.java b/src/main/java/org/apache/xalan/templates/ElemParam.java
new file mode 100644
index 0000000..5e3feed
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemParam.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemParam.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implement xsl:param.
+ * <pre>
+ * <!ELEMENT xsl:param %template;>
+ * <!ATTLIST xsl:param
+ *   name %qname; #REQUIRED
+ *   select %expr; #IMPLIED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemParam extends ElemVariable
+{
+    static final long serialVersionUID = -1131781475589006431L;
+  int m_qnameID;
+
+  /**
+   * Constructor ElemParam
+   *
+   */
+  public ElemParam(){}
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID of the element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_PARAMVARIABLE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_PARAMVARIABLE_STRING;
+  }
+
+  /**
+   * Copy constructor.
+   *
+   * @param param Element from an xsl:param
+   *
+   * @throws TransformerException
+   */
+  public ElemParam(ElemParam param) throws TransformerException
+  {
+    super(param);
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    m_qnameID = sroot.getComposeState().getQNameID(m_qname);
+    int parentToken = m_parentNode.getXSLToken();
+    if (parentToken == Constants.ELEMNAME_TEMPLATE
+        || parentToken == Constants.EXSLT_ELEMNAME_FUNCTION)
+      ((ElemTemplate)m_parentNode).m_inArgsSize++;
+  }
+  
+  /**
+   * Execute a variable declaration and push it onto the variable stack.
+   * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+    VariableStack vars = transformer.getXPathContext().getVarStack();
+    
+    if(!vars.isLocalSet(m_index))
+    {
+
+      int sourceNode = transformer.getXPathContext().getCurrentNode();
+      XObject var = getValue(transformer, sourceNode);
+  
+      // transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
+      transformer.getXPathContext().getVarStack().setLocalVariable(m_index, var);
+    }
+  }
+  
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemSort.java b/src/main/java/org/apache/xalan/templates/ElemSort.java
new file mode 100644
index 0000000..c8f6c14
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemSort.java
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemSort.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xpath.XPath;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+
+/**
+ * Implement xsl:sort.
+ * <pre>
+ * <!ELEMENT xsl:sort EMPTY>
+ * <!ATTLIST xsl:sort
+ *   select %expr; "."
+ *   lang %avt; #IMPLIED
+ *   data-type %avt; "text"
+ *   order %avt; "ascending"
+ *   case-order %avt; #IMPLIED
+ * >
+ * <!-- xsl:sort cannot occur after any other elements or
+ * any non-whitespace character -->
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#sorting">sorting in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemSort extends ElemTemplateElement
+{
+    static final long serialVersionUID = -4991510257335851938L;
+
+  /**
+   * xsl:sort has a select attribute whose value is an expression.
+   * @serial
+   */
+  private XPath m_selectExpression = null;
+
+  /**
+   * Set the "select" attribute.
+   * xsl:sort has a select attribute whose value is an expression.
+   * For each node to be processed, the expression is evaluated
+   * with that node as the current node and with the complete
+   * list of nodes being processed in unsorted order as the current
+   * node list. The resulting object is converted to a string as if
+   * by a call to the string function; this string is used as the
+   * sort key for that node. The default value of the select attribute
+   * is ., which will cause the string-value of the current node to
+   * be used as the sort key.
+   *
+   * @param v Value to set for the "select" attribute
+   */
+  public void setSelect(XPath v)
+  {
+
+    if (v.getPatternString().indexOf("{") < 0)
+      m_selectExpression = v;
+    else
+      error(XSLTErrorResources.ER_NO_CURLYBRACE, null);
+  }
+
+  /**
+   * Get the "select" attribute.
+   * xsl:sort has a select attribute whose value is an expression.
+   * For each node to be processed, the expression is evaluated
+   * with that node as the current node and with the complete
+   * list of nodes being processed in unsorted order as the current
+   * node list. The resulting object is converted to a string as if
+   * by a call to the string function; this string is used as the
+   * sort key for that node. The default value of the select attribute
+   * is ., which will cause the string-value of the current node to
+   * be used as the sort key.
+   *
+   * @return The value of the "select" attribute
+   */
+  public XPath getSelect()
+  {
+    return m_selectExpression;
+  }
+
+  /**
+   * lang specifies the language of the sort keys.
+   * @serial
+   */
+  private AVT m_lang_avt = null;
+
+  /**
+   * Set the "lang" attribute.
+   * lang specifies the language of the sort keys; it has the same
+   * range of values as xml:lang [XML]; if no lang value is
+   * specified, the language should be determined from the system environment.
+   *
+   * @param v The value to set for the "lang" attribute
+   */
+  public void setLang(AVT v)
+  {
+    m_lang_avt = v;
+  }
+
+  /**
+   * Get the "lang" attribute.
+   * lang specifies the language of the sort keys; it has the same
+   * range of values as xml:lang [XML]; if no lang value is
+   * specified, the language should be determined from the system environment.
+   *
+   * @return The value of the "lang" attribute
+   */
+  public AVT getLang()
+  {
+    return m_lang_avt;
+  }
+
+  /**
+   * data-type specifies the data type of the
+   * strings to be sorted.
+   * @serial
+   */
+  private AVT m_dataType_avt = null;
+
+  /**
+   * Set the "data-type" attribute.
+   * <code>data-type</code> specifies the data type of the
+   * strings; the following values are allowed:
+   * <ul>
+   * <li>
+   * <code>text</code> specifies that the sort keys should be
+   * sorted lexicographically in the culturally correct manner for the
+   * language specified by <code>lang</code>.
+   * </li>
+   * <li>
+   * <code>number</code> specifies that the sort keys should be
+   * converted to numbers and then sorted according to the numeric value;
+   * the sort key is converted to a number as if by a call to the
+   * <b><a href="http://www.w3.org/TR/xpath#function-number">number</a></b> function; the <code>lang</code>
+   * attribute is ignored.
+   * </li>
+   * <li>
+   * A <a href="http://www.w3.org/TR/REC-xml-names#NT-QName">QName</a> with a prefix
+   * is expanded into an <a href="http://www.w3.org/TR/xpath#dt-expanded-name">expanded-name</a> as described
+   * in <a href="#qname">[<b>2.4 Qualified Names</b>]</a>; the expanded-name identifies the data-type;
+   * the behavior in this case is not specified by this document.
+   * </li>
+   * </ul>
+   * <p>The default value is <code>text</code>.</p>
+   * <blockquote>
+   * <b>NOTE: </b>The XSL Working Group plans that future versions of XSLT will
+   * leverage XML Schemas to define further values for this
+   * attribute.</blockquote>
+   *
+   * @param v Value to set for the "data-type" attribute
+   */
+  public void setDataType(AVT v)
+  {
+    m_dataType_avt = v;
+  }
+
+  /**
+   * Get the "data-type" attribute.
+   * <code>data-type</code> specifies the data type of the
+   * strings; the following values are allowed:
+   * <ul>
+   * <li>
+   * <code>text</code> specifies that the sort keys should be
+   * sorted lexicographically in the culturally correct manner for the
+   * language specified by <code>lang</code>.
+   * </li>
+   * <li>
+   * <code>number</code> specifies that the sort keys should be
+   * converted to numbers and then sorted according to the numeric value;
+   * the sort key is converted to a number as if by a call to the
+   * <b><a href="http://www.w3.org/TR/xpath#function-number">number</a></b> function; the <code>lang</code>
+   * attribute is ignored.
+   * </li>
+   * <li>
+   * A <a href="http://www.w3.org/TR/REC-xml-names#NT-QName">QName</a> with a prefix
+   * is expanded into an <a href="http://www.w3.org/TR/xpath#dt-expanded-name">expanded-name</a> as described
+   * in <a href="#qname">[<b>2.4 Qualified Names</b>]</a>; the expanded-name identifies the data-type;
+   * the behavior in this case is not specified by this document.
+   * </li>
+   * </ul>
+   * <p>The default value is <code>text</code>.</p>
+   * <blockquote>
+   * <b>NOTE: </b>The XSL Working Group plans that future versions of XSLT will
+   * leverage XML Schemas to define further values for this
+   * attribute.</blockquote>
+   *
+   * @return The value of the "data-type" attribute
+   */
+  public AVT getDataType()
+  {
+    return m_dataType_avt;
+  }
+
+  /**
+   * order specifies whether the strings should be sorted in ascending
+   * or descending order.
+   * @serial
+   */
+  private AVT m_order_avt = null;
+
+  /**
+   * Set the "order" attribute.
+   * order specifies whether the strings should be sorted in ascending
+   * or descending order; ascending specifies ascending order; descending
+   * specifies descending order; the default is ascending.
+   *
+   * @param v The value to set for the "order" attribute
+   */
+  public void setOrder(AVT v)
+  {
+    m_order_avt = v;
+  }
+
+  /**
+   * Get the "order" attribute.
+   * order specifies whether the strings should be sorted in ascending
+   * or descending order; ascending specifies ascending order; descending
+   * specifies descending order; the default is ascending.
+   *
+   * @return The value of the "order" attribute
+   */
+  public AVT getOrder()
+  {
+    return m_order_avt;
+  }
+
+  /**
+   * case-order has the value upper-first or lower-first.
+   * The default value is language dependent.
+   * @serial
+   */
+  private AVT m_caseorder_avt = null;
+
+  /**
+   * Set the "case-order" attribute.
+   * case-order has the value upper-first or lower-first; this applies
+   * when data-type="text", and specifies that upper-case letters should
+   * sort before lower-case letters or vice-versa respectively.
+   * For example, if lang="en", then A a B b are sorted with
+   * case-order="upper-first" and a A b B are sorted with case-order="lower-first".
+   * The default value is language dependent.
+   *
+   * @param v The value to set for the "case-order" attribute
+   * 
+   * @serial
+   */
+  public void setCaseOrder(AVT v)
+  {
+    m_caseorder_avt = v;
+  }
+
+  /**
+   * Get the "case-order" attribute.
+   * case-order has the value upper-first or lower-first; this applies
+   * when data-type="text", and specifies that upper-case letters should
+   * sort before lower-case letters or vice-versa respectively.
+   * For example, if lang="en", then A a B b are sorted with
+   * case-order="upper-first" and a A b B are sorted with case-order="lower-first".
+   * The default value is language dependent.
+   *
+   * @return The value of the "case-order" attribute
+   */
+  public AVT getCaseOrder()
+  {
+    return m_caseorder_avt;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID of the element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_SORT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_SORT_STRING;
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to the child list
+   *
+   * @return Child just added to the child list
+   *
+   * @throws DOMException
+   */
+  public Node appendChild(Node newChild) throws DOMException
+  {
+
+    error(XSLTErrorResources.ER_CANNOT_ADD,
+          new Object[]{ newChild.getNodeName(),
+                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    return null;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) 
+    throws javax.xml.transform.TransformerException
+  {
+    super.compose(sroot);
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    java.util.Vector vnames = cstate.getVariableNames();
+    if(null != m_caseorder_avt)
+      m_caseorder_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_dataType_avt)
+      m_dataType_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_lang_avt)
+      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_order_avt)
+      m_order_avt.fixupVariables(vnames, cstate.getGlobalsSize());
+    if(null != m_selectExpression)
+      m_selectExpression.fixupVariables(vnames, cstate.getGlobalsSize());
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemTemplate.java b/src/main/java/org/apache/xalan/templates/ElemTemplate.java
new file mode 100644
index 0000000..cc17381
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemTemplate.java
@@ -0,0 +1,413 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemTemplate.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Implement xsl:template.
+ * <pre>
+ * <!ELEMENT xsl:template
+ *  (#PCDATA
+ *   %instructions;
+ *   %result-elements;
+ *   | xsl:param)
+ * >
+ *
+ * <!ATTLIST xsl:template
+ *   match %pattern; #IMPLIED
+ *   name %qname; #IMPLIED
+ *   priority %priority; #IMPLIED
+ *   mode %qname; #IMPLIED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemTemplate extends ElemTemplateElement
+{
+    static final long serialVersionUID = -5283056789965384058L;
+  /** The public identifier for the current document event.
+   *  @serial          */
+  private String m_publicId;
+
+  /** The system identifier for the current document event.
+   *  @serial          */
+  private String m_systemId;
+
+  /**
+   * Return the public identifier for the current document event.
+   * <p>This will be the public identifier
+   * @return A string containing the public identifier, or
+   *         null if none is available.
+   * @see #getSystemId
+   */
+  public String getPublicId()
+  {
+    return m_publicId;
+  }
+
+  /**
+   * Return the system identifier for the current document event.
+   *
+   * <p>If the system identifier is a URL, the parser must resolve it
+   * fully before passing it to the application.</p>
+   *
+   * @return A string containing the system identifier, or null
+   *         if none is available.
+   * @see #getPublicId
+   */
+  public String getSystemId()
+  {
+    return m_systemId;
+  }
+
+  /**
+   * Set the location information for this element.
+   *
+   * @param locator SourceLocator holding location information 
+   */
+  public void setLocaterInfo(SourceLocator locator)
+  {
+
+    m_publicId = locator.getPublicId();
+    m_systemId = locator.getSystemId();
+
+    super.setLocaterInfo(locator);
+  }
+
+  /**
+   * The owning stylesheet.
+   * (Should this only be put on the template element, to
+   * conserve space?)
+   * @serial
+   */
+  private Stylesheet m_stylesheet;
+
+  /**
+   * Get the stylesheet composed (resolves includes and
+   * imports and has methods on it that return "composed" properties.
+   * 
+   * @return The stylesheet composed.
+   */
+  public StylesheetComposed getStylesheetComposed()
+  {
+    return m_stylesheet.getStylesheetComposed();
+  }
+
+  /**
+   * Get the owning stylesheet.
+   *
+   * @return The owning stylesheet.
+   */
+  public Stylesheet getStylesheet()
+  {
+    return m_stylesheet;
+  }
+
+  /**
+   * Set the owning stylesheet.
+   *
+   * @param sheet The owning stylesheet for this element
+   */
+  public void setStylesheet(Stylesheet sheet)
+  {
+    m_stylesheet = sheet;
+  }
+
+  /**
+   * Get the root stylesheet.
+   *
+   * @return The root stylesheet for this element
+   */
+  public StylesheetRoot getStylesheetRoot()
+  {
+    return m_stylesheet.getStylesheetRoot();
+  }
+
+  /**
+   * The match attribute is a Pattern that identifies the source
+   * node or nodes to which the rule applies.
+   * @serial
+   */
+  private XPath m_matchPattern = null;
+
+  /**
+   * Set the "match" attribute.
+   * The match attribute is a Pattern that identifies the source
+   * node or nodes to which the rule applies. The match attribute
+   * is required unless the xsl:template element has a name
+   * attribute (see [6 Named Templates]). It is an error for the
+   * value of the match attribute to contain a VariableReference.
+   * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
+   *
+   * @param v Value to set for the "match" attribute
+   */
+  public void setMatch(XPath v)
+  {
+    m_matchPattern = v;
+  }
+
+  /**
+   * Get the "match" attribute.
+   * The match attribute is a Pattern that identifies the source
+   * node or nodes to which the rule applies. The match attribute
+   * is required unless the xsl:template element has a name
+   * attribute (see [6 Named Templates]). It is an error for the
+   * value of the match attribute to contain a VariableReference.
+   * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
+   *
+   * @return Value of the "match" attribute 
+   */
+  public XPath getMatch()
+  {
+    return m_matchPattern;
+  }
+
+  /**
+   * An xsl:template element with a name attribute specifies a named template.
+   * @serial
+   */
+  private QName m_name = null;
+
+  /**
+   * Set the "name" attribute.
+   * An xsl:template element with a name attribute specifies a named template.
+   * If an xsl:template element has a name attribute, it may, but need not,
+   * also have a match attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
+   *
+   * @param v Value to set the "name" attribute
+   */
+  public void setName(QName v)
+  {
+    m_name = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * An xsl:template element with a name attribute specifies a named template.
+   * If an xsl:template element has a name attribute, it may, but need not,
+   * also have a match attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
+   *
+   * @return Value of the "name" attribute
+   */
+  public QName getName()
+  {
+    return m_name;
+  }
+
+  /**
+   * Modes allow an element to be processed multiple times,
+   * each time producing a different result.
+   * @serial
+   */
+  private QName m_mode;
+
+  /**
+   * Set the "mode" attribute.
+   * Modes allow an element to be processed multiple times,
+   * each time producing a different result.  If xsl:template
+   * does not have a match attribute, it must not have a mode attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
+   *
+   * @param v Value to set the "mode" attribute
+   */
+  public void setMode(QName v)
+  {
+    m_mode = v;
+  }
+
+  /**
+   * Get the "mode" attribute.
+   * Modes allow an element to be processed multiple times,
+   * each time producing a different result.  If xsl:template
+   * does not have a match attribute, it must not have a mode attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
+   *
+   * @return Value of the "mode" attribute
+   */
+  public QName getMode()
+  {
+    return m_mode;
+  }
+
+  /**
+   * The priority of a template rule is specified by the priority
+   * attribute on the template rule.
+   * @serial
+   */
+  private double m_priority = XPath.MATCH_SCORE_NONE;
+
+  /**
+   * Set the "priority" attribute.
+   * The priority of a template rule is specified by the priority
+   * attribute on the template rule. The value of this must be a
+   * real number (positive or negative), matching the production
+   * Number with an optional leading minus sign (-).
+   * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
+   *
+   * @param v The value to set for the "priority" attribute
+   */
+  public void setPriority(double v)
+  {
+    m_priority = v;
+  }
+
+  /**
+   * Get the "priority" attribute.
+   * The priority of a template rule is specified by the priority
+   * attribute on the template rule. The value of this must be a
+   * real number (positive or negative), matching the production
+   * Number with an optional leading minus sign (-).
+   * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
+   *
+   * @return The value of the "priority" attribute
+   */
+  public double getPriority()
+  {
+    return m_priority;
+  }
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for the element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_TEMPLATE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_TEMPLATE_STRING;
+  }
+  
+  /**
+   * The stack frame size for this template, which is equal to the maximum number 
+   * of params and variables that can be declared in the template at one time.
+   */
+  public int m_frameSize;
+  
+  /**
+   * The size of the portion of the stack frame that can hold parameter 
+   * arguments.
+   */
+  int m_inArgsSize;
+  
+  /**
+   * List of namespace/local-name pairs, DTM style, that are unique 
+   * qname identifiers for the arguments.  The position of a given qname 
+   * in the list is the argument ID, and thus the position in the stack
+   * frame.
+   */
+  private int[] m_argsQNameIDs;
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    java.util.Vector vnames = cstate.getVariableNames();
+    if(null != m_matchPattern)
+      m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+      
+    cstate.resetStackFrameSize();
+    m_inArgsSize = 0;
+  }
+  
+  /**
+   * This after the template's children have been composed.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    super.endCompose(sroot);
+    m_frameSize = cstate.getFrameSize();
+    
+    cstate.resetStackFrameSize();
+  }
+
+  /**
+   * Copy the template contents into the result tree.
+   * The content of the xsl:template element is the template
+   * that is instantiated when the template rule is applied.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    XPathContext xctxt = transformer.getXPathContext();
+    
+    xctxt.pushRTFContext();
+
+      // %REVIEW% commenting out of the code below.
+//    if (null != sourceNode)
+//    {
+      transformer.executeChildTemplates(this, true);
+//    }
+//    else  // if(null == sourceNode)
+//    {
+//      transformer.getMsgMgr().error(this,
+//        this, sourceNode,
+//        XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES);
+//
+//      //"sourceNode is null in handleApplyTemplatesInstruction!");
+//    }
+
+    xctxt.popRTFContext();
+    }
+
+  /**
+   * This function is called during recomposition to
+   * control how this element is composed.
+   * @param root The root stylesheet for this transformation.
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeTemplates(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemTemplateElement.java b/src/main/java/org/apache/xalan/templates/ElemTemplateElement.java
new file mode 100644
index 0000000..8a4cedf
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemTemplateElement.java
@@ -0,0 +1,1660 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemTemplateElement.java 475981 2006-11-16 23:35:53Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.UnImplNode;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.WhitespaceStrippingElementMatcher;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.helpers.NamespaceSupport;
+
+/**
+ * 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
+ * @xsl.usage advanced
+ */
+public class ElemTemplateElement extends UnImplNode
+        implements PrefixResolver, Serializable, ExpressionNode, 
+                   WhitespaceStrippingElementMatcher, XSLTVisitable
+{
+    static final long serialVersionUID = 4440018597841834447L;
+
+  /**
+   * Construct a template element instance.
+   *
+   */
+  public ElemTemplateElement(){}
+
+  /**
+   * Tell if this template is a compiled template.
+   *
+   * @return Boolean flag indicating whether this is a compiled template   
+   */
+  public boolean isCompiledTemplate()
+  {
+    return false;
+  }
+
+  /**
+   * 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_UNDEFINED;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return An invalid node name
+   */
+  public String getNodeName()
+  {
+    return "Unknown XSLT Element";
+  }
+  
+  /**
+   * For now, just return the result of getNodeName(), which 
+   * the local name.
+   *
+   * @return The result of getNodeName().
+   */
+  public String getLocalName()
+  {
+
+    return getNodeName();
+  }
+
+
+  /**
+   * This function will be called on top-level elements
+   * only, just before the transform begins.
+   *
+   * @param transformer The XSLT TransformerFactory.
+   *
+   * @throws TransformerException
+   */
+  public void runtimeInit(TransformerImpl transformer) throws TransformerException{}
+
+  /**
+   * Execute the element's primary function.  Subclasses of this
+   * function may recursivly execute down the element tree.
+   *
+   * @param transformer The XSLT TransformerFactory.
+   * 
+   * @throws TransformerException if any checked exception occurs.
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException{}
+
+  /**
+   * Get the owning "composed" stylesheet.  This looks up the
+   * inheritance chain until it calls getStylesheetComposed
+   * on a Stylesheet object, which will Get the owning
+   * aggregated stylesheet, or that stylesheet if it is aggregated.
+   *
+   * @return the owning "composed" stylesheet.
+   */
+  public StylesheetComposed getStylesheetComposed()
+  {
+    return m_parentNode.getStylesheetComposed();
+  }
+
+  /**
+   * Get the owning stylesheet.  This looks up the
+   * inheritance chain until it calls getStylesheet
+   * on a Stylesheet object, which will return itself.
+   *
+   * @return the owning stylesheet
+   */
+  public Stylesheet getStylesheet()
+  {
+    return (null==m_parentNode) ? null : m_parentNode.getStylesheet();
+  }
+
+  /**
+   * Get the owning root stylesheet.  This looks up the
+   * inheritance chain until it calls StylesheetRoot
+   * on a Stylesheet object, which will return a reference
+   * to the root stylesheet.
+   *
+   * @return the owning root stylesheet
+   */
+  public StylesheetRoot getStylesheetRoot()
+  {
+    return m_parentNode.getStylesheetRoot();
+  }
+
+  /**
+   * This function is called during recomposition to
+   * control how this element is composed.
+   */
+  public void recompose(StylesheetRoot root) throws TransformerException
+  {
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    resolvePrefixTables();
+    ElemTemplateElement t = getFirstChildElem();
+    m_hasTextLitOnly = ((t != null) 
+              && (t.getXSLToken() == Constants.ELEMNAME_TEXTLITERALRESULT) 
+              && (t.getNextSiblingElem() == null));
+              
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    cstate.pushStackMark();
+  }
+  
+  /**
+   * This after the template's children have been composed.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    cstate.popStackMark();
+  }
+
+  /**
+   * Throw a template element runtime error.  (Note: should we throw a TransformerException instead?)
+   *
+   * @param msg key of the error that occured.
+   * @param args Arguments to be used in the message
+   */
+  public void error(String msg, Object[] args)
+  {
+
+    String themsg = XSLMessages.createMessage(msg, args);
+
+    throw new RuntimeException(XSLMessages.createMessage(
+                                    XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
+                                    new Object[]{ themsg }));
+  }
+  
+  /*
+   * Throw an error.
+   *
+   * @param msg Message key for the error
+   *
+   */
+  public void error(String msg)
+  {
+    error(msg, null);
+  }
+  
+
+  // Implemented DOM Element methods.
+  /**
+   * Add a child to the child list.
+   * NOTE: This presumes the child did not previously have a parent.
+   * Making that assumption makes this a less expensive operation -- but
+   * requires that if you *do* want to reparent a node, you use removeChild()
+   * first to remove it from its previous context. Failing to do so will
+   * damage the tree.
+   *
+   * @param newChild Child to be added to child list
+   *
+   * @return Child just added to the child list
+   * @throws DOMException
+   */
+  public Node appendChild(Node newChild) throws DOMException
+  {
+
+    if (null == newChild)
+    {
+      error(XSLTErrorResources.ER_NULL_CHILD, null);  //"Trying to add a null child!");
+    }
+
+    ElemTemplateElement elem = (ElemTemplateElement) newChild;
+
+    if (null == m_firstChild)
+    {
+      m_firstChild = elem;
+    }
+    else
+    {
+      ElemTemplateElement last = (ElemTemplateElement) getLastChild();
+
+      last.m_nextSibling = elem;
+    }
+
+    elem.m_parentNode = this;
+
+    return newChild;
+  }
+
+  /**
+   * Add a child to the child list.
+   * NOTE: This presumes the child did not previously have a parent.
+   * Making that assumption makes this a less expensive operation -- but
+   * requires that if you *do* want to reparent a node, you use removeChild()
+   * first to remove it from its previous context. Failing to do so will
+   * damage the tree.
+   *
+   * @param elem Child to be added to child list
+   *
+   * @return Child just added to the child list
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement elem)
+  {
+
+    if (null == elem)
+    {
+      error(XSLTErrorResources.ER_NULL_CHILD, null);  //"Trying to add a null child!");
+    }
+
+    if (null == m_firstChild)
+    {
+      m_firstChild = elem;
+    }
+    else
+    {
+      ElemTemplateElement last = getLastChildElem();
+
+      last.m_nextSibling = elem;
+    }
+
+    elem.setParentElem(this);
+
+    return elem;
+  }
+
+
+  /**
+   * Tell if there are child nodes.
+   *
+   * @return True if there are child nodes
+   */
+  public boolean hasChildNodes()
+  {
+    return (null != m_firstChild);
+  }
+
+  /**
+   * Get the type of the node.
+   *
+   * @return Constant for this node type
+   */
+  public short getNodeType()
+  {
+    return org.w3c.dom.Node.ELEMENT_NODE;
+  }
+
+  /**
+   * Return the nodelist (same reference).
+   *
+   * @return The nodelist containing the child nodes (this)
+   */
+  public NodeList getChildNodes()
+  {
+    return this;
+  }
+
+  /**
+   * Remove a child.
+   * ADDED 9/8/200 to support compilation.
+   * TODO: ***** Alternative is "removeMe() from my parent if any"
+   * ... which is less well checked, but more convenient in some cases.
+   * Given that we assume only experts are calling this class, it might
+   * be preferable. It's less DOMish, though.
+   * 
+   * @param childETE The child to remove. This operation is a no-op
+   * if oldChild is not a child of this node.
+   *
+   * @return the removed child, or null if the specified
+   * node was not a child of this element.
+   */
+  public ElemTemplateElement removeChild(ElemTemplateElement childETE)
+  {
+
+    if (childETE == null || childETE.m_parentNode != this)
+      return null;
+
+    // Pointers to the child
+    if (childETE == m_firstChild)
+      m_firstChild = childETE.m_nextSibling;
+    else
+    {
+      ElemTemplateElement prev = childETE.getPreviousSiblingElem();
+
+      prev.m_nextSibling = childETE.m_nextSibling;
+    }
+
+    // Pointers from the child
+    childETE.m_parentNode = null;
+    childETE.m_nextSibling = null;
+
+    return childETE;
+  }
+
+  /**
+   * Replace the old child with a new child.
+   *
+   * @param newChild New child to replace with
+   * @param oldChild Old child to be replaced
+   *
+   * @return The new child
+   *
+   * @throws DOMException
+   */
+  public Node replaceChild(Node newChild, Node oldChild) throws DOMException
+  {
+
+    if (oldChild == null || oldChild.getParentNode() != this)
+      return null;
+
+    ElemTemplateElement newChildElem = ((ElemTemplateElement) newChild);
+    ElemTemplateElement oldChildElem = ((ElemTemplateElement) oldChild);
+
+    // Fix up previous sibling.
+    ElemTemplateElement prev =
+      (ElemTemplateElement) oldChildElem.getPreviousSibling();
+
+    if (null != prev)
+      prev.m_nextSibling = newChildElem;
+
+    // Fix up parent (this)
+    if (m_firstChild == oldChildElem)
+      m_firstChild = newChildElem;
+
+    newChildElem.m_parentNode = this;
+    oldChildElem.m_parentNode = null;
+    newChildElem.m_nextSibling = oldChildElem.m_nextSibling;
+    oldChildElem.m_nextSibling = null;
+
+    // newChildElem.m_stylesheet = oldChildElem.m_stylesheet;
+    // oldChildElem.m_stylesheet = null;
+    return newChildElem;
+  }
+  
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param newChild New child node to insert
+   * @param refChild Insert in front of this child
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node insertBefore(Node newChild, Node refChild) throws DOMException
+  {
+  	if(null == refChild)
+  	{
+  		appendChild(newChild);
+  		return newChild;
+  	}
+  	
+  	if(newChild == refChild)
+  	{
+  		// hmm...
+  		return newChild;
+  	}
+
+    Node node = m_firstChild; 
+    Node prev = null;  
+    boolean foundit = false;
+    
+    while (null != node)
+    {
+    	// If the newChild is already in the tree, it is first removed.
+    	if(newChild == node)
+    	{
+    		if(null != prev)
+    			((ElemTemplateElement)prev).m_nextSibling = 
+    				(ElemTemplateElement)node.getNextSibling();
+    		else
+    			m_firstChild = (ElemTemplateElement)node.getNextSibling();
+    		node = node.getNextSibling();
+    		continue; // prev remains the same.
+    	}
+    	if(refChild == node)
+    	{
+    		if(null != prev)
+    		{
+    			((ElemTemplateElement)prev).m_nextSibling = (ElemTemplateElement)newChild;
+    		}
+    		else
+    		{
+    			m_firstChild = (ElemTemplateElement)newChild;
+    		}
+    		((ElemTemplateElement)newChild).m_nextSibling = (ElemTemplateElement)refChild;
+    		((ElemTemplateElement)newChild).setParentElem(this);
+    		prev = newChild;
+    		node = node.getNextSibling();
+    		foundit = true;
+    		continue;
+    	}
+    	prev = node;
+    	node = node.getNextSibling();
+    }
+    
+    if(!foundit)
+    	throw new DOMException(DOMException.NOT_FOUND_ERR, 
+    		"refChild was not found in insertBefore method!");
+    else
+    	return newChild;
+  }
+
+
+  /**
+   * Replace the old child with a new child.
+   *
+   * @param newChildElem New child to replace with
+   * @param oldChildElem Old child to be replaced
+   *
+   * @return The new child
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement replaceChild(ElemTemplateElement newChildElem, 
+                                          ElemTemplateElement oldChildElem)
+  {
+
+    if (oldChildElem == null || oldChildElem.getParentElem() != this)
+      return null;
+
+    // Fix up previous sibling.
+    ElemTemplateElement prev =
+      oldChildElem.getPreviousSiblingElem();
+
+    if (null != prev)
+      prev.m_nextSibling = newChildElem;
+
+    // Fix up parent (this)
+    if (m_firstChild == oldChildElem)
+      m_firstChild = newChildElem;
+
+    newChildElem.m_parentNode = this;
+    oldChildElem.m_parentNode = null;
+    newChildElem.m_nextSibling = oldChildElem.m_nextSibling;
+    oldChildElem.m_nextSibling = null;
+
+    // newChildElem.m_stylesheet = oldChildElem.m_stylesheet;
+    // oldChildElem.m_stylesheet = null;
+    return newChildElem;
+  }
+
+  /**
+   * NodeList method: Count the immediate children of this node
+   *
+   * @return The count of children of this node
+   */
+  public int getLength()
+  {
+
+    // It is assumed that the getChildNodes call synchronized
+    // the children. Therefore, we can access the first child
+    // reference directly.
+    int count = 0;
+
+    for (ElemTemplateElement node = m_firstChild; node != null;
+            node = node.m_nextSibling)
+    {
+      count++;
+    }
+
+    return count;
+  }  // getLength():int
+
+  /**
+   * NodeList method: Return the Nth immediate child of this node, or
+   * null if the index is out of bounds.
+   *
+   * @param index Index of child to find
+   * @return org.w3c.dom.Node: the child node at given index
+   */
+  public Node item(int index)
+  {
+
+    // It is assumed that the getChildNodes call synchronized
+    // the children. Therefore, we can access the first child
+    // reference directly.
+    ElemTemplateElement node = m_firstChild;
+
+    for (int i = 0; i < index && node != null; i++)
+    {
+      node = node.m_nextSibling;
+    }
+
+    return node;
+  }  // item(int):Node
+
+  /**
+   * Get the stylesheet owner.
+   *
+   * @return The stylesheet owner
+   */
+  public Document getOwnerDocument()
+  {
+    return getStylesheet();
+  }
+  
+  /**
+   * Get the owning xsl:template element.
+   *
+   * @return The owning xsl:template element, this element if it is a xsl:template, or null if not found.
+   */
+  public ElemTemplate getOwnerXSLTemplate()
+  {
+  	ElemTemplateElement el = this;
+  	int type = el.getXSLToken();
+  	while((null != el) && (type != Constants.ELEMNAME_TEMPLATE))
+  	{
+    	el = el.getParentElem();
+    	if(null != el)
+  			type = el.getXSLToken();
+  	}
+  	return (ElemTemplate)el;
+  }
+
+
+  /**
+   * Return the element name.
+   *
+   * @return The element name
+   */
+  public String getTagName()
+  {
+    return getNodeName();
+  }
+  
+  /**
+   * Tell if this element only has one text child, for optimization purposes.
+   * @return true of this element only has one text literal child.
+   */
+  public boolean hasTextLitOnly()
+  {
+    return m_hasTextLitOnly;
+  }
+
+  /**
+   * Return the base identifier.
+   *
+   * @return The base identifier 
+   */
+  public String getBaseIdentifier()
+  {
+
+    // Should this always be absolute?
+    return this.getSystemId();
+  }
+
+  /** line number where the current document event ends.
+   *  @serial         */
+  private int m_lineNumber;
+
+  /** line number where the current document event ends.
+   *  @serial         */
+  private int m_endLineNumber;
+
+  /**
+   * Return the line number where the current document event ends.
+   * Note that this is the line position of the first character
+   * after the text associated with the document event.
+   * @return The line number, or -1 if none is available.
+   * @see #getColumnNumber
+   */
+  public int getEndLineNumber()
+  {
+	return m_endLineNumber;
+  }
+
+  /**
+   * Return the line number where the current document event ends.
+   * Note that this is the line position of the first character
+   * after the text associated with the document event.
+   * @return The line number, or -1 if none is available.
+   * @see #getColumnNumber
+   */
+  public int getLineNumber()
+  {
+    return m_lineNumber;
+  }
+
+  /** the column number where the current document event ends.
+   *  @serial        */
+  private int m_columnNumber;
+
+  /** the column number where the current document event ends.
+   *  @serial        */
+  private int m_endColumnNumber;
+
+  /**
+   * Return the column number where the current document event ends.
+   * Note that this is the column number of the first
+   * character after the text associated with the document
+   * event.  The first column in a line is position 1.
+   * @return The column number, or -1 if none is available.
+   * @see #getLineNumber
+   */
+  public int getEndColumnNumber()
+  {
+	return m_endColumnNumber;
+  }
+
+  /**
+   * Return the column number where the current document event ends.
+   * Note that this is the column number of the first
+   * character after the text associated with the document
+   * event.  The first column in a line is position 1.
+   * @return The column number, or -1 if none is available.
+   * @see #getLineNumber
+   */
+  public int getColumnNumber()
+  {
+    return m_columnNumber;
+  }
+
+  /**
+   * Return the public identifier for the current document event.
+   * <p>This will be the public identifier
+   * @return A string containing the public identifier, or
+   *         null if none is available.
+   * @see #getSystemId
+   */
+  public String getPublicId()
+  {
+    return (null != m_parentNode) ? m_parentNode.getPublicId() : null;
+  }
+
+  /**
+   * Return the system identifier for the current document event.
+   *
+   * <p>If the system identifier is a URL, the parser must resolve it
+   * fully before passing it to the application.</p>
+   *
+   * @return A string containing the system identifier, or null
+   *         if none is available.
+   * @see #getPublicId
+   */
+  public String getSystemId()
+  {
+    Stylesheet sheet=getStylesheet();
+    return (sheet==null) ? null : sheet.getHref();
+  }
+
+  /**
+   * Set the location information for this element.
+   *
+   * @param locator Source Locator with location information for this element
+   */
+  public void setLocaterInfo(SourceLocator locator)
+  {
+    m_lineNumber = locator.getLineNumber();
+    m_columnNumber = locator.getColumnNumber();
+  }
+  
+  /**
+   * Set the end location information for this element.
+   *
+   * @param locator Source Locator with location information for this element
+   */
+  public void setEndLocaterInfo(SourceLocator locator)
+  {
+	m_endLineNumber = locator.getLineNumber();
+	m_endColumnNumber = locator.getColumnNumber();
+  } 
+
+  /**
+   * Tell if this element has the default space handling
+   * turned off or on according to the xml:space attribute.
+   * @serial
+   */
+  private boolean m_defaultSpace = true;
+
+  /**
+   * Tell if this element only has one text child, for optimization purposes.
+   * @serial
+   */
+  private boolean m_hasTextLitOnly = false;
+
+  /**
+   * Tell if this element only has one text child, for optimization purposes.
+   * @serial
+   */
+  protected boolean m_hasVariableDecl = false;
+  
+  public boolean hasVariableDecl()
+  {
+    return m_hasVariableDecl;
+  }
+
+  /**
+   * Set the "xml:space" attribute.
+   * A text node is preserved if an ancestor element of the text node
+   * has an xml:space attribute with a value of preserve, and
+   * no closer ancestor element has xml:space with a value of default.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text in XSLT Specification</a>
+   *
+   * @param v  Enumerated value, either Constants.ATTRVAL_PRESERVE 
+   * or Constants.ATTRVAL_STRIP.
+   */
+  public void setXmlSpace(int v)
+  {
+    m_defaultSpace = ((Constants.ATTRVAL_STRIP == v) ? true : false);
+  }
+
+  /**
+   * Get the "xml:space" attribute.
+   * A text node is preserved if an ancestor element of the text node
+   * has an xml:space attribute with a value of preserve, and
+   * no closer ancestor element has xml:space with a value of default.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text in XSLT Specification</a>
+   *
+   * @return The value of the xml:space attribute
+   */
+  public boolean getXmlSpace()
+  {
+    return m_defaultSpace;
+  }
+
+  /**
+   * The list of namespace declarations for this element only.
+   * @serial
+   */
+  private List m_declaredPrefixes;
+
+  /**
+   * Return a table that contains all prefixes available
+   * within this element context.
+   *
+   * @return Vector containing the prefixes available within this
+   * element context 
+   */
+  public List getDeclaredPrefixes()
+  {
+    return m_declaredPrefixes;
+  }
+
+  /**
+   * From the SAX2 helper class, set the namespace table for
+   * this element.  Take care to call resolveInheritedNamespaceDecls.
+   * after all namespace declarations have been added.
+   *
+   * @param nsSupport non-null reference to NamespaceSupport from 
+   * the ContentHandler.
+   *
+   * @throws TransformerException
+   */
+  public void setPrefixes(NamespaceSupport nsSupport) throws TransformerException
+  {
+    setPrefixes(nsSupport, false);
+  }
+
+  /**
+   * Copy the namespace declarations from the NamespaceSupport object.  
+   * Take care to call resolveInheritedNamespaceDecls.
+   * after all namespace declarations have been added.
+   *
+   * @param nsSupport non-null reference to NamespaceSupport from 
+   * the ContentHandler.
+   * @param excludeXSLDecl true if XSLT namespaces should be ignored.
+   *
+   * @throws TransformerException
+   */
+  public void setPrefixes(NamespaceSupport nsSupport, boolean excludeXSLDecl)
+          throws TransformerException
+  {
+
+    Enumeration decls = nsSupport.getDeclaredPrefixes();
+
+    while (decls.hasMoreElements())
+    {
+      String prefix = (String) decls.nextElement();
+
+      if (null == m_declaredPrefixes)
+        m_declaredPrefixes = new ArrayList();
+
+      String uri = nsSupport.getURI(prefix);
+
+      if (excludeXSLDecl && uri.equals(Constants.S_XSLNAMESPACEURL))
+        continue;
+
+      // System.out.println("setPrefixes - "+prefix+", "+uri);
+      XMLNSDecl decl = new XMLNSDecl(prefix, uri, false);
+
+      m_declaredPrefixes.add(decl);
+    }
+  }
+
+  /**
+   * Fullfill the PrefixResolver interface.  Calling this for this class 
+   * will throw an error.
+   *
+   * @param prefix The prefix to look up, which may be an empty string ("") 
+   *               for the default Namespace.
+   * @param context The node context from which to look up the URI.
+   *
+   * @return null if the error listener does not choose to throw an exception.
+   */
+  public String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context)
+  {
+    this.error(XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, null);
+
+    return null;
+  }
+
+  /**
+   * Given a namespace, get the corrisponding prefix.
+   * 9/15/00: This had been iteratively examining the m_declaredPrefixes
+   * field for this node and its parents. That makes life difficult for
+   * the compilation experiment, which doesn't have a static vector of
+   * local declarations. Replaced a recursive solution, which permits
+   * easier subclassing/overriding.
+   *
+   * @param prefix non-null reference to prefix string, which should map 
+   *               to a namespace URL.
+   *
+   * @return The namespace URL that the prefix maps to, or null if no 
+   *         mapping can be found.
+   */
+  public String getNamespaceForPrefix(String prefix)
+  {
+//    if (null != prefix && prefix.equals("xmlns"))
+//    {
+//      return Constants.S_XMLNAMESPACEURI;
+//    }
+
+    List nsDecls = m_declaredPrefixes;
+
+    if (null != nsDecls)
+    {
+      int n = nsDecls.size();
+      if(prefix.equals(Constants.ATTRVAL_DEFAULT_PREFIX))
+      {
+        prefix = "";
+      }
+
+      for (int i = 0; i < n; i++)
+      {
+        XMLNSDecl decl = (XMLNSDecl) nsDecls.get(i);
+
+        if (prefix.equals(decl.getPrefix()))
+          return decl.getURI();
+      }
+    }
+
+    // Not found; ask our ancestors
+    if (null != m_parentNode)
+      return m_parentNode.getNamespaceForPrefix(prefix);
+
+    // JJK: No ancestors; try implicit
+    // %REVIEW% Are there literals somewhere that we should use instead?
+    // %REVIEW% Is this really the best place to patch?
+    if("xml".equals(prefix))
+      return "http://www.w3.org/XML/1998/namespace";
+
+    // No parent, so no definition
+    return null;
+  }
+
+  /**
+   * The table of {@link XMLNSDecl}s for this element
+   * and all parent elements, screened for excluded prefixes.
+   * @serial
+   */
+  private List m_prefixTable;
+
+  /**
+   * Return a table that contains all prefixes available
+   * within this element context.
+   *
+   * @return reference to vector of {@link XMLNSDecl}s, which may be null.
+   */
+  List getPrefixTable()
+  {
+    return m_prefixTable;
+  }
+  
+  void setPrefixTable(List list) {
+      m_prefixTable = list;
+  }
+  
+  /**
+   * Get whether or not the passed URL is contained flagged by
+   * the "extension-element-prefixes" property.  This method is overridden 
+   * by {@link ElemLiteralResult#containsExcludeResultPrefix}.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param prefix non-null reference to prefix that might be excluded.
+   *
+   * @return true if the prefix should normally be excluded.
+   */
+  public boolean containsExcludeResultPrefix(String prefix, String uri)
+  {
+    ElemTemplateElement parent = this.getParentElem();
+    if(null != parent)
+      return parent.containsExcludeResultPrefix(prefix, uri);
+      
+    return false;
+  }
+
+  /**
+   * Tell if the result namespace decl should be excluded.  Should be called before
+   * namespace aliasing (I think).
+   *
+   * @param prefix non-null reference to prefix.
+   * @param uri reference to namespace that prefix maps to, which is protected 
+   *            for null, but should really never be passed as null.
+   *
+   * @return true if the given namespace should be excluded.
+   *
+   * @throws TransformerException
+   */
+  private boolean excludeResultNSDecl(String prefix, String uri)
+          throws TransformerException
+  {
+
+    if (uri != null)
+    {
+      if (uri.equals(Constants.S_XSLNAMESPACEURL)
+              || getStylesheet().containsExtensionElementURI(uri))
+        return true;
+
+      if (containsExcludeResultPrefix(prefix, uri))
+        return true;
+    }
+
+    return false;
+  }
+  
+  /**
+   * Combine the parent's namespaces with this namespace
+   * for fast processing, taking care to reference the
+   * parent's namespace if this namespace adds nothing new.
+   * (Recursive method, walking the elements depth-first,
+   * processing parents before children).
+   * Note that this method builds m_prefixTable with aliased 
+   * namespaces, *not* the original namespaces.
+   *
+   * @throws TransformerException
+   */
+  public void resolvePrefixTables() throws TransformerException
+  {
+    // Always start with a fresh prefix table!
+    setPrefixTable(null);
+
+    // If we have declared declarations, then we look for 
+    // a parent that has namespace decls, and add them 
+    // to this element's decls.  Otherwise we just point 
+    // to the parent that has decls.
+    if (null != this.m_declaredPrefixes)
+    {
+      StylesheetRoot stylesheet = this.getStylesheetRoot();
+      
+      // Add this element's declared prefixes to the 
+      // prefix table.
+      int n = m_declaredPrefixes.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        XMLNSDecl decl = (XMLNSDecl) m_declaredPrefixes.get(i);
+        String prefix = decl.getPrefix();
+        String uri = decl.getURI();
+        if(null == uri)
+          uri = "";
+        boolean shouldExclude = excludeResultNSDecl(prefix, uri);
+
+        // Create a new prefix table if one has not already been created.
+        if (null == m_prefixTable)
+            setPrefixTable(new ArrayList());
+
+        NamespaceAlias nsAlias = stylesheet.getNamespaceAliasComposed(uri);
+        if(null != nsAlias)
+        {
+          // Should I leave the non-aliased element in the table as 
+          // an excluded element?
+          
+          // The exclusion should apply to the non-aliased prefix, so 
+          // we don't calculate it here.  -sb
+          // Use stylesheet prefix, as per xsl WG
+          decl = new XMLNSDecl(nsAlias.getStylesheetPrefix(), 
+                              nsAlias.getResultNamespace(), shouldExclude);
+        }
+        else
+          decl = new XMLNSDecl(prefix, uri, shouldExclude);
+
+        m_prefixTable.add(decl);
+        
+      }
+    }
+
+    ElemTemplateElement parent = this.getParentNodeElem();
+
+    if (null != parent)
+    {
+
+      // The prefix table of the parent should never be null!
+      List prefixes = parent.m_prefixTable;
+
+      if (null == m_prefixTable && !needToCheckExclude())
+      {
+
+        // Nothing to combine, so just use parent's table!
+        setPrefixTable(parent.m_prefixTable);
+      }
+      else
+      {
+
+        // Add the prefixes from the parent's prefix table.
+        int n = prefixes.size();
+        
+        for (int i = 0; i < n; i++)
+        {
+          XMLNSDecl decl = (XMLNSDecl) prefixes.get(i);
+          boolean shouldExclude = excludeResultNSDecl(decl.getPrefix(),
+                                                      decl.getURI());
+
+          if (shouldExclude != decl.getIsExcluded())
+          {
+            decl = new XMLNSDecl(decl.getPrefix(), decl.getURI(),
+                                 shouldExclude);
+          }
+          
+          //m_prefixTable.addElement(decl);
+          addOrReplaceDecls(decl);
+        }
+      }
+    }
+    else if (null == m_prefixTable)
+    {
+
+      // Must be stylesheet element without any result prefixes!
+      setPrefixTable(new ArrayList());
+    }
+  }
+  
+  /**
+   * Add or replace this namespace declaration in list
+   * of namespaces in scope for this element.
+   *
+   * @param newDecl namespace declaration to add to list
+   */
+  void addOrReplaceDecls(XMLNSDecl newDecl)
+  {
+      int n = m_prefixTable.size();
+
+        for (int i = n - 1; i >= 0; i--)
+        {
+          XMLNSDecl decl = (XMLNSDecl) m_prefixTable.get(i);
+
+          if (decl.getPrefix().equals(newDecl.getPrefix()))
+          {
+            return;
+          }
+        }
+      m_prefixTable.add(newDecl);    
+    
+  }
+  
+  /**
+   * Return whether we need to check namespace prefixes 
+   * against and exclude result prefixes list.
+   */
+  boolean needToCheckExclude()
+  {
+    return false;    
+  } 
+
+  /**
+   * Send startPrefixMapping events to the result tree handler
+   * for all declared prefix mappings in the stylesheet.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  void executeNSDecls(TransformerImpl transformer) throws TransformerException
+  {
+       executeNSDecls(transformer, null);
+  }
+
+  /**
+   * Send startPrefixMapping events to the result tree handler
+   * for all declared prefix mappings in the stylesheet.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param ignorePrefix string prefix to not startPrefixMapping
+   *
+   * @throws TransformerException
+   */
+  void executeNSDecls(TransformerImpl transformer, String ignorePrefix) throws TransformerException
+  {  
+    try
+    {
+      if (null != m_prefixTable)
+      {
+        SerializationHandler rhandler = transformer.getResultTreeHandler();
+        int n = m_prefixTable.size();
+
+        for (int i = n - 1; i >= 0; i--)
+        {
+          XMLNSDecl decl = (XMLNSDecl) m_prefixTable.get(i);
+
+          if (!decl.getIsExcluded() && !(null != ignorePrefix && decl.getPrefix().equals(ignorePrefix)))
+          {
+            rhandler.startPrefixMapping(decl.getPrefix(), decl.getURI(), true);
+          }
+        }
+      }
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+
+  /**
+   * Send endPrefixMapping events to the result tree handler
+   * for all declared prefix mappings in the stylesheet.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  void unexecuteNSDecls(TransformerImpl transformer) throws TransformerException
+  {
+       unexecuteNSDecls(transformer, null);
+  }
+
+  /**
+   * Send endPrefixMapping events to the result tree handler
+   * for all declared prefix mappings in the stylesheet.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param ignorePrefix string prefix to not endPrefixMapping
+   * 
+   * @throws TransformerException
+   */
+  void unexecuteNSDecls(TransformerImpl transformer, String ignorePrefix) throws TransformerException
+  {
+ 
+    try
+    {
+      if (null != m_prefixTable)
+      {
+        SerializationHandler rhandler = transformer.getResultTreeHandler();
+        int n = m_prefixTable.size();
+
+        for (int i = 0; i < n; i++)
+        {
+          XMLNSDecl decl = (XMLNSDecl) m_prefixTable.get(i);
+
+          if (!decl.getIsExcluded() && !(null != ignorePrefix && decl.getPrefix().equals(ignorePrefix)))
+          {
+            rhandler.endPrefixMapping(decl.getPrefix());
+          }
+        }
+      }
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+  
+  /** The *relative* document order number of this element.
+   *  @serial */
+  protected int m_docOrderNumber = -1;
+  
+  /**
+   * Set the UID (document order index).
+   *
+   * @param i Index of this child.
+   */
+  public void setUid(int i)
+  {
+    m_docOrderNumber = i;
+  }
+
+  /**
+   * Get the UID (document order index).
+   *
+   * @return Index of this child
+   */
+  public int getUid()
+  {
+    return m_docOrderNumber;
+  }
+
+
+  /**
+   * Parent node.
+   * @serial
+   */
+  protected ElemTemplateElement m_parentNode;
+
+  /**
+   * Get the parent as a Node.
+   *
+   * @return This node's parent node
+   */
+  public Node getParentNode()
+  {
+    return m_parentNode;
+  }
+
+  /**
+   * Get the parent as an ElemTemplateElement.
+   *
+   * @return This node's parent as an ElemTemplateElement
+   */
+  public ElemTemplateElement getParentElem()
+  {
+    return m_parentNode;
+  }
+
+  /**
+   * Set the parent as an ElemTemplateElement.
+   *
+   * @param p This node's parent as an ElemTemplateElement
+   */
+  public void setParentElem(ElemTemplateElement p)
+  {
+    m_parentNode = p;
+  }
+
+  /**
+   * Next sibling.
+   * @serial
+   */
+  ElemTemplateElement m_nextSibling;
+
+  /**
+   * Get the next sibling (as a Node) or return null.
+   *
+   * @return this node's next sibling or null
+   */
+  public Node getNextSibling()
+  {
+    return m_nextSibling;
+  }
+
+  /**
+   * Get the previous sibling (as a Node) or return null.
+   * Note that this may be expensive if the parent has many kids;
+   * we accept that price in exchange for avoiding the prev pointer
+   * TODO: If we were sure parents and sibs are always ElemTemplateElements,
+   * we could hit the fields directly rather than thru accessors.
+   *
+   * @return This node's previous sibling or null
+   */
+  public Node getPreviousSibling()
+  {
+
+    Node walker = getParentNode(), prev = null;
+
+    if (walker != null)
+      for (walker = walker.getFirstChild(); walker != null;
+              prev = walker, walker = walker.getNextSibling())
+      {
+        if (walker == this)
+          return prev;
+      }
+
+    return null;
+  }
+
+  /**
+   * Get the previous sibling (as a Node) or return null.
+   * Note that this may be expensive if the parent has many kids;
+   * we accept that price in exchange for avoiding the prev pointer
+   * TODO: If we were sure parents and sibs are always ElemTemplateElements,
+   * we could hit the fields directly rather than thru accessors.
+   *
+   * @return This node's previous sibling or null
+   */
+  public ElemTemplateElement getPreviousSiblingElem()
+  {
+
+    ElemTemplateElement walker = getParentNodeElem();
+    ElemTemplateElement prev = null;
+
+    if (walker != null)
+      for (walker = walker.getFirstChildElem(); walker != null;
+              prev = walker, walker = walker.getNextSiblingElem())
+      {
+        if (walker == this)
+          return prev;
+      }
+
+    return null;
+  }
+
+
+  /**
+   * Get the next sibling (as a ElemTemplateElement) or return null.
+   *
+   * @return This node's next sibling (as a ElemTemplateElement) or null 
+   */
+  public ElemTemplateElement getNextSiblingElem()
+  {
+    return m_nextSibling;
+  }
+  
+  /**
+   * Get the parent element.
+   *
+   * @return This node's next parent (as a ElemTemplateElement) or null 
+   */
+  public ElemTemplateElement getParentNodeElem()
+  {
+    return m_parentNode;
+  }
+
+
+  /**
+   * First child.
+   * @serial
+   */
+  ElemTemplateElement m_firstChild;
+
+  /**
+   * Get the first child as a Node.
+   *
+   * @return This node's first child or null
+   */
+  public Node getFirstChild()
+  {
+    return m_firstChild;
+  }
+
+  /**
+   * Get the first child as a ElemTemplateElement.
+   *
+   * @return This node's first child (as a ElemTemplateElement) or null
+   */
+  public ElemTemplateElement getFirstChildElem()
+  {
+    return m_firstChild;
+  }
+
+  /**
+   * Get the last child.
+   *
+   * @return This node's last child
+   */
+  public Node getLastChild()
+  {
+
+    ElemTemplateElement lastChild = null;
+
+    for (ElemTemplateElement node = m_firstChild; node != null;
+            node = node.m_nextSibling)
+    {
+      lastChild = node;
+    }
+
+    return lastChild;
+  }
+
+  /**
+   * Get the last child.
+   *
+   * @return This node's last child
+   */
+  public ElemTemplateElement getLastChildElem()
+  {
+
+    ElemTemplateElement lastChild = null;
+
+    for (ElemTemplateElement node = m_firstChild; node != null;
+            node = node.m_nextSibling)
+    {
+      lastChild = node;
+    }
+
+    return lastChild;
+  }
+
+
+  /** DOM backpointer that this element originated from.          */
+  transient private org.w3c.dom.Node m_DOMBackPointer;
+
+  /**
+   * If this stylesheet was created from a DOM, get the
+   * DOM backpointer that this element originated from.
+   * For tooling use.
+   *
+   * @return DOM backpointer that this element originated from or null.
+   */
+  public org.w3c.dom.Node getDOMBackPointer()
+  {
+    return m_DOMBackPointer;
+  }
+
+  /**
+   * If this stylesheet was created from a DOM, set the
+   * DOM backpointer that this element originated from.
+   * For tooling use.
+   *
+   * @param n DOM backpointer that this element originated from.
+   */
+  public void setDOMBackPointer(org.w3c.dom.Node n)
+  {
+    m_DOMBackPointer = n;
+  }
+
+  /**
+   * Compares this object with the specified object for precedence order.
+   * The order is determined by the getImportCountComposed() of the containing
+   * composed stylesheet and the getUid() of this element.
+   * Returns a negative integer, zero, or a positive integer as this
+   * object is less than, equal to, or greater than the specified object.
+   * 
+   * @param o The object to be compared to this object
+   * @return  a negative integer, zero, or a positive integer as this object is
+   *          less than, equal to, or greater than the specified object.
+   * @throws ClassCastException if the specified object's
+   *         type prevents it from being compared to this Object.
+   */
+  public int compareTo(Object o) throws ClassCastException {
+    
+    ElemTemplateElement ro = (ElemTemplateElement) o;
+    int roPrecedence = ro.getStylesheetComposed().getImportCountComposed();
+    int myPrecedence = this.getStylesheetComposed().getImportCountComposed();
+
+    if (myPrecedence < roPrecedence)
+      return -1;
+    else if (myPrecedence > roPrecedence)
+      return 1;
+    else
+      return this.getUid() - ro.getUid();
+  }
+  
+  /**
+   * Get information about whether or not an element should strip whitespace.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param support The XPath runtime state.
+   * @param targetElement Element to check
+   *
+   * @return true if the whitespace should be stripped.
+   *
+   * @throws TransformerException
+   */
+  public boolean shouldStripWhiteSpace(
+          org.apache.xpath.XPathContext support, 
+          org.w3c.dom.Element targetElement) throws TransformerException
+  {
+    StylesheetRoot sroot = this.getStylesheetRoot();
+    return (null != sroot) ? sroot.shouldStripWhiteSpace(support, targetElement) :false;
+  }
+  
+  /**
+   * Get information about whether or not whitespace can be stripped.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @return true if the whitespace can be stripped.
+   */
+  public boolean canStripWhiteSpace()
+  {
+    StylesheetRoot sroot = this.getStylesheetRoot();
+    return (null != sroot) ? sroot.canStripWhiteSpace() : false;
+  }
+  
+  /**
+   * Tell if this element can accept variable declarations.
+   * @return true if the element can accept and process variable declarations.
+   */
+  public boolean canAcceptVariables()
+  {
+  	return true;
+  }
+  
+  //=============== ExpressionNode methods ================
+  
+  /** 
+   * Set the parent of this node.
+   * @param n Must be a ElemTemplateElement.
+   */
+  public void exprSetParent(ExpressionNode n)
+  {
+  	// This obviously requires that only a ElemTemplateElement can 
+  	// parent a node of this type.
+  	setParentElem((ElemTemplateElement)n);
+  }
+  
+  /**
+   * Get the ExpressionNode parent of this node.
+   */
+  public ExpressionNode exprGetParent()
+  {
+  	return getParentElem();
+  }
+
+  /** 
+   * This method tells the node to add its argument to the node's
+   * list of children. 
+   * @param n Must be a ElemTemplateElement. 
+   */
+  public void exprAddChild(ExpressionNode n, int i)
+  {
+  	appendChild((ElemTemplateElement)n);
+  }
+
+  /** This method returns a child node.  The children are numbered
+     from zero, left to right. */
+  public ExpressionNode exprGetChild(int i)
+  {
+  	return (ExpressionNode)item(i);
+  }
+
+  /** Return the number of children the node has. */
+  public int exprGetNumChildren()
+  {
+  	return getLength();
+  }
+  
+  /**
+   * Accept a visitor and call the appropriate method 
+   * for this class.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   * @return true if the children of the object should be visited.
+   */
+  protected boolean accept(XSLTVisitor visitor)
+  {
+  	return visitor.visitInstruction(this);
+  }
+
+  /**
+   * @see XSLTVisitable#callVisitors(XSLTVisitor)
+   */
+  public void callVisitors(XSLTVisitor visitor)
+  {
+  	if(accept(visitor))
+  	{
+		callChildVisitors(visitor);
+  	}
+  }
+
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)
+  {
+    for (ElemTemplateElement node = m_firstChild;
+      node != null;
+      node = node.m_nextSibling)
+      {
+      node.callVisitors(visitor);
+    }
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor)
+  {
+  	callChildVisitors(visitor, true);
+  }
+
+
+	/**
+	 * @see PrefixResolver#handlesNullPrefixes()
+	 */
+	public boolean handlesNullPrefixes() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemText.java b/src/main/java/org/apache/xalan/templates/ElemText.java
new file mode 100644
index 0000000..7dc22da
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemText.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemText.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xalan.res.XSLTErrorResources;
+
+/**
+ * Implement xsl:template.
+ * This primarily acts as a marker on the element
+ * stack to signal that whitespace should be preserved.
+ * <pre>
+ * <!ELEMENT xsl:text (#PCDATA)>
+ * <!ATTLIST xsl:text
+ *   disable-output-escaping (yes|no) "no"
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemText extends ElemTemplateElement
+{
+    static final long serialVersionUID = 1383140876182316711L;
+
+  /**
+   * Tells if this element should disable escaping.
+   * @serial
+   */
+  private boolean m_disableOutputEscaping = false;
+
+  /**
+   * Set the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @param v Boolean flag indicating whether this element should disable escaping
+   */
+  public void setDisableOutputEscaping(boolean v)
+  {
+    m_disableOutputEscaping = v;
+  }
+
+  /**
+   * Get the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @return Boolean flag indicating whether this element should disable escaping
+   */
+  public boolean getDisableOutputEscaping()
+  {
+    return m_disableOutputEscaping;
+  }
+
+  /**
+   * 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_TEXT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_TEXT_STRING;
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to children list
+   *
+   * @return Child added to children list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    int type = ((ElemTemplateElement) newChild).getXSLToken();
+
+    switch (type)
+    {
+    case Constants.ELEMNAME_TEXTLITERALRESULT :
+      break;
+    default :
+      error(XSLTErrorResources.ER_CANNOT_ADD,
+            new Object[]{ newChild.getNodeName(),
+                          this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    }
+
+    return super.appendChild(newChild);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemTextLiteral.java b/src/main/java/org/apache/xalan/templates/ElemTextLiteral.java
new file mode 100644
index 0000000..1d6f5e1
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemTextLiteral.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemTextLiteral.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement a text literal.
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemTextLiteral extends ElemTemplateElement
+{
+    static final long serialVersionUID = -7872620006767660088L;
+
+  /**
+   * Tell if space should be preserved.
+   * @serial
+   */
+  private boolean m_preserveSpace;
+
+  /**
+   * Set whether or not space should be preserved.
+   *
+   * @param v Boolean flag indicating whether 
+   * or not space should be preserved
+   */
+  public void setPreserveSpace(boolean v)
+  {
+    m_preserveSpace = v;
+  }
+
+  /**
+   * Get whether or not space should be preserved.
+   *
+   * @return Boolean flag indicating whether 
+   * or not space should be preserved 
+   */
+  public boolean getPreserveSpace()
+  {
+    return m_preserveSpace;
+  }
+
+  /**
+   * The character array.
+   * @serial
+   */
+  private char m_ch[];
+  
+  /**
+   * The character array as a string.
+   * @serial
+   */
+  private String m_str;
+
+  /**
+   * Set the characters that will be output to the result tree..
+   *
+   * @param v Array of characters that will be output to the result tree 
+   */
+  public void setChars(char[] v)
+  {
+    m_ch = v;
+  }
+
+  /**
+   * Get the characters that will be output to the result tree..
+   *
+   * @return Array of characters that will be output to the result tree
+   */
+  public char[] getChars()
+  {
+    return m_ch;
+  }
+  
+  /**
+   * Get the value of the node as a string.
+   *
+   * @return null
+   */
+  public synchronized String getNodeValue()
+  {
+
+    if(null == m_str)
+    {
+      m_str = new String(m_ch);
+    }
+
+    return m_str;
+  }
+
+
+  /**
+   * Tells if this element should disable escaping.
+   * @serial
+   */
+  private boolean m_disableOutputEscaping = false;
+
+  /**
+   * Set the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @param v Boolean value for "disable-output-escaping" attribute.
+   */
+  public void setDisableOutputEscaping(boolean v)
+  {
+    m_disableOutputEscaping = v;
+  }
+
+  /**
+   * Get the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @return Boolean value of "disable-output-escaping" attribute.
+   */
+  public boolean getDisableOutputEscaping()
+  {
+    return m_disableOutputEscaping;
+  }
+
+  /**
+   * 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_TEXTLITERALRESULT;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The element's name
+   */
+  public String getNodeName()
+  {
+    return "#Text";
+  }
+
+  /**
+   * Copy the text literal to the result tree.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    try
+    {
+      SerializationHandler rth = transformer.getResultTreeHandler();
+
+        if (m_disableOutputEscaping)
+      {
+        rth.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+      }
+
+      rth.characters(m_ch, 0, m_ch.length);
+
+      if (m_disableOutputEscaping)
+      {
+        rth.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+      }
+    }
+    catch(SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemUnknown.java b/src/main/java/org/apache/xalan/templates/ElemUnknown.java
new file mode 100644
index 0000000..618ba3f
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemUnknown.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemUnknown.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+
+
+/**
+ * Implement an unknown element
+ * @xsl.usage advanced
+ */
+public class ElemUnknown extends ElemLiteralResult
+{
+    static final long serialVersionUID = -4573981712648730168L;
+
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   *@return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_UNDEFINED;
+  }
+  
+  /**
+   * Execute the fallbacks when an extension is not available.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  private void executeFallbacks(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    for (ElemTemplateElement child = m_firstChild; child != null;
+             child = child.m_nextSibling)
+    {
+      if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
+      {
+        try
+        {
+          transformer.pushElemTemplateElement(child);
+          ((ElemFallback) child).executeFallback(transformer);
+        }
+        finally
+        {
+          transformer.popElemTemplateElement();
+        }
+      }
+    }
+
+  }
+  
+  /**
+   * Return true if this extension element has a <xsl:fallback> child element.
+   *
+   * @return true if this extension element has a <xsl:fallback> child element.
+   */
+  private boolean hasFallbackChildren()
+  {
+    for (ElemTemplateElement child = m_firstChild; child != null;
+             child = child.m_nextSibling)
+    {
+      if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
+        return true;
+    }
+    
+    return false;
+  }
+
+
+  /**
+   * Execute an unknown element.
+   * Execute fallback if fallback child exists or do nothing
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer)
+            throws TransformerException
+  {
+
+
+	try {
+
+		if (hasFallbackChildren()) {
+			executeFallbacks(transformer);
+		} else {
+			// do nothing
+		}
+		
+	} catch (TransformerException e) {
+		transformer.getErrorListener().fatalError(e);
+	}
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemUse.java b/src/main/java/org/apache/xalan/templates/ElemUse.java
new file mode 100644
index 0000000..85d3a57
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemUse.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemUse.java 476466 2006-11-18 08:22:31Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+
+/**
+ * Implement xsl:use.
+ * This acts as a superclass for ElemCopy, ElemAttributeSet,
+ * ElemElement, and ElemLiteralResult, on order to implement
+ * shared behavior the use-attribute-sets attribute.
+ * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemUse extends ElemTemplateElement
+{
+    static final long serialVersionUID = 5830057200289299736L;
+
+  /**
+   * The value of the "use-attribute-sets" attribute.
+   * @serial
+   */
+  private QName m_attributeSetsNames[] = null;
+
+  /**
+   * Set the "use-attribute-sets" attribute.
+   * Attribute sets are used by specifying a use-attribute-sets
+   * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
+   * xsl:attribute-set elements. The value of the use-attribute-sets
+   * attribute is a whitespace-separated list of names of attribute
+   * sets. Each name is specified as a QName, which is expanded as
+   * described in [2.4 Qualified Names].
+   *
+   * @param v The value to set for the "use-attribute-sets" attribute. 
+   */
+  public void setUseAttributeSets(Vector v)
+  {
+
+    int n = v.size();
+
+    m_attributeSetsNames = new QName[n];
+
+    for (int i = 0; i < n; i++)
+    {
+      m_attributeSetsNames[i] = (QName) v.elementAt(i);
+    }
+  }
+
+  /**
+   * Set the "use-attribute-sets" attribute.
+   * Attribute sets are used by specifying a use-attribute-sets
+   * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
+   * xsl:attribute-set elements. The value of the use-attribute-sets
+   * attribute is a whitespace-separated list of names of attribute
+   * sets. Each name is specified as a QName, which is expanded as
+   * described in [2.4 Qualified Names].
+   *
+   * @param v The value to set for the "use-attribute-sets" attribute. 
+   */
+  public void setUseAttributeSets(QName[] v)
+  {
+    m_attributeSetsNames = v;
+  }
+
+  /**
+   * Get the "use-attribute-sets" attribute.
+   * Attribute sets are used by specifying a use-attribute-sets
+   * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
+   * xsl:attribute-set elements, or a xsl:use-attribute-sets attribute on
+   * Literal Result Elements.
+   * The value of the use-attribute-sets
+   * attribute is a whitespace-separated list of names of attribute
+   * sets. Each name is specified as a QName, which is expanded as
+   * described in [2.4 Qualified Names].
+   *
+   * @return The value of the "use-attribute-sets" attribute. 
+   */
+  public QName[] getUseAttributeSets()
+  {
+    return m_attributeSetsNames;
+  }
+  
+  /**
+   * Add the attributes from the named attribute sets to the attribute list.
+   * TODO: Error handling for: "It is an error if there are two attribute sets
+   * with the same expanded-name and with equal import precedence and that both
+   * contain the same attribute unless there is a definition of the attribute
+   * set with higher import precedence that also contains the attribute."
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param stylesheet The owning root stylesheet
+   *
+   * @throws TransformerException
+   */
+  public void applyAttrSets(
+          TransformerImpl transformer, StylesheetRoot stylesheet)
+            throws TransformerException
+  {
+    applyAttrSets(transformer, stylesheet, m_attributeSetsNames);
+  }
+
+  /**
+   * Add the attributes from the named attribute sets to the attribute list.
+   * TODO: Error handling for: "It is an error if there are two attribute sets
+   * with the same expanded-name and with equal import precedence and that both
+   * contain the same attribute unless there is a definition of the attribute
+   * set with higher import precedence that also contains the attribute."
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param stylesheet The owning root stylesheet
+   * @param attributeSetsNames List of attribute sets names to apply
+   *
+   * @throws TransformerException
+   */
+  private void applyAttrSets(
+          TransformerImpl transformer, StylesheetRoot stylesheet, QName attributeSetsNames[])
+            throws TransformerException
+  {
+
+    if (null != attributeSetsNames)
+    {
+      int nNames = attributeSetsNames.length;
+
+      for (int i = 0; i < nNames; i++)
+      {
+        QName qname = attributeSetsNames[i];
+        java.util.List attrSets = stylesheet.getAttributeSetComposed(qname);
+
+        if (null != attrSets)
+        {
+          int nSets = attrSets.size();
+
+          // Highest priority attribute set will be at the top,
+          // so process it last.
+          for (int k = nSets-1; k >= 0 ; k--)
+          {
+            ElemAttributeSet attrSet =
+              (ElemAttributeSet) attrSets.get(k);
+
+            attrSet.execute(transformer);
+          }
+        } 
+        else 
+        {
+          throw new TransformerException(
+              XSLMessages.createMessage(XSLTErrorResources.ER_NO_ATTRIB_SET, 
+                  new Object[] {qname}),this); 
+        }
+      }
+    }
+  }
+
+  /**
+   * Copy attributes specified by use-attribute-sets to the result tree.
+   * Specifying a use-attribute-sets attribute is equivalent to adding
+   * xsl:attribute elements for each of the attributes in each of the
+   * named attribute sets to the beginning of the content of the element
+   * with the use-attribute-sets attribute, in the same order in which
+   * the names of the attribute sets are specified in the use-attribute-sets
+   * attribute. It is an error if use of use-attribute-sets attributes
+   * on xsl:attribute-set elements causes an attribute set to directly
+   * or indirectly use itself.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+
+    if (null != m_attributeSetsNames)
+    {
+      applyAttrSets(transformer, getStylesheetRoot(),
+                    m_attributeSetsNames);
+    }
+ 
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemValueOf.java b/src/main/java/org/apache/xalan/templates/ElemValueOf.java
new file mode 100644
index 0000000..a8d38c7
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemValueOf.java
@@ -0,0 +1,289 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemValueOf.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.xml.sax.SAXException;
+
+/**
+ * Implement xsl:value-of.
+ * <pre>
+ * <!ELEMENT xsl:value-of EMPTY>
+ * <!ATTLIST xsl:value-of
+ *   select %expr; #REQUIRED
+ *   disable-output-escaping (yes|no) "no"
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemValueOf extends ElemTemplateElement
+{
+    static final long serialVersionUID = 3490728458007586786L;
+
+  /**
+   * The select expression to be executed.
+   * @serial
+   */
+  private XPath m_selectExpression = null;
+
+  /**
+   * True if the pattern is a simple ".".
+   * @serial
+   */
+  private boolean m_isDot = false;
+
+  /**
+   * Set the "select" attribute.
+   * The required select attribute is an expression; this expression
+   * is evaluated and the resulting object is converted to a
+   * string as if by a call to the string function.
+   *
+   * @param v The value to set for the "select" attribute.
+   */
+  public void setSelect(XPath v)
+  {
+
+    if (null != v)
+    {
+      String s = v.getPatternString();
+
+      m_isDot = (null != s) && s.equals(".");
+    }
+
+    m_selectExpression = v;
+  }
+
+  /**
+   * Get the "select" attribute.
+   * The required select attribute is an expression; this expression
+   * is evaluated and the resulting object is converted to a
+   * string as if by a call to the string function.
+   *
+   * @return The value of the "select" attribute.
+   */
+  public XPath getSelect()
+  {
+    return m_selectExpression;
+  }
+
+  /**
+   * Tells if this element should disable escaping.
+   * @serial
+   */
+  private boolean m_disableOutputEscaping = false;
+
+  /**
+   * Set the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @param v The value to set for the "disable-output-escaping" attribute.
+   */
+  public void setDisableOutputEscaping(boolean v)
+  {
+    m_disableOutputEscaping = v;
+  }
+
+  /**
+   * Get the "disable-output-escaping" attribute.
+   * Normally, the xml output method escapes & and < (and
+   * possibly other characters) when outputting text nodes.
+   * This ensures that the output is well-formed XML. However,
+   * it is sometimes convenient to be able to produce output
+   * that is almost, but not quite well-formed XML; for
+   * example, the output may include ill-formed sections
+   * which are intended to be transformed into well-formed
+   * XML by a subsequent non-XML aware process. For this reason,
+   * XSLT provides a mechanism for disabling output escaping.
+   * An xsl:value-of or xsl:text element may have a
+   * disable-output-escaping attribute; the allowed values
+   * are yes or no; the default is no; if the value is yes,
+   * then a text node generated by instantiating the xsl:value-of
+   * or xsl:text element should be output without any escaping.
+   * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
+   *
+   * @return The value of the "disable-output-escaping" attribute.
+   */
+  public boolean getDisableOutputEscaping()
+  {
+    return m_disableOutputEscaping;
+  }
+
+  /**
+   * 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_VALUEOF;
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   *
+   * NEEDSDOC @param sroot
+   *
+   * @throws TransformerException
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+
+    super.compose(sroot);
+
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+    if (null != m_selectExpression)
+      m_selectExpression.fixupVariables(
+        vnames, sroot.getComposeState().getGlobalsSize());
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The node name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_VALUEOF_STRING;
+  }
+
+  /**
+   * Execute the string expression and copy the text to the
+   * result tree.
+   * The required select attribute is an expression; this expression
+   * is evaluated and the resulting object is converted to a string
+   * as if by a call to the string function. The string specifies
+   * the string-value of the created text node. If the string is
+   * empty, no text node will be created. The created text node will
+   * be merged with any adjacent text nodes.
+   * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    XPathContext xctxt = transformer.getXPathContext();
+    SerializationHandler rth = transformer.getResultTreeHandler();
+
+    try
+    {
+      // Optimize for "."
+        xctxt.pushNamespaceContext(this);
+
+        int current = xctxt.getCurrentNode();
+
+        xctxt.pushCurrentNodeAndExpression(current, current);
+
+        if (m_disableOutputEscaping)
+          rth.processingInstruction(
+            javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+
+        try
+        {
+          Expression expr = m_selectExpression.getExpression();
+
+            expr.executeCharsToContentHandler(xctxt, rth);
+        }
+        finally
+        {
+          if (m_disableOutputEscaping)
+            rth.processingInstruction(
+              javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+
+          xctxt.popNamespaceContext();
+          xctxt.popCurrentNodeAndExpression();
+        }
+    }
+    catch (SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    catch (RuntimeException re) {
+    	TransformerException te = new TransformerException(re);
+    	te.setLocator(this);
+    	throw te;
+    }
+  }
+
+  /**
+   * Add a child to the child list.
+   *
+   * @param newChild Child to add to children list
+   *
+   * @return Child just added to children list
+   *
+   * @throws DOMException
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+  {
+
+    error(XSLTErrorResources.ER_CANNOT_ADD,
+          new Object[]{ newChild.getNodeName(),
+                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
+
+    //" to " + this.m_elemName);
+    return null;
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  		m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemVariable.java b/src/main/java/org/apache/xalan/templates/ElemVariable.java
new file mode 100644
index 0000000..099463a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemVariable.java
@@ -0,0 +1,528 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemVariable.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.objects.XRTreeFragSelectWrapper;
+import org.apache.xpath.objects.XString;
+import org.apache.xalan.res.XSLTErrorResources;
+
+/**
+ * Implement xsl:variable.
+ * <pre>
+ * <!ELEMENT xsl:variable %template;>
+ * <!ATTLIST xsl:variable
+ *   name %qname; #REQUIRED
+ *   select %expr; #IMPLIED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemVariable extends ElemTemplateElement
+{
+    static final long serialVersionUID = 9111131075322790061L;
+
+  /**
+   * Constructor ElemVariable
+   *
+   */
+  public ElemVariable(){}
+
+  /**
+   * This is the index into the stack frame.
+   */
+  protected int m_index;
+  
+  /**
+   * The stack frame size for this variable if it is a global variable 
+   * that declares an RTF, which is equal to the maximum number 
+   * of variables that can be declared in the variable at one time.
+   */
+  int m_frameSize = -1;
+
+  
+  /**
+   * Sets the relative position of this variable within the stack frame (if local)
+   * or the global area (if global).  Note that this should be called only for
+   * global variables since the local position is computed in the compose() method.
+   */
+  public void setIndex(int index)
+  {
+    m_index = index;
+  }
+
+  /**
+   * If this element is not at the top-level, get the relative position of the
+   * variable into the stack frame.  If this variable is at the top-level, get
+   * the relative position within the global area.
+   */
+  public int getIndex()
+  {
+    return m_index;
+  }
+
+  /**
+   * The value of the "select" attribute.
+   * @serial
+   */
+  private XPath m_selectPattern;
+
+  /**
+   * Set the "select" attribute.
+   * If the variable-binding element has a select attribute,
+   * then the value of the attribute must be an expression and
+   * the value of the variable is the object that results from
+   * evaluating the expression. In this case, the content
+   * of the variable must be empty.
+   *
+   * @param v Value to set for the "select" attribute.
+   */
+  public void setSelect(XPath v)
+  {
+    m_selectPattern = v;
+  }
+
+  /**
+   * Get the "select" attribute.
+   * If the variable-binding element has a select attribute,
+   * then the value of the attribute must be an expression and
+   * the value of the variable is the object that results from
+   * evaluating the expression. In this case, the content
+   * of the variable must be empty.
+   *
+   * @return Value of the "select" attribute.
+   */
+  public XPath getSelect()
+  {
+    return m_selectPattern;
+  }
+
+  /**
+   * The value of the "name" attribute.
+   * @serial
+   */
+  protected QName m_qname;
+
+  /**
+   * 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 "name" attribute.
+   */
+  public void setName(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 "name" attribute.
+   */
+  public QName getName()
+  {
+    return m_qname;
+  }
+
+  /**
+   * Tells if this is a top-level variable or param, or not.
+   * @serial
+   */
+  private boolean m_isTopLevel = false;
+
+  /**
+   * Set if this is a top-level variable or param, or not.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param v Boolean indicating whether this is a top-level variable
+   * or param, or not.
+   */
+  public void setIsTopLevel(boolean v)
+  {
+    m_isTopLevel = v;
+  }
+
+  /**
+   * Get if this is a top-level variable or param, or not.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @return Boolean indicating whether this is a top-level variable
+   * or param, or not.
+   */
+  public boolean getIsTopLevel()
+  {
+    return m_isTopLevel;
+  }
+
+  /**
+   * 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_VARIABLE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The node name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_VARIABLE_STRING;
+  }
+
+  /**
+   * Copy constructor.
+   *
+   * @param param An element created from an xsl:variable
+   *
+   * @throws TransformerException
+   */
+  public ElemVariable(ElemVariable param) throws TransformerException
+  {
+
+    m_selectPattern = param.m_selectPattern;
+    m_qname = param.m_qname;
+    m_isTopLevel = param.m_isTopLevel;
+
+    // m_value = param.m_value;
+    // m_varContext = param.m_varContext;
+  }
+
+  /**
+   * Execute a variable declaration and push it onto the variable stack.
+   * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    int sourceNode = transformer.getXPathContext().getCurrentNode();
+  
+    XObject var = getValue(transformer, sourceNode);
+
+    // transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
+    transformer.getXPathContext().getVarStack().setLocalVariable(m_index, var);
+  }
+
+  /**
+   * Get the XObject representation of the variable.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
+   *
+   * @return the XObject representation of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getValue(TransformerImpl transformer, int sourceNode)
+          throws TransformerException
+  {
+
+    XObject var;
+    XPathContext xctxt = transformer.getXPathContext();
+
+    xctxt.pushCurrentNode(sourceNode);
+ 
+    try
+    {
+      if (null != m_selectPattern)
+      {
+        var = m_selectPattern.execute(xctxt, sourceNode, this);
+
+        var.allowDetachToRelease(false);
+      }
+      else if (null == getFirstChildElem())
+      {
+        var = XString.EMPTYSTRING;
+      }
+      else
+      {
+
+        // Use result tree fragment.
+        // Global variables may be deferred (see XUnresolvedVariable) and hence
+        // need to be assigned to a different set of DTMs than local variables
+        // so they aren't popped off the stack on return from a template.
+        int df;
+
+		// Bugzilla 7118: A variable set via an RTF may create local
+		// variables during that computation. To keep them from overwriting
+		// variables at this level, push a new variable stack.
+		////// PROBLEM: This is provoking a variable-used-before-set
+		////// problem in parameters. Needs more study.
+		try
+		{
+			//////////xctxt.getVarStack().link(0);
+			if(m_parentNode instanceof Stylesheet) // Global variable
+				df = transformer.transformToGlobalRTF(this);
+			else
+				df = transformer.transformToRTF(this);
+    	}
+		finally{ 
+			//////////////xctxt.getVarStack().unlink(); 
+			}
+
+        var = new XRTreeFrag(df, xctxt, this);
+      }
+    }
+    finally
+    {      
+      xctxt.popCurrentNode();
+    }
+
+    return var;
+  }
+  
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    // See if we can reduce an RTF to a select with a string expression.
+    if(null == m_selectPattern  
+       && sroot.getOptimizer())
+    {
+      XPath newSelect = rewriteChildToExpression(this);
+      if(null != newSelect)
+        m_selectPattern = newSelect;
+    }
+    
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    
+    // This should be done before addVariableName, so we don't have visibility 
+    // to the variable now being defined.
+    java.util.Vector vnames = cstate.getVariableNames();
+    if(null != m_selectPattern)
+      m_selectPattern.fixupVariables(vnames, cstate.getGlobalsSize());
+      
+    // Only add the variable if this is not a global.  If it is a global, 
+    // it was already added by stylesheet root.
+    if(!(m_parentNode instanceof Stylesheet) && m_qname != null)
+    {
+      m_index = cstate.addVariableName(m_qname) - cstate.getGlobalsSize();
+    }
+    else if (m_parentNode instanceof Stylesheet)
+    {
+    	// If this is a global, then we need to treat it as if it's a xsl:template, 
+    	// and count the number of variables it contains.  So we set the count to 
+    	// zero here.
+		cstate.resetStackFrameSize();
+    }
+    
+    // This has to be done after the addVariableName, so that the variable 
+    // pushed won't be immediately popped again in endCompose.
+    super.compose(sroot);
+  }
+  
+  /**
+   * This after the template's children have been composed.  We have to get 
+   * the count of how many variables have been declared, so we can do a link 
+   * and unlink.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.endCompose(sroot);
+    if(m_parentNode instanceof Stylesheet)
+    {
+    	StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    	m_frameSize = cstate.getFrameSize();
+    	cstate.resetStackFrameSize();
+    }
+  }
+
+  
+  
+//  /**
+//   * This after the template's children have been composed.
+//   */
+//  public void endCompose() throws TransformerException
+//  {
+//    super.endCompose();
+//  }
+
+
+  /**
+   * If the children of a variable is a single xsl:value-of or text literal, 
+   * it is cheaper to evaluate this as an expression, so try and adapt the 
+   * child an an expression.
+   *
+   * @param varElem Should be a ElemParam, ElemVariable, or ElemWithParam.
+   *
+   * @return An XPath if rewrite is possible, else null.
+   *
+   * @throws TransformerException
+   */
+  static XPath rewriteChildToExpression(ElemTemplateElement varElem)
+          throws TransformerException
+  {
+
+    ElemTemplateElement t = varElem.getFirstChildElem();
+
+    // Down the line this can be done with multiple string objects using 
+    // the concat function.
+    if (null != t && null == t.getNextSiblingElem())
+    {
+      int etype = t.getXSLToken();
+
+      if (Constants.ELEMNAME_VALUEOF == etype)
+      {
+        ElemValueOf valueof = (ElemValueOf) t;
+
+        // %TBD% I'm worried about extended attributes here.
+        if (valueof.getDisableOutputEscaping() == false
+                && valueof.getDOMBackPointer() == null)
+        {
+          varElem.m_firstChild = null;
+
+          return new XPath(new XRTreeFragSelectWrapper(valueof.getSelect().getExpression()));
+        }
+      }
+      else if (Constants.ELEMNAME_TEXTLITERALRESULT == etype)
+      {
+        ElemTextLiteral lit = (ElemTextLiteral) t;
+
+        if (lit.getDisableOutputEscaping() == false
+                && lit.getDOMBackPointer() == null)
+        {
+          String str = lit.getNodeValue();
+          XString xstr = new XString(str);
+
+          varElem.m_firstChild = null;
+
+          return new XPath(new XRTreeFragSelectWrapper(xstr));
+        }
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * This function is called during recomposition to
+   * control how this element is composed.
+   * @param root The root stylesheet for this transformation.
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeVariables(this);
+  }
+  
+  /**
+   * Set the parent as an ElemTemplateElement.
+   *
+   * @param p This node's parent as an ElemTemplateElement
+   */
+  public void setParentElem(ElemTemplateElement p)
+  {
+    super.setParentElem(p);
+    p.m_hasVariableDecl = true;
+  }
+  
+  /**
+   * Accept a visitor and call the appropriate method 
+   * for this class.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   * @return true if the children of the object should be visited.
+   */
+  protected boolean accept(XSLTVisitor visitor)
+  {
+  	return visitor.visitVariableOrParamDecl(this);
+  }
+
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(null != m_selectPattern)
+  		m_selectPattern.getExpression().callVisitors(m_selectPattern, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+  
+  /**
+   * Tell if this is a psuedo variable reference, declared by Xalan instead 
+   * of by the user.
+   */
+  public boolean isPsuedoVar()
+  {
+  	java.lang.String ns = m_qname.getNamespaceURI();
+  	if((null != ns) && ns.equals(RedundentExprEliminator.PSUEDOVARNAMESPACE))
+  	{
+  		if(m_qname.getLocalName().startsWith("#"))
+  			return true;
+  	}
+  	return false;
+  }
+  
+  /**
+   * Add a child to the child list. If the select attribute
+   * is present, an error will be raised.
+   *
+   * @param elem New element to append to this element's children list
+   *
+   * @return null if the select attribute was present, otherwise the 
+   * child just added to the child list 
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement elem)
+  {
+    // cannot have content and select
+    if (m_selectPattern != null)
+    {
+      error(XSLTErrorResources.ER_CANT_HAVE_CONTENT_AND_SELECT, 
+          new Object[]{"xsl:" + this.getNodeName()});
+      return null;
+    }
+    return super.appendChild(elem);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemVariablePsuedo.java b/src/main/java/org/apache/xalan/templates/ElemVariablePsuedo.java
new file mode 100644
index 0000000..9200e8c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemVariablePsuedo.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemVariablePsuedo.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.XPath;
+
+public class ElemVariablePsuedo extends ElemVariable
+{
+    static final long serialVersionUID = 692295692732588486L;
+  XUnresolvedVariableSimple m_lazyVar;
+	
+  /**
+   * Set the "select" attribute.
+   * If the variable-binding element has a select attribute,
+   * then the value of the attribute must be an expression and
+   * the value of the variable is the object that results from
+   * evaluating the expression. In this case, the content
+   * of the variable must be empty.
+   *
+   * @param v Value to set for the "select" attribute.
+   */
+  public void setSelect(XPath v)
+  {
+    super.setSelect(v);
+    m_lazyVar = new XUnresolvedVariableSimple(this);
+  }
+  
+  /**
+   * Execute a variable declaration and push it onto the variable stack.
+   * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {
+
+    // if (TransformerImpl.S_DEBUG)
+    //  transformer.getTraceManager().fireTraceEvent(this);
+
+    // transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
+    transformer.getXPathContext().getVarStack().setLocalVariable(m_index, m_lazyVar);
+  }
+
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/ElemWhen.java b/src/main/java/org/apache/xalan/templates/ElemWhen.java
new file mode 100644
index 0000000..b129161
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemWhen.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemWhen.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xpath.XPath;
+
+/**
+ * Implement xsl:when.
+ * <pre>
+ * <!ELEMENT xsl:when %template;>
+ * <!ATTLIST xsl:when
+ *   test %expr; #REQUIRED
+ *   %space-att;
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose">XXX in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemWhen extends ElemTemplateElement
+{
+    static final long serialVersionUID = 5984065730262071360L;
+
+  /**
+   * Each xsl:when element has a single attribute, test,
+   * which specifies an expression.
+   * @serial
+   */
+  private XPath m_test;
+
+  /**
+   * Set the "test" attribute.
+   * Each xsl:when element has a single attribute, test,
+   * which specifies an expression.
+   *
+   * @param v Value to set for the "test" attribute.
+   */
+  public void setTest(XPath v)
+  {
+    m_test = v;
+  }
+
+  /**
+   * Get the "test" attribute.
+   * Each xsl:when element has a single attribute, test,
+   * which specifies an expression.
+   *
+   * @return Value of the "test" attribute.
+   */
+  public XPath getTest()
+  {
+    return m_test;
+  }
+
+  /**
+   * 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_WHEN;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) 
+    throws javax.xml.transform.TransformerException
+  {
+    super.compose(sroot);
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+    if(null != m_test)
+      m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The node name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_WHEN_STRING;
+  }
+
+  /**
+   * Constructor ElemWhen
+   *
+   */
+  public ElemWhen(){}
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs)
+  		m_test.getExpression().callVisitors(m_test, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemWithParam.java b/src/main/java/org/apache/xalan/templates/ElemWithParam.java
new file mode 100644
index 0000000..b59212c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemWithParam.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemWithParam.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Implement xsl:with-param.  xsl:with-param is allowed within
+ * both xsl:call-template and xsl:apply-templates.
+ * <pre>
+ * <!ELEMENT xsl:with-param %template;>
+ * <!ATTLIST xsl:with-param
+ *   name %qname; #REQUIRED
+ *   select %expr; #IMPLIED
+ * >
+ * </pre>
+ * @see <a href="http://www.w3.org/TR/xslt#element-with-param">element-with-param in XSLT Specification</a>
+ * @xsl.usage advanced
+ */
+public class ElemWithParam extends ElemTemplateElement
+{
+    static final long serialVersionUID = -1070355175864326257L;
+  /**
+   * This is the index to the stack frame being called, <emph>not</emph> the 
+   * stack frame that contains this element.
+   */
+  int m_index;
+
+  /**
+   * The "select" attribute, which specifies the value of the
+   * argument, if element content is not specified.
+   * @serial
+   */
+  private XPath m_selectPattern = null;
+
+  /**
+   * Set the "select" attribute.
+   * The "select" attribute specifies the value of the
+   * argument, if element content is not specified.
+   *
+   * @param v Value to set for the "select" attribute. 
+   */
+  public void setSelect(XPath v)
+  {
+    m_selectPattern = v;
+  }
+
+  /**
+   * Get the "select" attribute.
+   * The "select" attribute specifies the value of the
+   * argument, if element content is not specified.
+   *
+   * @return Value of the "select" attribute. 
+   */
+  public XPath getSelect()
+  {
+    return m_selectPattern;
+  }
+
+  /**
+   * The required name attribute specifies the name of the
+   * parameter (the variable the value of whose binding is
+   * to be replaced). The value of the name attribute is a QName,
+   * which is expanded as described in [2.4 Qualified Names].
+   * @serial
+   */
+  private QName m_qname = null;
+  
+  int m_qnameID;
+
+  /**
+   * Set the "name" attribute.
+   * DJD
+   *
+   * @param v Value to set for the "name" attribute.
+   */
+  public void setName(QName v)
+  {
+    m_qname = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * DJD
+   *
+   * @return Value of the "name" attribute.
+   */
+  public QName getName()
+  {
+    return m_qname;
+  }
+
+  /**
+   * 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_WITHPARAM;
+  }
+
+
+  /**
+   * Return the node name.
+   *
+   * @return the node name.
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_WITHPARAM_STRING;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    // See if we can reduce an RTF to a select with a string expression.
+    if(null == m_selectPattern  
+       && sroot.getOptimizer())
+    {
+      XPath newSelect = ElemVariable.rewriteChildToExpression(this);
+      if(null != newSelect)
+        m_selectPattern = newSelect;
+    }
+    m_qnameID = sroot.getComposeState().getQNameID(m_qname);
+    super.compose(sroot);
+    
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+    if(null != m_selectPattern)
+      m_selectPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+      
+    // m_index must be resolved by ElemApplyTemplates and ElemCallTemplate!
+  }
+  
+  /**
+   * Set the parent as an ElemTemplateElement.
+   *
+   * @param p This node's parent as an ElemTemplateElement
+   */
+  public void setParentElem(ElemTemplateElement p)
+  {
+    super.setParentElem(p);
+    p.m_hasVariableDecl = true;
+  }
+  
+  /**
+   * Get the XObject representation of the variable.
+   *
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
+   *
+   * @return the XObject representation of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getValue(TransformerImpl transformer, int sourceNode)
+          throws TransformerException
+  {
+
+    XObject var;
+    XPathContext xctxt = transformer.getXPathContext();
+
+    xctxt.pushCurrentNode(sourceNode);
+
+    try
+    {
+      if (null != m_selectPattern)
+      {
+        var = m_selectPattern.execute(xctxt, sourceNode, this);
+
+        var.allowDetachToRelease(false);
+      }
+      else if (null == getFirstChildElem())
+      {
+        var = XString.EMPTYSTRING;
+      }
+      else
+      {
+
+        // Use result tree fragment
+        int df = transformer.transformToRTF(this);
+
+        var = new XRTreeFrag(df, xctxt, this);
+      }
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+    }
+
+    return var;
+  }
+  
+  /**
+   * Call the children visitors.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if(callAttrs && (null != m_selectPattern))
+  		m_selectPattern.getExpression().callVisitors(m_selectPattern, visitor);
+    super.callChildVisitors(visitor, callAttrs);
+  }
+  
+  /**
+   * Add a child to the child list. If the select attribute
+   * is present, an error will be raised.
+   *
+   * @param elem New element to append to this element's children list
+   *
+   * @return null if the select attribute was present, otherwise the 
+   * child just added to the child list 
+   */
+  public ElemTemplateElement appendChild(ElemTemplateElement elem)
+  {
+    // cannot have content and select
+    if (m_selectPattern != null)
+    {
+      error(XSLTErrorResources.ER_CANT_HAVE_CONTENT_AND_SELECT, 
+          new Object[]{"xsl:" + this.getNodeName()});
+      return null;
+    }
+    return super.appendChild(elem);
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/FuncDocument.java b/src/main/java/org/apache/xalan/templates/FuncDocument.java
new file mode 100644
index 0000000..ba2d38d
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/FuncDocument.java
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncDocument.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.Expression;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.SourceTreeManager;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.Function2Args;
+import org.apache.xpath.functions.WrongNumberArgsException;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Doc() function.
+ *
+ * When the document function has exactly one argument and the argument
+ * is a node-set, then the result is the union, for each node in the
+ * argument node-set, of the result of calling the document function with
+ * the first argument being the string-value of the node, and the second
+ * argument being a node-set with the node as its only member. When the
+ * document function has two arguments and the first argument is a node-set,
+ * then the result is the union, for each node in the argument node-set,
+ * of the result of calling the document function with the first argument
+ * being the string-value of the node, and with the second argument being
+ * the second argument passed to the document function.
+ * @xsl.usage advanced
+ */
+public class FuncDocument extends Function2Args
+{
+    static final long serialVersionUID = 2483304325971281424L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+    
+    int docContext = dtm.getDocumentRoot(context);
+    XObject arg = (XObject) this.getArg0().execute(xctxt);
+
+    String base = "";
+    Expression arg1Expr = this.getArg1();
+
+    if (null != arg1Expr)
+    {
+
+      // The URI reference may be relative. The base URI (see [3.2 Base URI]) 
+      // of the node in the second argument node-set that is first in document 
+      // order is used as the base URI for resolving the 
+      // relative URI into an absolute URI. 
+      XObject arg2 = arg1Expr.execute(xctxt);
+
+      if (XObject.CLASS_NODESET == arg2.getType())
+      {
+        int baseNode = arg2.iter().nextNode();
+
+        if (baseNode == DTM.NULL)
+        {
+            // See http://www.w3.org/1999/11/REC-xslt-19991116-errata#E14.
+            // If the second argument is an empty nodeset, this is an error.
+            // The processor can recover by returning an empty nodeset.
+          	warn(xctxt, XSLTErrorResources.WG_EMPTY_SECOND_ARG, null);
+          	XNodeSet nodes = new XNodeSet(xctxt.getDTMManager());
+   	        return nodes;
+        } else{
+	        DTM baseDTM = xctxt.getDTM(baseNode);
+    	    base = baseDTM.getDocumentBaseURI();
+        }
+        // %REVIEW% This doesn't seem to be a problem with the conformance
+        // suite, but maybe it's just not doing a good test?
+//        int baseDoc = baseDTM.getDocument();
+//
+//        if (baseDoc == DTM.NULL /* || baseDoc instanceof Stylesheet  -->What to do?? */)
+//        {
+//
+//          // base = ((Stylesheet)baseDoc).getBaseIdentifier();
+//          base = xctxt.getNamespaceContext().getBaseIdentifier();
+//        }
+//        else
+//          base = xctxt.getSourceTreeManager().findURIFromDoc(baseDoc);
+      }
+      else
+      {
+        //Can not convert other type to a node-set!;
+        arg2.iter();
+      }
+    }
+    else
+    {
+
+      // If the second argument is omitted, then it defaults to 
+      // the node in the stylesheet that contains the expression that 
+      // includes the call to the document function. Note that a 
+      // zero-length URI reference is a reference to the document 
+      // relative to which the URI reference is being resolved; thus 
+      // document("") refers to the root node of the stylesheet; 
+      // the tree representation of the stylesheet is exactly 
+      // the same as if the XML document containing the stylesheet 
+      // was the initial source document.
+      assertion(null != xctxt.getNamespaceContext(), "Namespace context can not be null!");
+      base = xctxt.getNamespaceContext().getBaseIdentifier();
+    }
+
+    XNodeSet nodes = new XNodeSet(xctxt.getDTMManager());
+    NodeSetDTM mnl = nodes.mutableNodeset();
+    DTMIterator iterator = (XObject.CLASS_NODESET == arg.getType())
+                            ? arg.iter() : null;
+    int pos = DTM.NULL;
+
+    while ((null == iterator) || (DTM.NULL != (pos = iterator.nextNode())))
+    {
+      XMLString ref = (null != iterator)
+                   ? xctxt.getDTM(pos).getStringValue(pos) : arg.xstr();
+      
+      // The first and only argument was a nodeset, the base in that
+      // case is the base URI of the node from the first argument nodeset. 
+      // Remember, when the document function has exactly one argument and
+      // the argument is a node-set, then the result is the union, for each
+      // node in the argument node-set, of the result of calling the document
+      // function with the first argument being the string-value of the node,
+      // and the second argument being a node-set with the node as its only 
+      // member.
+      if (null == arg1Expr && DTM.NULL != pos)
+      {
+        DTM baseDTM = xctxt.getDTM(pos);
+        base = baseDTM.getDocumentBaseURI();
+      }
+
+      if (null == ref)
+        continue;
+
+      if (DTM.NULL == docContext)
+      {
+        error(xctxt, XSLTErrorResources.ER_NO_CONTEXT_OWNERDOC, null);  //"context does not have an owner document!");
+      }
+
+      // From http://www.ics.uci.edu/pub/ietf/uri/rfc1630.txt
+      // A partial form can be distinguished from an absolute form in that the
+      // latter must have a colon and that colon must occur before any slash
+      // characters. Systems not requiring partial forms should not use any
+      // unencoded slashes in their naming schemes.  If they do, absolute URIs
+      // will still work, but confusion may result.
+      int indexOfColon = ref.indexOf(':');
+      int indexOfSlash = ref.indexOf('/');
+
+      if ((indexOfColon != -1) && (indexOfSlash != -1)
+              && (indexOfColon < indexOfSlash))
+      {
+
+        // The url (or filename, for that matter) is absolute.
+        base = null;
+      }
+
+      int newDoc = getDoc(xctxt, context, ref.toString(), base);
+
+      // nodes.mutableNodeset().addNode(newDoc);  
+      if (DTM.NULL != newDoc)
+      {
+        // TODO: mnl.addNodeInDocOrder(newDoc, true, xctxt); ??
+        if (!mnl.contains(newDoc))
+        {
+          mnl.addElement(newDoc);
+        }
+      }
+
+      if (null == iterator || newDoc == DTM.NULL)
+        break;
+    }
+
+    return nodes;
+  }
+
+  /**
+   * Get the document from the given URI and base
+   *
+   * @param xctxt The XPath runtime state.
+   * @param context The current context node
+   * @param uri Relative(?) URI of the document
+   * @param base Base to resolve relative URI from.
+   *
+   * @return The document Node pointing to the document at the given URI
+   * or null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  int getDoc(XPathContext xctxt, int context, String uri, String base)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // System.out.println("base: "+base+", uri: "+uri);
+    SourceTreeManager treeMgr = xctxt.getSourceTreeManager();
+    Source source;
+   
+    int newDoc;
+    try
+    {
+      source = treeMgr.resolveURI(base, uri, xctxt.getSAXLocator());
+      newDoc = treeMgr.getNode(source);
+    }
+    catch (IOException ioe)
+    {
+      throw new TransformerException(ioe.getMessage(), 
+        (SourceLocator)xctxt.getSAXLocator(), ioe);
+    }
+    catch(TransformerException te)
+    {
+      throw new TransformerException(te);
+    }
+
+    if (DTM.NULL != newDoc)
+      return newDoc;
+
+    // If the uri length is zero, get the uri of the stylesheet.
+    if (uri.length() == 0)
+    {
+      // Hmmm... this seems pretty bogus to me... -sb
+      uri = xctxt.getNamespaceContext().getBaseIdentifier();
+      try
+      {
+        source = treeMgr.resolveURI(base, uri, xctxt.getSAXLocator());
+      }
+      catch (IOException ioe)
+      {
+        throw new TransformerException(ioe.getMessage(), 
+          (SourceLocator)xctxt.getSAXLocator(), ioe);
+      }
+    }
+
+    String diagnosticsString = null;
+
+    try
+    {
+      if ((null != uri) && (uri.length() > 0))
+      {
+        newDoc = treeMgr.getSourceTree(source, xctxt.getSAXLocator(), xctxt);
+
+        // System.out.println("newDoc: "+((Document)newDoc).getDocumentElement().getNodeName());
+      }
+      else
+        warn(xctxt, XSLTErrorResources.WG_CANNOT_MAKE_URL_FROM,
+             new Object[]{ ((base == null) ? "" : base) + uri });  //"Can not make URL from: "+((base == null) ? "" : base )+uri);
+    }
+    catch (Throwable throwable)
+    {
+
+      // throwable.printStackTrace();
+      newDoc = DTM.NULL;
+
+      // path.warn(XSLTErrorResources.WG_ENCODING_NOT_SUPPORTED_USING_JAVA, new Object[]{((base == null) ? "" : base )+uri}); //"Can not load requested doc: "+((base == null) ? "" : base )+uri);
+      while (throwable
+             instanceof org.apache.xml.utils.WrappedRuntimeException)
+      {
+        throwable =
+          ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
+      }
+
+      if ((throwable instanceof NullPointerException)
+              || (throwable instanceof ClassCastException))
+      {
+        throw new org.apache.xml.utils.WrappedRuntimeException(
+          (Exception) throwable);
+      }
+
+      StringWriter sw = new StringWriter();
+      PrintWriter diagnosticsWriter = new PrintWriter(sw);
+
+      if (throwable instanceof TransformerException)
+      {
+        TransformerException spe = (TransformerException) throwable;
+
+        {
+          Throwable e = spe;
+
+          while (null != e)
+          {
+            if (null != e.getMessage())
+            {
+              diagnosticsWriter.println(" (" + e.getClass().getName() + "): "
+                                        + e.getMessage());
+            }
+
+            if (e instanceof TransformerException)
+            {
+              TransformerException spe2 = (TransformerException) e;
+
+              SourceLocator locator = spe2.getLocator();
+              if ((null != locator) && (null != locator.getSystemId()))
+                diagnosticsWriter.println("   ID: " + locator.getSystemId()
+                                          + " Line #" + locator.getLineNumber()
+                                          + " Column #"
+                                          + locator.getColumnNumber());
+
+              e = spe2.getException();
+
+              if (e instanceof org.apache.xml.utils.WrappedRuntimeException)
+                e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
+            }
+            else
+              e = null;
+          }
+        }
+      }
+      else
+      {
+        diagnosticsWriter.println(" (" + throwable.getClass().getName()
+                                  + "): " + throwable.getMessage());
+      }
+
+      diagnosticsString = throwable.getMessage(); //sw.toString();
+    }
+
+    if (DTM.NULL == newDoc)
+    {
+
+      // System.out.println("what?: "+base+", uri: "+uri);
+      if (null != diagnosticsString)
+      {
+        warn(xctxt, XSLTErrorResources.WG_CANNOT_LOAD_REQUESTED_DOC,
+             new Object[]{ diagnosticsString });  //"Can not load requested doc: "+((base == null) ? "" : base )+uri);
+      }
+      else
+        warn(xctxt, XSLTErrorResources.WG_CANNOT_LOAD_REQUESTED_DOC,
+             new Object[]{
+               uri == null
+               ? ((base == null) ? "" : base) + uri : uri.toString() });  //"Can not load requested doc: "+((base == null) ? "" : base )+uri);
+    }
+    else
+    {
+      // %REVIEW%
+      // TBD: What to do about XLocator?
+      // xctxt.getSourceTreeManager().associateXLocatorToNode(newDoc, url, null);
+    }
+
+    return newDoc;
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param xctxt The XPath runtime state.
+   * @param msg The error message key
+   * @param args Arguments to be used in the error message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void error(XPathContext xctxt, String msg, Object args[])
+          throws javax.xml.transform.TransformerException
+  {
+
+    String formattedMsg = XSLMessages.createMessage(msg, args);
+    ErrorListener errHandler = xctxt.getErrorListener();
+    TransformerException spe = new TransformerException(formattedMsg,
+                              (SourceLocator)xctxt.getSAXLocator());
+
+    if (null != errHandler)
+      errHandler.error(spe);
+    else
+      System.out.println(formattedMsg);
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param xctxt The XPath runtime state.
+   * @param msg Warning message key
+   * @param args Arguments to be used in the warning message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void warn(XPathContext xctxt, String msg, Object args[])
+          throws javax.xml.transform.TransformerException
+  {
+
+    String formattedMsg = XSLMessages.createWarning(msg, args);
+    ErrorListener errHandler = xctxt.getErrorListener();
+    TransformerException spe = new TransformerException(formattedMsg,
+                              (SourceLocator)xctxt.getSAXLocator());
+
+    if (null != errHandler)
+      errHandler.warning(spe);
+    else
+      System.out.println(formattedMsg);
+  }
+
+ /**
+   * Overide the superclass method to allow one or two arguments.
+   *
+   *
+   * @param argNum Number of arguments passed in to this function
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if ((argNum < 1) || (argNum > 2))
+      reportWrongNumberArgs();
+  }
+  
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createMessage(XSLTErrorResources.ER_ONE_OR_TWO, null)); //"1 or 2");
+  }
+  
+  /**
+   * Tell if the expression is a nodeset expression.
+   * @return true if the expression can be represented as a nodeset.
+   */
+  public boolean isNodesetExpr()
+  {
+    return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/FuncFormatNumb.java b/src/main/java/org/apache/xalan/templates/FuncFormatNumb.java
new file mode 100644
index 0000000..bf1a877
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/FuncFormatNumb.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncFormatNumb.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.Function3Args;
+import org.apache.xpath.functions.WrongNumberArgsException;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the FormatNumber() function.
+ * @xsl.usage advanced
+ */
+public class FuncFormatNumb extends Function3Args
+{
+    static final long serialVersionUID = -8869935264870858636L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    // A bit of an ugly hack to get our context.
+    ElemTemplateElement templElem =
+      (ElemTemplateElement) xctxt.getNamespaceContext();
+    StylesheetRoot ss = templElem.getStylesheetRoot();
+    java.text.DecimalFormat formatter = null;
+    java.text.DecimalFormatSymbols dfs = null;
+    double num = getArg0().execute(xctxt).num();
+    String patternStr = getArg1().execute(xctxt).str();
+
+    // TODO: what should be the behavior here??
+    if (patternStr.indexOf(0x00A4) > 0)
+      ss.error(XSLTErrorResources.ER_CURRENCY_SIGN_ILLEGAL);  // currency sign not allowed
+
+    // this third argument is not a locale name. It is the name of a
+    // decimal-format declared in the stylesheet!(xsl:decimal-format
+    try
+    {
+      Expression arg2Expr = getArg2();
+
+      if (null != arg2Expr)
+      {
+        String dfName = arg2Expr.execute(xctxt).str();
+        QName qname = new QName(dfName, xctxt.getNamespaceContext());
+
+        dfs = ss.getDecimalFormatComposed(qname);
+
+        if (null == dfs)
+        {
+          warn(xctxt, XSLTErrorResources.WG_NO_DECIMALFORMAT_DECLARATION,
+               new Object[]{ dfName });  //"not found!!!
+
+          //formatter = new java.text.DecimalFormat(patternStr);
+        }
+        else
+        {
+
+          //formatter = new java.text.DecimalFormat(patternStr, dfs);
+          formatter = new java.text.DecimalFormat();
+
+          formatter.setDecimalFormatSymbols(dfs);
+          formatter.applyLocalizedPattern(patternStr);
+        }
+      }
+
+      //else
+      if (null == formatter)
+      {
+
+        // look for a possible default decimal-format
+        dfs = ss.getDecimalFormatComposed(new QName(""));
+
+        if (dfs != null)
+        {
+          formatter = new java.text.DecimalFormat();
+
+          formatter.setDecimalFormatSymbols(dfs);
+          formatter.applyLocalizedPattern(patternStr);
+        }
+        else
+        {
+          dfs = new java.text.DecimalFormatSymbols(java.util.Locale.US);
+
+          dfs.setInfinity(Constants.ATTRVAL_INFINITY);
+          dfs.setNaN(Constants.ATTRVAL_NAN);
+
+          formatter = new java.text.DecimalFormat();
+
+          formatter.setDecimalFormatSymbols(dfs);
+
+          if (null != patternStr)
+            formatter.applyLocalizedPattern(patternStr);
+        }
+      }
+
+      return new XString(formatter.format(num));
+    }
+    catch (Exception iae)
+    {
+      templElem.error(XSLTErrorResources.ER_MALFORMED_FORMAT_STRING,
+                      new Object[]{ patternStr });
+
+      return XString.EMPTYSTRING;
+
+      //throw new XSLProcessorException(iae);
+    }
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param xctxt The XPath runtime state.
+   * @param msg Warning message key
+   * @param args Arguments to be used in warning message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void warn(XPathContext xctxt, String msg, Object args[])
+          throws javax.xml.transform.TransformerException
+  {
+
+    String formattedMsg = XSLMessages.createWarning(msg, args);
+    ErrorListener errHandler = xctxt.getErrorListener();
+
+    errHandler.warning(new TransformerException(formattedMsg,
+                                             (SAXSourceLocator)xctxt.getSAXLocator()));
+  }
+
+  /**
+   * Overide the superclass method to allow one or two arguments. 
+   *
+   *
+   * @param argNum Number of arguments passed in
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if ((argNum > 3) || (argNum < 2))
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createMessage(XSLTErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3");
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/FuncKey.java b/src/main/java/org/apache/xalan/templates/FuncKey.java
new file mode 100644
index 0000000..0f98fc2
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/FuncKey.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncKey.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Hashtable;
+
+import org.apache.xalan.transformer.KeyManager;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.UnionPathIterator;
+import org.apache.xpath.functions.Function2Args;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Key() function.
+ * @xsl.usage advanced
+ */
+public class FuncKey extends Function2Args
+{
+    static final long serialVersionUID = 9089293100115347340L;
+
+  /** Dummy value to be used in usedrefs hashtable           */
+  static private Boolean ISTRUE = new Boolean(true);
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    // TransformerImpl transformer = (TransformerImpl)xctxt;
+    TransformerImpl transformer = (TransformerImpl) xctxt.getOwnerObject();
+    XNodeSet nodes = null;
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+    int docContext = dtm.getDocumentRoot(context);
+
+    if (DTM.NULL == docContext)
+    {
+
+      // path.error(context, XPATHErrorResources.ER_CONTEXT_HAS_NO_OWNERDOC); //"context does not have an owner document!");
+    }
+
+    String xkeyname = getArg0().execute(xctxt).str();
+    QName keyname = new QName(xkeyname, xctxt.getNamespaceContext());
+    XObject arg = getArg1().execute(xctxt);
+    boolean argIsNodeSetDTM = (XObject.CLASS_NODESET == arg.getType());
+    KeyManager kmgr = transformer.getKeyManager();
+    
+    // Don't bother with nodeset logic if the thing is only one node.
+    if(argIsNodeSetDTM)
+    {
+    	XNodeSet ns = (XNodeSet)arg;
+    	ns.setShouldCacheNodes(true);
+    	int len = ns.getLength();
+    	if(len <= 1)
+    		argIsNodeSetDTM = false;
+    }
+
+    if (argIsNodeSetDTM)
+    {
+      Hashtable usedrefs = null;
+      DTMIterator ni = arg.iter();
+      int pos;
+      UnionPathIterator upi = new UnionPathIterator();
+      upi.exprSetParent(this);
+
+      while (DTM.NULL != (pos = ni.nextNode()))
+      {
+        dtm = xctxt.getDTM(pos);
+        XMLString ref = dtm.getStringValue(pos);
+
+        if (null == ref)
+          continue;
+
+        if (null == usedrefs)
+          usedrefs = new Hashtable();
+
+        if (usedrefs.get(ref) != null)
+        {
+          continue;  // We already have 'em.
+        }
+        else
+        {
+
+          // ISTRUE being used as a dummy value.
+          usedrefs.put(ref, ISTRUE);
+        }
+
+        XNodeSet nl =
+          kmgr.getNodeSetDTMByKey(xctxt, docContext, keyname, ref,
+                               xctxt.getNamespaceContext());
+                               
+        nl.setRoot(xctxt.getCurrentNode(), xctxt);
+
+//        try
+//        {
+          upi.addIterator(nl);
+//        }
+//        catch(CloneNotSupportedException cnse)
+//        {
+//          // will never happen.
+//        }
+        //mnodeset.addNodesInDocOrder(nl, xctxt); needed??
+      }
+
+      int current = xctxt.getCurrentNode();
+      upi.setRoot(current, xctxt);
+
+      nodes = new XNodeSet(upi);
+    }
+    else
+    {
+      XMLString ref = arg.xstr();
+      nodes = kmgr.getNodeSetDTMByKey(xctxt, docContext, keyname,
+                                                ref,
+                                                xctxt.getNamespaceContext());
+      nodes.setRoot(xctxt.getCurrentNode(), xctxt);
+    }
+
+    return nodes;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/KeyDeclaration.java b/src/main/java/org/apache/xalan/templates/KeyDeclaration.java
new file mode 100644
index 0000000..5caacbe
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/KeyDeclaration.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: KeyDeclaration.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+
+/**
+ * Holds the attribute declarations for the xsl:keys element.
+ * A stylesheet declares a set of keys for each document using
+ * the xsl:key element. When this set of keys contains a member
+ * with node x, name y and value z, we say that node x has a key
+ * with name y and value z.
+ * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+ * @xsl.usage internal
+ */
+public class KeyDeclaration extends ElemTemplateElement
+{
+    static final long serialVersionUID = 7724030248631137918L;
+
+  /**
+   * Constructs a new element representing the xsl:key.  The parameters
+   * are needed to prioritize this key element as part of the recomposing
+   * process.  For this element, they are not automatically created
+   * because the element is never added on to the stylesheet parent.
+   */
+  public KeyDeclaration(Stylesheet parentNode, int docOrderNumber)
+  {
+    m_parentNode = parentNode;
+    setUid(docOrderNumber);
+  }
+
+  /**
+   * The "name" property.
+   * @serial
+   */
+  private QName m_name;
+
+  /**
+   * Set the "name" attribute.
+   * The name attribute specifies the name of the key. The value
+   * of the name attribute is a QName, which is expanded as
+   * described in [2.4 Qualified Names].
+   *
+   * @param name Value to set for the "name" attribute.
+   */
+  public void setName(QName name)
+  {
+    m_name = name;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * The name attribute specifies the name of the key. The value
+   * of the name attribute is a QName, which is expanded as
+   * described in [2.4 Qualified Names].
+   *
+   * @return Value of the "name" attribute.
+   */
+  public QName getName()
+  {
+    return m_name;
+  }
+  
+  /**
+   * Return the node name.
+   *
+   * @return the element's name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_KEY_STRING;
+  }
+
+
+  /**
+   * The "match" attribute.
+   * @serial
+   */
+  private XPath m_matchPattern = null;
+
+  /**
+   * Set the "match" attribute.
+   * The match attribute is a Pattern; an xsl:key element gives
+   * information about the keys of any node that matches the
+   * pattern specified in the match attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
+   *
+   * @param v Value to set for the "match" attribute.
+   */
+  public void setMatch(XPath v)
+  {
+    m_matchPattern = v;
+  }
+
+  /**
+   * Get the "match" attribute.
+   * The match attribute is a Pattern; an xsl:key element gives
+   * information about the keys of any node that matches the
+   * pattern specified in the match attribute.
+   * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
+   *
+   * @return Value of the "match" attribute.
+   */
+  public XPath getMatch()
+  {
+    return m_matchPattern;
+  }
+
+  /**
+   * The "use" attribute.
+   * @serial
+   */
+  private XPath m_use;
+
+  /**
+   * Set the "use" attribute.
+   * The use attribute is an expression specifying the values
+   * of the key; the expression is evaluated once for each node
+   * that matches the pattern.
+   *
+   * @param v Value to set for the "use" attribute.
+   */
+  public void setUse(XPath v)
+  {
+    m_use = v;
+  }
+
+  /**
+   * Get the "use" attribute.
+   * The use attribute is an expression specifying the values
+   * of the key; the expression is evaluated once for each node
+   * that matches the pattern.
+   *
+   * @return Value of the "use" attribute.
+   */
+  public XPath getUse()
+  {
+    return m_use;
+  }
+  
+  /**
+   * Get an int constant identifying the type of element.
+   * @see org.apache.xalan.templates.Constants
+   *
+   * @return The token ID for this element
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_KEY;
+  }
+  
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) 
+    throws javax.xml.transform.TransformerException
+  {
+    super.compose(sroot);
+    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+    if(null != m_matchPattern)
+      m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+    if(null != m_use)
+      m_use.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+  }
+
+  /**
+   * This function is called during recomposition to
+   * control how this element is composed.
+   * @param root The root stylesheet for this transformation.
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeKeys(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/NamespaceAlias.java b/src/main/java/org/apache/xalan/templates/NamespaceAlias.java
new file mode 100644
index 0000000..76aee1a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/NamespaceAlias.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NamespaceAlias.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+/**
+ * Object to hold an xsl:namespace element.
+ * A stylesheet can use the xsl:namespace-alias element to declare
+ * that one namespace URI is an alias for another namespace URI.
+ * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+ */
+public class NamespaceAlias extends ElemTemplateElement
+{
+    static final long serialVersionUID = 456173966637810718L;
+  
+  /**
+   * Constructor NamespaceAlias
+   * 
+   * @param docOrderNumber The document order number
+   *
+   */
+  public NamespaceAlias(int docOrderNumber)
+  {
+    super();
+    m_docOrderNumber = docOrderNumber;
+  }
+
+  /**
+   * The "stylesheet-prefix" attribute.
+   * @serial
+   */
+  private String m_StylesheetPrefix;
+
+  /**
+   * Set the "stylesheet-prefix" attribute.
+   *
+   * @param v non-null prefix value.
+   */
+  public void setStylesheetPrefix(String v)
+  {
+    m_StylesheetPrefix = v;
+  }
+
+  /**
+   * Get the "stylesheet-prefix" attribute.
+   *
+   * @return non-null prefix value.
+   */
+  public String getStylesheetPrefix()
+  {
+    return m_StylesheetPrefix;
+  }
+  
+  /**
+   * The namespace in the stylesheet space.
+   * @serial
+   */
+  private String m_StylesheetNamespace;
+
+  /**
+   * Set the value for the stylesheet namespace.
+   *
+   * @param v non-null prefix value.
+   */
+  public void setStylesheetNamespace(String v)
+  {
+    m_StylesheetNamespace = v;
+  }
+
+  /**
+   * Get the value for the stylesheet namespace.
+   *
+   * @return non-null prefix value.
+   */
+  public String getStylesheetNamespace()
+  {
+    return m_StylesheetNamespace;
+  }
+
+  /**
+   * The "result-prefix" attribute.
+   * @serial
+   */
+  private String m_ResultPrefix;
+
+  /**
+   * Set the "result-prefix" attribute.
+   *
+   * @param v non-null prefix value.
+   */
+  public void setResultPrefix(String v)
+  {
+    m_ResultPrefix = v;
+  }
+
+  /**
+   * Get the "result-prefix" attribute.
+   *
+   * @return non-null prefix value.
+   */
+  public String getResultPrefix()
+  {
+    return m_ResultPrefix;
+  }
+  
+  /**
+   * The result namespace.
+   * @serial
+   */
+  private String m_ResultNamespace;
+
+  /**
+   * Set the result namespace.
+   *
+   * @param v non-null namespace value
+   */
+  public void setResultNamespace(String v)
+  {
+    m_ResultNamespace = v;
+  }
+
+  /**
+   * Get the result namespace value.
+   *
+   * @return non-null namespace value.
+   */
+  public String getResultNamespace()
+  {
+    return m_ResultNamespace;
+  }
+
+  /**
+   * This function is called to recompose() all of the namespace alias properties elements.
+   * 
+   * @param root The owning root stylesheet
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeNamespaceAliases(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/OutputProperties.java b/src/main/java/org/apache/xalan/templates/OutputProperties.java
new file mode 100644
index 0000000..e4bc447
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/OutputProperties.java
@@ -0,0 +1,689 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OutputProperties.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.serializer.OutputPropertyUtils;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.QName;
+
+/**
+ * This class provides information from xsl:output elements. It is mainly
+ * a wrapper for {@link java.util.Properties}, but can not extend that class
+ * because it must be part of the {@link org.apache.xalan.templates.ElemTemplateElement}
+ * heararchy.
+ * <p>An OutputProperties list can contain another OutputProperties list as
+ * its "defaults"; this second property list is searched if the property key
+ * is not found in the original property list.</p>
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#output">xsl:output in XSLT Specification</a>
+ *
+ */
+public class OutputProperties extends ElemTemplateElement
+        implements Cloneable
+{
+    static final long serialVersionUID = -6975274363881785488L;
+  /**
+   * Creates an empty OutputProperties with no default values.
+   */
+  public OutputProperties()
+  {
+    this(org.apache.xml.serializer.Method.XML);
+  }
+
+  /**
+   * Creates an empty OutputProperties with the specified defaults.
+   *
+   * @param   defaults   the defaults.
+   */
+  public OutputProperties(Properties defaults)
+  {
+    m_properties = new Properties(defaults);
+  }
+
+  /**
+   * Creates an empty OutputProperties with the defaults specified by
+   * a property file.  The method argument is used to construct a string of
+   * the form output_[method].properties (for instance, output_html.properties).
+   * The output_xml.properties file is always used as the base.
+   * <p>At the moment, anything other than 'text', 'xml', and 'html', will
+   * use the output_xml.properties file.</p>
+   *
+   * @param   method non-null reference to method name.
+   */
+  public OutputProperties(String method)
+  {
+    m_properties = new Properties(
+        OutputPropertiesFactory.getDefaultMethodProperties(method));
+  }
+
+  /**
+   * Clone this OutputProperties, including a clone of the wrapped Properties
+   * reference.
+   *
+   * @return A new OutputProperties reference, mutation of which should not
+   *         effect this object.
+   */
+  public Object clone()
+  {
+
+    try
+    {
+      OutputProperties cloned = (OutputProperties) super.clone();
+
+      cloned.m_properties = (Properties) cloned.m_properties.clone();
+
+      return cloned;
+    }
+    catch (CloneNotSupportedException e)
+    {
+      return null;
+    }
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setProperty(QName key, String value)
+  {
+    setProperty(key.toNamespacedString(), value);
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setProperty(String key, String value)
+  {
+    if(key.equals(OutputKeys.METHOD))
+    {
+      setMethodDefaults(value);
+    }
+    
+    if (key.startsWith(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL))
+      key = OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL
+         + key.substring(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN);
+    
+    m_properties.put(key, value);
+  }
+
+  /**
+   * Searches for the property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list with the specified key value.
+   */
+  public String getProperty(QName key)
+  {
+    return m_properties.getProperty(key.toNamespacedString());
+  }
+
+  /**
+   * Searches for the property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list with the specified key value.
+   */
+  public String getProperty(String key) 
+  {
+    if (key.startsWith(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL))
+      key = OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL 
+        + key.substring(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN);
+    return m_properties.getProperty(key);
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setBooleanProperty(QName key, boolean value)
+  {
+    m_properties.put(key.toNamespacedString(), value ? "yes" : "no");
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setBooleanProperty(String key, boolean value)
+  {
+    m_properties.put(key, value ? "yes" : "no");
+  }
+
+  /**
+   * Searches for the boolean property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>false</code> if the property is not found, or if the value is other
+   * than "yes".
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a boolean value, or false
+   * if null or not "yes".
+   */
+  public boolean getBooleanProperty(QName key)
+  {
+    return getBooleanProperty(key.toNamespacedString());
+  }
+
+  /**
+   * Searches for the boolean property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>false</code> if the property is not found, or if the value is other
+   * than "yes".
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a boolean value, or false
+   * if null or not "yes".
+   */
+  public boolean getBooleanProperty(String key)
+  {
+    return OutputPropertyUtils.getBooleanProperty(key, m_properties);
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setIntProperty(QName key, int value)
+  {
+    setIntProperty(key.toNamespacedString(), value);
+  }
+
+  /**
+   * Set an output property.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setIntProperty(String key, int value)
+  {
+    m_properties.put(key, Integer.toString(value));
+  }
+
+  /**
+   * Searches for the int property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>false</code> if the property is not found, or if the value is other
+   * than "yes".
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a int value, or false
+   * if null or not a number.
+   */
+  public int getIntProperty(QName key)
+  {
+    return getIntProperty(key.toNamespacedString());
+  }
+
+  /**
+   * Searches for the int property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>false</code> if the property is not found, or if the value is other
+   * than "yes".
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a int value, or false
+   * if null or not a number.
+   */
+  public int getIntProperty(String key)
+  {
+    return OutputPropertyUtils.getIntProperty(key, m_properties);
+  }
+
+
+  /**
+   * Set an output property with a QName value.  The QName will be turned
+   * into a string with the namespace in curly brackets.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setQNameProperty(QName key, QName value)
+  {
+    setQNameProperty(key.toNamespacedString(), value);
+  }
+  
+  /**
+   * Reset the default properties based on the method.
+   *
+   * @param method the method value.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setMethodDefaults(String method)
+  {
+        String defaultMethod = m_properties.getProperty(OutputKeys.METHOD);
+ 
+        if((null == defaultMethod) || !defaultMethod.equals(method)
+         // bjm - add the next condition as a hack
+         // but it is because both output_xml.properties and
+         // output_unknown.properties have the same method=xml
+         // for their default. Otherwise we end up with
+         // a ToUnknownStream wraping a ToXMLStream even
+         // when the users says method="xml"
+         //
+         || defaultMethod.equals("xml")
+         )
+        {
+            Properties savedProps = m_properties;
+            Properties newDefaults = 
+                OutputPropertiesFactory.getDefaultMethodProperties(method);
+            m_properties = new Properties(newDefaults);
+            copyFrom(savedProps, false);
+        }
+  }
+  
+
+  /**
+   * Set an output property with a QName value.  The QName will be turned
+   * into a string with the namespace in curly brackets.
+   *
+   * @param key the key to be placed into the property list.
+   * @param value the value corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setQNameProperty(String key, QName value)
+  {
+    setProperty(key, value.toNamespacedString());
+  }
+
+  /**
+   * Searches for the qname property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a QName value, or false
+   * if null or not "yes".
+   */
+  public QName getQNameProperty(QName key)
+  {
+    return getQNameProperty(key.toNamespacedString());
+  }
+
+  /**
+   * Searches for the qname property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a QName value, or false
+   * if null or not "yes".
+   */
+  public QName getQNameProperty(String key)
+  {
+    return getQNameProperty(key, m_properties);
+  }
+
+  /**
+   * Searches for the qname property with the specified key in the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @param props the list of properties to search in.
+   * @return  the value in this property list as a QName value, or false
+   * if null or not "yes".
+   */
+  public static QName getQNameProperty(String key, Properties props)
+  {
+
+    String s = props.getProperty(key);
+
+    if (null != s)
+      return QName.getQNameFromString(s);
+    else
+      return null;
+  }
+
+  /**
+   * Set an output property with a QName list value.  The QNames will be turned
+   * into strings with the namespace in curly brackets.
+   *
+   * @param key the key to be placed into the property list.
+   * @param v non-null list of QNames corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setQNameProperties(QName key, Vector v)
+  {
+    setQNameProperties(key.toNamespacedString(), v);
+  }
+
+  /**
+   * Set an output property with a QName list value.  The QNames will be turned
+   * into strings with the namespace in curly brackets.
+   *
+   * @param key the key to be placed into the property list.
+   * @param v non-null list of QNames corresponding to <tt>key</tt>.
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setQNameProperties(String key, Vector v)
+  {
+
+    int s = v.size();
+
+    // Just an initial guess at reasonable tuning parameters
+    FastStringBuffer fsb = new FastStringBuffer(9,9);
+
+    for (int i = 0; i < s; i++)
+    {
+      QName qname = (QName) v.elementAt(i);
+
+      fsb.append(qname.toNamespacedString());
+      // Don't append space after last value
+      if (i < s-1) 
+        fsb.append(' ');
+    }
+
+    m_properties.put(key, fsb.toString());
+  }
+
+  /**
+   * Searches for the list of qname properties with the specified key in
+   * the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a vector of QNames, or false
+   * if null or not "yes".
+   */
+  public Vector getQNameProperties(QName key)
+  {
+    return getQNameProperties(key.toNamespacedString());
+  }
+
+  /**
+   * Searches for the list of qname properties with the specified key in
+   * the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @return  the value in this property list as a vector of QNames, or false
+   * if null or not "yes".
+   */
+  public Vector getQNameProperties(String key)
+  {
+    return getQNameProperties(key, m_properties);
+  }
+
+  /**
+   * Searches for the list of qname properties with the specified key in
+   * the property list.
+   * If the key is not found in this property list, the default property list,
+   * and its defaults, recursively, are then checked. The method returns
+   * <code>null</code> if the property is not found.
+   *
+   * @param   key   the property key.
+   * @param props the list of properties to search in.
+   * @return  the value in this property list as a vector of QNames, or false
+   * if null or not "yes".
+   */
+  public static Vector getQNameProperties(String key, Properties props)
+  {
+
+    String s = props.getProperty(key);
+
+    if (null != s)
+    {
+      Vector v = new Vector();
+      int l = s.length();
+      boolean inCurly = false;
+      FastStringBuffer buf = new FastStringBuffer();
+
+      // parse through string, breaking on whitespaces.  I do this instead 
+      // of a tokenizer so I can track whitespace inside of curly brackets, 
+      // which theoretically shouldn't happen if they contain legal URLs.
+      for (int i = 0; i < l; i++)
+      {
+        char c = s.charAt(i);
+
+        if (Character.isWhitespace(c))
+        {
+          if (!inCurly)
+          {
+            if (buf.length() > 0)
+            {
+              QName qname = QName.getQNameFromString(buf.toString());
+              v.addElement(qname);
+              buf.reset();
+            }
+            continue;
+          }
+        }
+        else if ('{' == c)
+          inCurly = true;
+        else if ('}' == c)
+          inCurly = false;
+
+        buf.append(c);
+      }
+
+      if (buf.length() > 0)
+      {
+        QName qname = QName.getQNameFromString(buf.toString());
+        v.addElement(qname);
+        buf.reset();
+      }
+
+      return v;
+    }
+    else
+      return null;
+  }
+
+  /**
+   * This function is called to recompose all of the output format extended elements.
+   *
+   * @param root non-null reference to the stylesheet root object.
+   */
+  public void recompose(StylesheetRoot root)
+    throws TransformerException
+  {
+    root.recomposeOutput(this);
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+
+    super.compose(sroot);
+
+  }
+
+  /**
+   * Get the Properties object that this class wraps.
+   *
+   * @return non-null reference to Properties object.
+   */
+  public Properties getProperties()
+  {
+    return m_properties;
+  }
+  
+  /**
+   * Copy the keys and values from the source to this object.  This will
+   * not copy the default values.  This is meant to be used by going from
+   * a higher precedence object to a lower precedence object, so that if a
+   * key already exists, this method will not reset it.
+   *
+   * @param src non-null reference to the source properties.
+   */
+  public void copyFrom(Properties src)
+  {
+    copyFrom(src, true);
+  }
+
+  /**
+   * Copy the keys and values from the source to this object.  This will
+   * not copy the default values.  This is meant to be used by going from
+   * a higher precedence object to a lower precedence object, so that if a
+   * key already exists, this method will not reset it.
+   *
+   * @param src non-null reference to the source properties.
+   * @param shouldResetDefaults true if the defaults should be reset based on 
+   *                            the method property.
+   */
+  public void copyFrom(Properties src, boolean shouldResetDefaults)
+  {
+
+    Enumeration keys = src.keys();
+
+    while (keys.hasMoreElements())
+    {
+      String key = (String) keys.nextElement();
+    
+      if (!isLegalPropertyKey(key))
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{key})); //"output property not recognized: "
+      
+      Object oldValue = m_properties.get(key);
+      if (null == oldValue)
+      {
+        String val = (String) src.get(key);
+        
+        if(shouldResetDefaults && key.equals(OutputKeys.METHOD))
+        {
+          setMethodDefaults(val);
+        }
+
+        m_properties.put(key, val);
+      }
+      else if (key.equals(OutputKeys.CDATA_SECTION_ELEMENTS))
+      {
+        m_properties.put(key, (String) oldValue + " " + (String) src.get(key));
+      }
+    }
+  }
+
+  /**
+   * Copy the keys and values from the source to this object.  This will
+   * not copy the default values.  This is meant to be used by going from
+   * a higher precedence object to a lower precedence object, so that if a
+   * key already exists, this method will not reset it.
+   *
+   * @param opsrc non-null reference to an OutputProperties.
+   */
+  public void copyFrom(OutputProperties opsrc)
+    throws TransformerException
+  {
+   // Bugzilla 6157: recover from xsl:output statements
+    // checkDuplicates(opsrc);
+    copyFrom(opsrc.getProperties());
+  }
+
+  /**
+   * Report if the key given as an argument is a legal xsl:output key.
+   *
+   * @param key non-null reference to key name.
+   *
+   * @return true if key is legal.
+   */
+  public static boolean isLegalPropertyKey(String key)
+  {
+
+    return (key.equals(OutputKeys.CDATA_SECTION_ELEMENTS)
+            || key.equals(OutputKeys.DOCTYPE_PUBLIC)
+            || key.equals(OutputKeys.DOCTYPE_SYSTEM)
+            || key.equals(OutputKeys.ENCODING)
+            || key.equals(OutputKeys.INDENT)
+            || key.equals(OutputKeys.MEDIA_TYPE)
+            || key.equals(OutputKeys.METHOD)
+            || key.equals(OutputKeys.OMIT_XML_DECLARATION)
+            || key.equals(OutputKeys.STANDALONE)
+            || key.equals(OutputKeys.VERSION)
+            || (key.length() > 0) 
+                  && (key.charAt(0) == '{') 
+                  && (key.lastIndexOf('{') == 0)
+                  && (key.indexOf('}') > 0)
+                  && (key.lastIndexOf('}') == key.indexOf('}')));
+  }
+
+  /** The output properties.
+   *  @serial */
+  private Properties m_properties = null;
+
+    /**
+     * Creates an empty OutputProperties with the defaults specified by
+     * a property file.  The method argument is used to construct a string of
+     * the form output_[method].properties (for instance, output_html.properties).
+     * The output_xml.properties file is always used as the base.
+     * <p>At the moment, anything other than 'text', 'xml', and 'html', will
+     * use the output_xml.properties file.</p>
+     *
+     * @param   method non-null reference to method name.
+     *
+     * @return Properties object that holds the defaults for the given method.
+     * 
+     * @deprecated Use org.apache.xml.serializer.OuputPropertiesFactory.
+     * getDefaultMethodProperties directly.
+     */
+    static public Properties getDefaultMethodProperties(String method)
+    {
+        return org.apache.xml.serializer.OutputPropertiesFactory.getDefaultMethodProperties(method);
+    }
+}
diff --git a/src/main/java/org/apache/xalan/templates/RedundentExprEliminator.java b/src/main/java/org/apache/xalan/templates/RedundentExprEliminator.java
new file mode 100644
index 0000000..a2a0c03
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/RedundentExprEliminator.java
@@ -0,0 +1,1432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: RedundentExprEliminator.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.WrappedRuntimeException;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.axes.AxesWalker;
+import org.apache.xpath.axes.FilterExprIteratorSimple;
+import org.apache.xpath.axes.FilterExprWalker;
+import org.apache.xpath.axes.LocPathIterator;
+import org.apache.xpath.axes.SelfIteratorNoPredicate;
+import org.apache.xpath.axes.WalkerFactory;
+import org.apache.xpath.axes.WalkingIterator;
+import org.apache.xpath.operations.Variable;
+import org.apache.xpath.operations.VariableSafeAbsRef;
+
+/**
+ * This class eleminates redundent XPaths from a given subtree, 
+ * and also collects all absolute paths within the subtree.  First 
+ * it must be called as a visitor to the subtree, and then 
+ * eleminateRedundent must be called.
+ */
+public class RedundentExprEliminator extends XSLTVisitor
+{
+  Vector m_paths;
+  Vector m_absPaths;
+  boolean m_isSameContext;
+  AbsPathChecker m_absPathChecker = new AbsPathChecker();
+  
+  private static int m_uniquePseudoVarID = 1;
+  static final String PSUEDOVARNAMESPACE = Constants.S_VENDORURL+"/xalan/psuedovar";
+ 
+  public static final boolean DEBUG = false;
+  public static final boolean DIAGNOSE_NUM_PATHS_REDUCED = false;
+  public static final boolean DIAGNOSE_MULTISTEPLIST = false;
+
+  /**
+   * So we can reuse it over and over again.
+   */
+  VarNameCollector m_varNameCollector = new VarNameCollector();
+
+  /**
+   * Construct a RedundentExprEliminator.
+   */
+  public RedundentExprEliminator()
+  {
+    m_isSameContext = true;
+    m_absPaths = new Vector();
+    m_paths = null;
+  }
+  
+  
+  /**
+   * Method to be called after the all expressions within an  
+   * node context have been visited.  It eliminates redundent 
+   * expressions by creating a variable in the psuedoVarRecipient 
+   * for each redundent expression, and then rewriting the redundent 
+   * expression to be a variable reference.
+   * 
+   * @param psuedoVarRecipient The recipient of the psuedo vars.  The 
+   * variables will be inserted as first children of the element, before 
+   * any existing variables.
+   */
+  public void eleminateRedundentLocals(ElemTemplateElement psuedoVarRecipient)
+  {
+    eleminateRedundent(psuedoVarRecipient, m_paths);
+  }
+  
+  /**
+   * Method to be called after the all global expressions within a stylesheet 
+   * have been collected.  It eliminates redundent 
+   * expressions by creating a variable in the psuedoVarRecipient 
+   * for each redundent expression, and then rewriting the redundent 
+   * expression to be a variable reference.
+   * 
+   */
+  public void eleminateRedundentGlobals(StylesheetRoot stylesheet)
+  {
+    eleminateRedundent(stylesheet, m_absPaths);
+  }
+
+  
+  /**
+   * Method to be called after the all expressions within an  
+   * node context have been visited.  It eliminates redundent 
+   * expressions by creating a variable in the psuedoVarRecipient 
+   * for each redundent expression, and then rewriting the redundent 
+   * expression to be a variable reference.
+   * 
+   * @param psuedoVarRecipient The owner of the subtree from where the 
+   *                           paths were collected.
+   * @param paths A vector of paths that hold ExpressionOwner objects, 
+   *              which must yield LocationPathIterators.
+   */
+  protected void eleminateRedundent(ElemTemplateElement psuedoVarRecipient, Vector paths)
+  {
+    int n = paths.size();
+    int numPathsEliminated = 0;
+    int numUniquePathsEliminated = 0;
+    for (int i = 0; i < n; i++)
+    {
+      ExpressionOwner owner = (ExpressionOwner) paths.elementAt(i);
+      if (null != owner)
+      {
+        int found = findAndEliminateRedundant(i + 1, i, owner, psuedoVarRecipient, paths);
+        if (found > 0)
+                  numUniquePathsEliminated++;
+        numPathsEliminated += found;
+      }
+    }
+    
+    eleminateSharedPartialPaths(psuedoVarRecipient, paths);
+    
+    if(DIAGNOSE_NUM_PATHS_REDUCED)
+		diagnoseNumPaths(paths, numPathsEliminated, numUniquePathsEliminated);
+  }
+  
+  /**
+   * Eliminate the shared partial paths in the expression list.
+   * 
+   * @param psuedoVarRecipient The recipient of the psuedo vars.
+   * 
+   * @param paths A vector of paths that hold ExpressionOwner objects, 
+   *              which must yield LocationPathIterators.
+   */
+  protected void eleminateSharedPartialPaths(ElemTemplateElement psuedoVarRecipient, Vector paths)
+  {
+  	MultistepExprHolder list = createMultistepExprList(paths);
+  	if(null != list)
+  	{
+  		if(DIAGNOSE_MULTISTEPLIST)
+        	list.diagnose();
+        	
+        boolean isGlobal = (paths == m_absPaths);
+        	
+        // Iterate over the list, starting with the most number of paths, 
+        // trying to find the longest matches first.
+        int longestStepsCount = list.m_stepCount;
+    	for (int i = longestStepsCount-1; i >= 1; i--)
+    	{
+    		MultistepExprHolder next = list;
+        	while(null != next)
+        	{
+        		if(next.m_stepCount < i)
+        			break;
+				list = matchAndEliminatePartialPaths(next, list, isGlobal, i, psuedoVarRecipient);
+				next = next.m_next;
+        	}
+    	}
+  	}
+  }
+
+  /**
+   * For a given path, see if there are any partitial matches in the list, 
+   * and, if there are, replace those partial paths with psuedo variable refs,
+   * and create the psuedo variable decl.
+   * 
+   * @return The head of the list, which may have changed.
+   */
+  protected MultistepExprHolder matchAndEliminatePartialPaths(MultistepExprHolder testee, 
+                                               MultistepExprHolder head,
+                                               boolean isGlobal,
+                                               int lengthToTest,
+                                               ElemTemplateElement varScope)
+  {  	
+  	if(null == testee.m_exprOwner)
+  		return head;
+  		
+    // Start with the longest possible match, and move down.
+    WalkingIterator iter1 = (WalkingIterator) testee.m_exprOwner.getExpression();
+    if(partialIsVariable(testee, lengthToTest))
+    	return head;
+    MultistepExprHolder matchedPaths = null;
+    MultistepExprHolder matchedPathsTail = null;
+    MultistepExprHolder meh = head;
+    while( null != meh)
+    {
+      if ((meh != testee) && (null != meh.m_exprOwner))
+      {
+	      WalkingIterator iter2 = (WalkingIterator) meh.m_exprOwner.getExpression();
+	      if (stepsEqual(iter1, iter2, lengthToTest))
+	      {
+	        if (null == matchedPaths)
+	        {
+	          try
+	          {
+	          	matchedPaths = (MultistepExprHolder)testee.clone();
+	          	testee.m_exprOwner = null; // So it won't be processed again.
+	          }
+	          catch(CloneNotSupportedException cnse){}
+	          matchedPathsTail = matchedPaths;
+	          matchedPathsTail.m_next = null;
+	        }
+	       
+	        try
+	        {
+	          matchedPathsTail.m_next = (MultistepExprHolder)meh.clone();
+	          meh.m_exprOwner = null; // So it won't be processed again.
+	        }
+	        catch(CloneNotSupportedException cnse){}
+	        matchedPathsTail = matchedPathsTail.m_next;
+	        matchedPathsTail.m_next = null;
+	      }
+      }
+      meh = meh.m_next;
+    }
+    	
+	int matchCount = 0;
+	if(null != matchedPaths)
+	{
+		ElemTemplateElement root = isGlobal ? varScope : findCommonAncestor(matchedPaths);
+		WalkingIterator sharedIter = (WalkingIterator)matchedPaths.m_exprOwner.getExpression();
+		WalkingIterator newIter = createIteratorFromSteps(sharedIter, lengthToTest);
+		ElemVariable var = createPseudoVarDecl(root, newIter, isGlobal);
+		if(DIAGNOSE_MULTISTEPLIST)
+			System.err.println("Created var: "+var.getName()+(isGlobal ? "(Global)" : ""));
+		while(null != matchedPaths)
+		{
+			ExpressionOwner owner = matchedPaths.m_exprOwner;
+			WalkingIterator iter = (WalkingIterator)owner.getExpression();
+			
+			if(DIAGNOSE_MULTISTEPLIST)
+				diagnoseLineNumber(iter);
+			
+			LocPathIterator newIter2 = 
+			    changePartToRef(var.getName(), iter, lengthToTest, isGlobal);
+			owner.setExpression(newIter2);
+			
+			matchedPaths = matchedPaths.m_next;
+		}
+	}
+	
+	if(DIAGNOSE_MULTISTEPLIST)
+		diagnoseMultistepList(matchCount, lengthToTest, isGlobal);
+    return head;
+  }
+  
+  /**
+   * Check if results of partial reduction will just be a variable, in 
+   * which case, skip it.
+   */
+  boolean partialIsVariable(MultistepExprHolder testee, int lengthToTest)
+  {
+  	if(1 == lengthToTest)
+  	{
+  		WalkingIterator wi = (WalkingIterator)testee.m_exprOwner.getExpression();
+  		if(wi.getFirstWalker() instanceof FilterExprWalker)
+  			return true;
+  	}
+  	return false;
+  }
+
+  /**
+   * Tell what line number belongs to a given expression.
+   */
+  protected void diagnoseLineNumber(Expression expr)
+  {
+    ElemTemplateElement e = getElemFromExpression(expr);
+    System.err.println("   " + e.getSystemId() + " Line " + e.getLineNumber());
+  }
+      
+  /**
+   * Given a linked list of expressions, find the common ancestor that is 
+   * suitable for holding a psuedo variable for shared access.
+   */
+  protected ElemTemplateElement findCommonAncestor(MultistepExprHolder head)
+  {
+  	// Not sure this algorithm is the best, but will do for the moment.
+  	int numExprs = head.getLength();
+  	// The following could be made cheaper by pre-allocating large arrays, 
+  	// but then we would have to assume a max number of reductions, 
+  	// which I am not inclined to do right now.
+    ElemTemplateElement[] elems = new ElemTemplateElement[numExprs];
+    int[] ancestorCounts = new int[numExprs];
+    
+    // Loop through, getting the parent elements, and counting the 
+    // ancestors.
+  	MultistepExprHolder next = head;
+  	int shortestAncestorCount = 10000;
+  	for(int i = 0; i < numExprs; i++)
+  	{
+  		ElemTemplateElement elem = 
+  			getElemFromExpression(next.m_exprOwner.getExpression());
+  		elems[i] = elem;
+  		int numAncestors = countAncestors(elem);
+  		ancestorCounts[i] = numAncestors;
+  		if(numAncestors < shortestAncestorCount)
+  		{
+  			shortestAncestorCount = numAncestors;
+  		}
+  		next = next.m_next;
+  	}
+  	
+  	// Now loop through and "correct" the elements that have more ancestors.
+  	for(int i = 0; i < numExprs; i++)
+  	{
+  		if(ancestorCounts[i] > shortestAncestorCount)
+  		{
+  			int numStepCorrection = ancestorCounts[i] - shortestAncestorCount;
+  			for(int j = 0; j < numStepCorrection; j++)
+  			{
+  				elems[i] = elems[i].getParentElem();
+  			}
+  		}
+  	}
+  	
+  	// Now everyone has an equal number of ancestors.  Walk up from here 
+  	// equally until all are equal.
+  	ElemTemplateElement first = null;
+  	while(shortestAncestorCount-- >= 0)
+  	{
+  		boolean areEqual = true;
+  		first = elems[0];
+  		for(int i = 1; i < numExprs; i++)
+  		{
+  			if(first != elems[i])
+  			{
+  				areEqual = false;
+  				break;
+  			}
+  		}
+  		// This second check is to make sure we have a common ancestor that is not the same 
+  		// as the expression owner... i.e. the var decl has to go above the expression owner.
+  		if(areEqual && isNotSameAsOwner(head, first) && first.canAcceptVariables())
+  		{
+  			if(DIAGNOSE_MULTISTEPLIST)
+  			{
+  				System.err.print(first.getClass().getName());
+  				System.err.println(" at   " + first.getSystemId() + " Line " + first.getLineNumber());
+  			}
+  			return first;
+  		}
+   			
+  		for(int i = 0; i < numExprs; i++)
+  		{
+  			elems[i] = elems[i].getParentElem();
+  		}
+  	}
+  	
+  	assertion(false, "Could not find common ancestor!!!");
+  	return null;
+  }
+  
+  /**
+   * Find out if the given ElemTemplateElement is not the same as one of 
+   * the ElemTemplateElement owners of the expressions.
+   * 
+   * @param head Head of linked list of expression owners.
+   * @param ete The ElemTemplateElement that is a candidate for a psuedo 
+   * variable parent.
+   * @return true if the given ElemTemplateElement is not the same as one of 
+   * the ElemTemplateElement owners of the expressions.  This is to make sure 
+   * we find an ElemTemplateElement that is in a viable position to hold 
+   * psuedo variables that are visible to the references.
+   */
+  protected boolean isNotSameAsOwner(MultistepExprHolder head, ElemTemplateElement ete)
+  {
+  	MultistepExprHolder next = head;
+  	while(null != next)
+  	{
+  		ElemTemplateElement elemOwner = getElemFromExpression(next.m_exprOwner.getExpression());
+  		if(elemOwner == ete)
+  			return false;
+  		next = next.m_next;
+  	}
+  	return true;
+  }
+  
+  /**
+   * Count the number of ancestors that a ElemTemplateElement has.
+   * 
+   * @param elem An representation of an element in an XSLT stylesheet.
+   * @return The number of ancestors of elem (including the element itself).
+   */
+  protected int countAncestors(ElemTemplateElement elem)
+  {
+  	int count = 0;
+  	while(null != elem)
+  	{
+  		count++;
+  		elem = elem.getParentElem();
+  	}
+  	return count;
+  }
+
+  /**
+   * Print out diagnostics about partial multistep evaluation.
+   */
+  protected void diagnoseMultistepList(
+      int matchCount,
+      int lengthToTest,
+      boolean isGlobal)
+  {
+      if (matchCount > 0)
+        {
+        System.err.print(
+          "Found multistep matches: " + matchCount + ", " + lengthToTest + " length");
+        if (isGlobal)
+              System.err.println(" (global)");
+        else
+              System.err.println();
+      }
+  }
+  
+  /**
+   * Change a given number of steps to a single variable reference.
+   * 
+   * @param uniquePseudoVarName The name of the variable reference.
+   * @param wi The walking iterator that is to be changed.
+   * @param numSteps The number of steps to be changed.
+   * @param isGlobal true if this will be a global reference.
+   */
+  protected LocPathIterator changePartToRef(final QName uniquePseudoVarName, WalkingIterator wi, 
+                                 final int numSteps, final boolean isGlobal)
+  {
+  	Variable var = new Variable();
+  	var.setQName(uniquePseudoVarName);
+  	var.setIsGlobal(isGlobal);
+  	if(isGlobal)
+  	{	ElemTemplateElement elem = getElemFromExpression(wi);
+  		StylesheetRoot root = elem.getStylesheetRoot();
+  		Vector vars = root.getVariablesAndParamsComposed();
+  		var.setIndex(vars.size()-1);
+  	}
+  	
+  	// Walk to the first walker after the one's we are replacing.
+  	AxesWalker walker = wi.getFirstWalker();
+  	for(int i = 0; i < numSteps; i++)
+  	{
+  		assertion(null != walker, "Walker should not be null!");
+  		walker = walker.getNextWalker();
+  	}
+  	
+  	if(null != walker)
+  	{
+  	
+  	  FilterExprWalker few = new FilterExprWalker(wi);
+  	  few.setInnerExpression(var);
+  	  few.exprSetParent(wi);
+  	  few.setNextWalker(walker);
+  	  walker.setPrevWalker(few);
+  	  wi.setFirstWalker(few);
+  	  return wi;
+  	}
+  	else
+  	{
+  	  FilterExprIteratorSimple feis = new FilterExprIteratorSimple(var);
+  	  feis.exprSetParent(wi.exprGetParent());
+  	  return feis;
+  	}
+  }
+  
+  /**
+   * Create a new WalkingIterator from the steps in another WalkingIterator.
+   * 
+   * @param wi The iterator from where the steps will be taken.
+   * @param numSteps The number of steps from the first to copy into the new 
+   *                 iterator.
+   * @return The new iterator.
+   */
+  protected WalkingIterator createIteratorFromSteps(final WalkingIterator wi, int numSteps)
+  {
+  	WalkingIterator newIter = new WalkingIterator(wi.getPrefixResolver());
+  	try
+  	{
+  		AxesWalker walker = (AxesWalker)wi.getFirstWalker().clone();
+  		newIter.setFirstWalker(walker);
+  		walker.setLocPathIterator(newIter);
+  		for(int i = 1; i < numSteps; i++)
+  		{
+  			AxesWalker next = (AxesWalker)walker.getNextWalker().clone();
+  			walker.setNextWalker(next);
+  			next.setLocPathIterator(newIter);
+  			walker = next;
+  		}
+  		walker.setNextWalker(null);
+  	}
+  	catch(CloneNotSupportedException cnse)
+  	{
+  		throw new WrappedRuntimeException(cnse);
+  	}
+  	return newIter;
+  }
+    
+  /**
+   * Compare a given number of steps between two iterators, to see if they are equal.
+   * 
+   * @param iter1 The first iterator to compare.
+   * @param iter2 The second iterator to compare.
+   * @param numSteps The number of steps to compare.
+   * @return true If the given number of steps are equal.
+   * 
+   */
+  protected boolean stepsEqual(WalkingIterator iter1, WalkingIterator iter2, 
+                                         int numSteps)
+  {
+  	AxesWalker aw1 = iter1.getFirstWalker();
+  	AxesWalker aw2 = iter2.getFirstWalker();
+  	
+  	for(int i = 0; (i < numSteps); i++)
+  	{
+  		if((null == aw1) || (null == aw2))
+  		 	return false;
+  		 	
+  		if(!aw1.deepEquals(aw2))
+  			return false;
+  		
+  		aw1 = aw1.getNextWalker();
+  		aw2 = aw2.getNextWalker();
+  	}
+  	
+  	assertion((null != aw1) || (null != aw2), "Total match is incorrect!");
+  	
+  	return true;
+  }
+  
+  /**
+   * For the reduction of location path parts, create a list of all 
+   * the multistep paths with more than one step, sorted by the 
+   * number of steps, with the most steps occuring earlier in the list.
+   * If the list is only one member, don't bother returning it.
+   * 
+   * @param paths Vector of ExpressionOwner objects, which may contain null entries. 
+   *              The ExpressionOwner objects must own LocPathIterator objects.
+   * @return null if no multipart paths are found or the list is only of length 1, 
+   * otherwise the first MultistepExprHolder in a linked list of these objects.
+   */
+  protected MultistepExprHolder createMultistepExprList(Vector paths)
+  {
+  	MultistepExprHolder first = null;
+  	int n = paths.size();
+  	for(int i = 0; i < n; i++)
+  	{
+  		ExpressionOwner eo = (ExpressionOwner)paths.elementAt(i);
+  		if(null == eo)
+  			continue;
+  			
+  		// Assuming location path iterators should be OK.
+  		LocPathIterator lpi = (LocPathIterator)eo.getExpression();
+  		int numPaths = countSteps(lpi);
+  		if(numPaths > 1)
+  		{
+  			if(null == first)
+  				first = new MultistepExprHolder(eo, numPaths, null);
+  			else
+  				first = first.addInSortedOrder(eo, numPaths);
+  		}
+  	}
+  	
+  	if((null == first) || (first.getLength() <= 1))
+  		return null;
+  	else
+  		return first;
+  }
+  
+  /**
+   * Look through the vector from start point, looking for redundant occurances.
+   * When one or more are found, create a psuedo variable declaration, insert 
+   * it into the stylesheet, and replace the occurance with a reference to 
+   * the psuedo variable.  When a redundent variable is found, it's slot in 
+   * the vector will be replaced by null.
+   * 
+   * @param start The position to start looking in the vector.
+   * @param firstOccuranceIndex The position of firstOccuranceOwner.
+   * @param firstOccuranceOwner The owner of the expression we are looking for.
+   * @param psuedoVarRecipient Where to put the psuedo variables.
+   * 
+   * @return The number of expression occurances that were modified.
+   */
+  protected int findAndEliminateRedundant(int start, int firstOccuranceIndex,
+                         ExpressionOwner firstOccuranceOwner, 
+                         ElemTemplateElement psuedoVarRecipient,
+                         Vector paths) 
+                 throws org.w3c.dom.DOMException 
+  {
+	MultistepExprHolder head = null;
+	MultistepExprHolder tail = null;
+	int numPathsFound = 0;
+	int n = paths.size();
+	
+	Expression expr1 = firstOccuranceOwner.getExpression();
+	if(DEBUG)
+		assertIsLocPathIterator(expr1, firstOccuranceOwner);
+	boolean isGlobal = (paths == m_absPaths);
+	LocPathIterator lpi = (LocPathIterator)expr1;
+	int stepCount = countSteps(lpi);
+	for(int j = start; j < n; j++)
+	{
+		ExpressionOwner owner2 = (ExpressionOwner)paths.elementAt(j);
+		if(null != owner2)
+		{
+			Expression expr2 = owner2.getExpression();
+			boolean isEqual = expr2.deepEquals(lpi);
+			if(isEqual)
+			{  		
+				LocPathIterator lpi2  = (LocPathIterator)expr2;				
+				if(null == head)
+				{
+					head = new MultistepExprHolder(firstOccuranceOwner, stepCount, null);
+					tail = head;
+					numPathsFound++;
+				}
+				tail.m_next = new MultistepExprHolder(owner2, stepCount, null);
+				tail = tail.m_next;
+	
+				// Null out the occurance, so we don't have to test it again.
+				paths.setElementAt(null, j);
+				
+				// foundFirst = true;
+				numPathsFound++;
+			}
+		}
+	}
+	
+	// Change all globals in xsl:templates, etc, to global vars no matter what.
+	if((0 == numPathsFound) && isGlobal)
+	{
+      head = new MultistepExprHolder(firstOccuranceOwner, stepCount, null);
+      numPathsFound++;
+	}
+	
+	if(null != head)
+	{
+		ElemTemplateElement root = isGlobal ? psuedoVarRecipient : findCommonAncestor(head);
+		LocPathIterator sharedIter = (LocPathIterator)head.m_exprOwner.getExpression();
+		ElemVariable var = createPseudoVarDecl(root, sharedIter, isGlobal);
+		if(DIAGNOSE_MULTISTEPLIST)
+			System.err.println("Created var: "+var.getName()+(isGlobal ? "(Global)" : ""));
+		QName uniquePseudoVarName = var.getName();
+		while(null != head)
+		{
+			ExpressionOwner owner = head.m_exprOwner;	
+			if(DIAGNOSE_MULTISTEPLIST)
+				diagnoseLineNumber(owner.getExpression());
+			changeToVarRef(uniquePseudoVarName, owner, paths, root);
+			head = head.m_next;
+		}
+		// Replace the first occurance with the variable's XPath, so  
+		// that further reduction may take place if needed.
+		paths.setElementAt(var.getSelect(), firstOccuranceIndex);
+	}
+	
+	return numPathsFound;
+  } 
+  
+  /**
+   * To be removed.
+   */
+  protected int oldFindAndEliminateRedundant(int start, int firstOccuranceIndex,
+                         ExpressionOwner firstOccuranceOwner, 
+                         ElemTemplateElement psuedoVarRecipient,
+                         Vector paths) 
+                 throws org.w3c.dom.DOMException 
+  {
+	QName uniquePseudoVarName = null;
+	boolean foundFirst = false;
+	int numPathsFound = 0;
+	int n = paths.size();
+	Expression expr1 = firstOccuranceOwner.getExpression();
+	if(DEBUG)
+		assertIsLocPathIterator(expr1, firstOccuranceOwner);
+	boolean isGlobal = (paths == m_absPaths);
+	LocPathIterator lpi = (LocPathIterator)expr1;
+	for(int j = start; j < n; j++)
+	{
+		ExpressionOwner owner2 = (ExpressionOwner)paths.elementAt(j);
+		if(null != owner2)
+		{
+			Expression expr2 = owner2.getExpression();
+			boolean isEqual = expr2.deepEquals(lpi);
+			if(isEqual)
+			{  		
+				LocPathIterator lpi2  = (LocPathIterator)expr2;				
+				if(!foundFirst)
+				{
+					foundFirst = true;
+					// Insert variable decl into psuedoVarRecipient
+					// We want to insert this into the first legitimate 
+					// position for a variable.
+				    ElemVariable var = createPseudoVarDecl(psuedoVarRecipient, lpi, isGlobal);
+				    if(null == var)
+				    	return 0;
+				    uniquePseudoVarName = var.getName();
+	
+					changeToVarRef(uniquePseudoVarName, firstOccuranceOwner, 
+					               paths, psuedoVarRecipient);
+					               
+					// Replace the first occurance with the variable's XPath, so  
+					// that further reduction may take place if needed.
+					paths.setElementAt(var.getSelect(), firstOccuranceIndex);
+					numPathsFound++;
+				}
+	
+				changeToVarRef(uniquePseudoVarName, owner2, paths, psuedoVarRecipient);
+	
+				// Null out the occurance, so we don't have to test it again.
+				paths.setElementAt(null, j);
+				
+				// foundFirst = true;
+				numPathsFound++;
+			}
+		}
+	}
+	
+	// Change all globals in xsl:templates, etc, to global vars no matter what.
+	if((0 == numPathsFound) && (paths == m_absPaths))
+	{
+      ElemVariable var = createPseudoVarDecl(psuedoVarRecipient, lpi, true);
+      if(null == var)
+        return 0;
+	  uniquePseudoVarName = var.getName();
+      changeToVarRef(uniquePseudoVarName, firstOccuranceOwner, paths, psuedoVarRecipient);
+      paths.setElementAt(var.getSelect(), firstOccuranceIndex);
+      numPathsFound++;
+	}
+	return numPathsFound;
+  }
+  
+  /**
+   * Count the steps in a given location path.
+   * 
+   * @param lpi The location path iterator that owns the steps.
+   * @return The number of steps in the given location path.
+   */
+  protected int countSteps(LocPathIterator lpi)
+  {
+  	if(lpi instanceof WalkingIterator)
+  	{
+  		WalkingIterator wi = (WalkingIterator)lpi;
+  		AxesWalker aw = wi.getFirstWalker();
+  		int count = 0;
+  		while(null != aw)
+  		{
+  			count++;
+  			aw = aw.getNextWalker();
+  		}
+  		return count;
+  	}
+  	else
+  		return 1;
+  }
+  
+  /**
+   * Change the expression owned by the owner argument to a variable reference 
+   * of the given name.
+   * 
+   * Warning: For global vars, this function relies on the variable declaration 
+   * to which it refers having been added just prior to this function being called,
+   * so that the reference index can be determined from the size of the global variables 
+   * list minus one.
+   * 
+   * @param varName The name of the variable which will be referenced.
+   * @param owner The owner of the expression which will be replaced by a variable ref.
+   * @param paths The paths list that the iterator came from, mainly to determine
+   *              if this is a local or global reduction.
+   * @param psuedoVarRecipient The element within whose scope the variable is 
+   *                           being inserted, possibly a StylesheetRoot.
+   */
+  protected void changeToVarRef(QName varName, ExpressionOwner owner, 
+                                Vector paths, ElemTemplateElement psuedoVarRecipient) 
+  {
+	Variable varRef = (paths == m_absPaths) ? new VariableSafeAbsRef() : new Variable();
+	varRef.setQName(varName);
+	if(paths == m_absPaths)
+	{
+		StylesheetRoot root = (StylesheetRoot)psuedoVarRecipient;
+		Vector globalVars = root.getVariablesAndParamsComposed();
+		// Assume this operation is occuring just after the decl has 
+		// been added.
+		varRef.setIndex(globalVars.size()-1);
+		varRef.setIsGlobal(true);
+	}
+	owner.setExpression(varRef);
+  }
+   
+  private synchronized static int getPseudoVarID(){
+      return m_uniquePseudoVarID++; 
+  }
+  
+  /**
+   * Create a psuedo variable reference that will represent the 
+   * shared redundent XPath, and add it to the stylesheet.
+   * 
+   * @param psuedoVarRecipient The broadest scope of where the variable 
+   * should be inserted, usually an xsl:template or xsl:for-each.
+   * @param lpi The LocationPathIterator that the variable should represent.
+   * @param isGlobal true if the paths are global.
+   * @return The new psuedo var element.
+   */
+  protected ElemVariable createPseudoVarDecl(
+      ElemTemplateElement psuedoVarRecipient,
+      LocPathIterator lpi, boolean isGlobal)
+      throws org.w3c.dom.DOMException
+  {
+    QName uniquePseudoVarName = new QName (PSUEDOVARNAMESPACE, "#"+getPseudoVarID());
+  		
+  	if(isGlobal)
+  	{
+  	  return createGlobalPseudoVarDecl(uniquePseudoVarName, 
+  	                                  (StylesheetRoot)psuedoVarRecipient, lpi);
+  	}
+  	else						
+      return createLocalPseudoVarDecl(uniquePseudoVarName, psuedoVarRecipient, lpi);
+  }
+  
+  /**
+   * Create a psuedo variable reference that will represent the 
+   * shared redundent XPath, for a local reduction.
+   * 
+   * @param uniquePseudoVarName The name of the new variable.
+   * @param stylesheetRoot The broadest scope of where the variable 
+   *        should be inserted, which must be a StylesheetRoot element in this case.
+   * @param lpi The LocationPathIterator that the variable should represent.
+   * @return null if the decl was not created, otherwise the new Pseudo var  
+   *              element.
+   */
+  protected ElemVariable createGlobalPseudoVarDecl(QName uniquePseudoVarName,
+                                           StylesheetRoot stylesheetRoot, 
+                                           LocPathIterator lpi) 
+        throws org.w3c.dom.DOMException 
+  {
+  	ElemVariable psuedoVar = new ElemVariable();
+  	psuedoVar.setIsTopLevel(true);
+	XPath xpath = new XPath(lpi);
+	psuedoVar.setSelect(xpath);
+	psuedoVar.setName(uniquePseudoVarName);
+	
+	Vector globalVars = stylesheetRoot.getVariablesAndParamsComposed();
+	psuedoVar.setIndex(globalVars.size());
+	globalVars.addElement(psuedoVar);
+	return psuedoVar;
+  }
+
+  
+  
+
+  /**
+   * Create a psuedo variable reference that will represent the 
+   * shared redundent XPath, for a local reduction.
+   * 
+   * @param uniquePseudoVarName The name of the new variable.
+   * @param psuedoVarRecipient The broadest scope of where the variable 
+   * should be inserted, usually an xsl:template or xsl:for-each.
+   * @param lpi The LocationPathIterator that the variable should represent.
+   * @return null if the decl was not created, otherwise the new Pseudo var  
+   *              element.
+   */
+  protected ElemVariable createLocalPseudoVarDecl(QName uniquePseudoVarName,
+                                           ElemTemplateElement psuedoVarRecipient, 
+                                           LocPathIterator lpi) 
+        throws org.w3c.dom.DOMException 
+  {
+		ElemVariable psuedoVar = new ElemVariablePsuedo();
+		
+		XPath xpath = new XPath(lpi);
+		psuedoVar.setSelect(xpath);
+		psuedoVar.setName(uniquePseudoVarName);
+
+		ElemVariable var = addVarDeclToElem(psuedoVarRecipient, lpi, psuedoVar);
+		
+		lpi.exprSetParent(var);
+		
+		return var;
+  }
+
+  /**
+   * Add the given variable to the psuedoVarRecipient.
+   */
+  protected ElemVariable addVarDeclToElem(
+    ElemTemplateElement psuedoVarRecipient,
+    LocPathIterator lpi,
+    ElemVariable psuedoVar)
+    throws org.w3c.dom.DOMException
+  {
+    // Create psuedo variable element
+    ElemTemplateElement ete = psuedoVarRecipient.getFirstChildElem();
+
+    lpi.callVisitors(null, m_varNameCollector);
+
+    // If the location path contains variables, we have to insert the 
+    // psuedo variable after the reference. (Otherwise, we want to 
+    // insert it as close as possible to the top, so we'll be sure 
+    // it is in scope for any other vars.
+    if (m_varNameCollector.getVarCount() > 0)
+    {
+      ElemTemplateElement baseElem = getElemFromExpression(lpi);
+      ElemVariable varElem = getPrevVariableElem(baseElem);
+      while (null != varElem)
+      {
+        if (m_varNameCollector.doesOccur(varElem.getName()))
+          {
+          psuedoVarRecipient = varElem.getParentElem();
+          ete = varElem.getNextSiblingElem();
+          break;
+        }
+        varElem = getPrevVariableElem(varElem);
+      }
+    }
+
+    if ((null != ete) && (Constants.ELEMNAME_PARAMVARIABLE == ete.getXSLToken()))
+    {
+      // Can't stick something in front of a param, so abandon! (see variable13.xsl)
+      if(isParam(lpi))
+        return null;
+
+      while (null != ete)
+      {
+        ete = ete.getNextSiblingElem();
+        if ((null != ete) && Constants.ELEMNAME_PARAMVARIABLE != ete.getXSLToken())
+            break;
+      }
+    }
+    psuedoVarRecipient.insertBefore(psuedoVar, ete);
+    m_varNameCollector.reset();
+    return psuedoVar;
+  }
+    
+  /**
+   * Tell if the expr param is contained within an xsl:param.
+   */
+  protected boolean isParam(ExpressionNode expr)
+  {
+  	while(null != expr)
+  	{
+  		if(expr instanceof ElemTemplateElement)
+  			break;
+  		expr = expr.exprGetParent();
+  	}
+  	if(null != expr)
+  	{
+  		ElemTemplateElement ete = (ElemTemplateElement)expr;
+  		while(null != ete)
+  		{
+  			int type = ete.getXSLToken();
+  			switch(type)
+  			{
+  				case Constants.ELEMNAME_PARAMVARIABLE:
+  					return true;
+  				case Constants.ELEMNAME_TEMPLATE:
+  				case Constants.ELEMNAME_STYLESHEET:
+  					return false;
+  			}
+  			ete = ete.getParentElem();
+  		}
+  	}
+  	return false;
+  	
+  }
+  
+  /**
+   * Find the previous occurance of a xsl:variable.  Stop 
+   * the search when a xsl:for-each, xsl:template, or xsl:stylesheet is 
+   * encountered.
+   * 
+   * @param elem Should be non-null template element.
+   * @return The first previous occurance of an xsl:variable or xsl:param, 
+   * or null if none is found.
+   */
+  protected ElemVariable getPrevVariableElem(ElemTemplateElement elem)
+  {
+  	// This could be somewhat optimized.  since getPreviousSiblingElem is a  
+  	// fairly expensive operation.
+  	while(null != (elem = getPrevElementWithinContext(elem)))
+  	{
+  		int type = elem.getXSLToken();
+  			
+  		if((Constants.ELEMNAME_VARIABLE == type) ||
+  		   (Constants.ELEMNAME_PARAMVARIABLE == type))
+  		{
+  			return (ElemVariable)elem;
+  		}
+  	}
+  	return null;
+  }
+  
+  /**
+   * Get the previous sibling or parent of the given template, stopping at 
+   * xsl:for-each, xsl:template, or xsl:stylesheet.
+   * 
+   * @param elem Should be non-null template element.
+   * @return previous sibling or parent, or null if previous is xsl:for-each, 
+   * xsl:template, or xsl:stylesheet.
+   */
+  protected ElemTemplateElement getPrevElementWithinContext(ElemTemplateElement elem)
+  {
+  	ElemTemplateElement prev = elem.getPreviousSiblingElem();
+  	if(null == prev)
+  		prev = elem.getParentElem();
+  	if(null != prev)
+  	{
+  	  int type = prev.getXSLToken();
+  	  if((Constants.ELEMNAME_FOREACH == type) || 
+  	     (Constants.ELEMNAME_TEMPLATE == type) ||
+  	     (Constants.ELEMNAME_STYLESHEET == type))
+  	  {
+  	  	prev = null;
+  	  }
+  	}
+  	return prev;
+  }
+  
+  /**
+   * From an XPath expression component, get the ElemTemplateElement 
+   * owner.
+   * 
+   * @param expr Should be static expression with proper parentage.
+   * @return Valid ElemTemplateElement, or throw a runtime exception 
+   * if it is not found.
+   */
+  protected ElemTemplateElement getElemFromExpression(Expression expr)
+  {
+  	ExpressionNode parent = expr.exprGetParent();
+  	while(null != parent)
+  	{
+  		if(parent instanceof ElemTemplateElement)
+  			return (ElemTemplateElement)parent;
+  		parent = parent.exprGetParent();
+  	}
+  	throw new RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_NO_TEMPLATE_PARENT, null));
+  	// "Programmer's error! expr has no ElemTemplateElement parent!");
+  }
+      
+  /**
+   * Tell if the given LocPathIterator is relative to an absolute path, i.e. 
+   * in not dependent on the context.
+   * 
+   * @return true if the LocPathIterator is not dependent on the context node.
+   */
+  public boolean isAbsolute(LocPathIterator path)
+  {
+  	int analysis = path.getAnalysisBits();
+    boolean isAbs = (WalkerFactory.isSet(analysis, WalkerFactory.BIT_ROOT) || 
+           WalkerFactory.isSet(analysis, WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT));
+    if(isAbs)
+    {
+    	isAbs = m_absPathChecker.checkAbsolute(path);
+    }
+    return isAbs;
+  }
+
+
+  /**
+   * Visit a LocationPath.
+   * @param owner The owner of the expression, to which the expression can 
+   *              be reset if rewriting takes place.
+   * @param path The LocationPath object.
+   * @return true if the sub expressions should be traversed.
+   */
+  public boolean visitLocationPath(ExpressionOwner owner, LocPathIterator path)
+  {
+  	// Don't optimize "." or single step variable paths.
+  	// Both of these cases could use some further optimization by themselves.
+  	if(path instanceof SelfIteratorNoPredicate)
+  	{
+  		return true;
+  	}
+  	else if(path instanceof WalkingIterator)
+  	{
+  		WalkingIterator wi = (WalkingIterator)path;
+  		AxesWalker aw = wi.getFirstWalker();
+  		if((aw instanceof FilterExprWalker) && (null == aw.getNextWalker()))
+  		{
+  			FilterExprWalker few = (FilterExprWalker)aw;
+  			Expression exp = few.getInnerExpression();
+  			if(exp instanceof Variable)
+  				return true;
+  		}
+  	}
+
+    if (isAbsolute(path) && (null != m_absPaths))
+    {
+      if(DEBUG)
+        validateNewAddition(m_absPaths, owner, path);
+      m_absPaths.addElement(owner);
+    }
+    else if (m_isSameContext && (null != m_paths))
+    {
+      if(DEBUG)
+        validateNewAddition(m_paths, owner, path);
+      m_paths.addElement(owner);
+    }
+
+    return true;
+  }
+
+  /**
+   * Visit a predicate within a location path.  Note that there isn't a 
+   * proper unique component for predicates, and that the expression will 
+   * be called also for whatever type Expression is.
+   * 
+   * @param owner The owner of the expression, to which the expression can 
+   *              be reset if rewriting takes place.
+   * @param pred The predicate object.
+   * @return true if the sub expressions should be traversed.
+   */
+  public boolean visitPredicate(ExpressionOwner owner, Expression pred)
+  {
+    boolean savedIsSame = m_isSameContext;
+    m_isSameContext = false;
+
+    // Any further down, just collect the absolute paths.
+    pred.callVisitors(owner, this);
+
+    m_isSameContext = savedIsSame;
+
+    // We've already gone down the subtree, so don't go have the caller 
+    // go any further.
+    return false;
+  }
+  
+  /**
+   * Visit an XSLT top-level instruction.
+   * 
+   * @param elem The xsl instruction element object.
+   * @return true if the sub expressions should be traversed.
+   */
+   public boolean visitTopLevelInstruction(ElemTemplateElement elem)
+   {
+     int type = elem.getXSLToken();
+     switch(type)
+     {
+       case Constants.ELEMNAME_TEMPLATE :
+         return visitInstruction(elem);
+       default:
+         return true;
+     }
+   }
+
+
+  /**
+   * Visit an XSLT instruction.  Any element that isn't called by one 
+   * of the other visit methods, will be called by this method.
+   * 
+   * @param elem The xsl instruction element object.
+   * @return true if the sub expressions should be traversed.
+   */
+  public boolean visitInstruction(ElemTemplateElement elem)
+  {
+    int type = elem.getXSLToken();
+    switch (type)
+    {
+      case Constants.ELEMNAME_CALLTEMPLATE :
+      case Constants.ELEMNAME_TEMPLATE :
+      case Constants.ELEMNAME_FOREACH :
+        {
+          
+          // Just get the select value.
+          if(type == Constants.ELEMNAME_FOREACH)
+          {
+            ElemForEach efe = (ElemForEach) elem;
+   		    
+  		    Expression select = efe.getSelect();
+  		    select.callVisitors(efe, this);
+          }
+         
+  		  Vector savedPaths = m_paths;
+  		  m_paths = new Vector();
+  		    
+  		  // Visit children.  Call the superclass callChildVisitors, because 
+  		  // we don't want to visit the xsl:for-each select attribute, or, for 
+  		  // that matter, the xsl:template's match attribute.
+  		  elem.callChildVisitors(this, false);  		
+  		  eleminateRedundentLocals(elem);
+  		    
+  		  m_paths = savedPaths;
+ 
+          // select.callVisitors(efe, this);
+          return false;
+        }
+      case Constants.ELEMNAME_NUMBER :
+      case Constants.ELEMNAME_SORT :
+        // Just collect absolute paths until and unless we can fully
+        // analyze these cases.
+        boolean savedIsSame = m_isSameContext;
+        m_isSameContext = false;
+        elem.callChildVisitors(this);
+        m_isSameContext = savedIsSame;
+        return false;
+        
+      default :
+        return true;
+    }
+  }
+  
+  // ==== DIAGNOSTIC AND DEBUG FUNCTIONS ====
+  
+  /**
+   * Print out to std err the number of paths reduced.
+   */
+  protected void diagnoseNumPaths(Vector paths, int numPathsEliminated,  
+                                  int numUniquePathsEliminated) 
+  {
+		if (numPathsEliminated > 0)
+		{ 
+		  if(paths == m_paths)
+		  {
+		    System.err.println("Eliminated " + numPathsEliminated + " total paths!");
+		    System.err.println(
+		      "Consolodated " + numUniquePathsEliminated + " redundent paths!");
+		  }
+		  else
+		  {
+		    System.err.println("Eliminated " + numPathsEliminated + " total global paths!");
+		    System.err.println(
+		      "Consolodated " + numUniquePathsEliminated + " redundent global paths!");
+		  }
+		}  
+  }
+
+
+  /**
+   * Assert that the expression is a LocPathIterator, and, if 
+   * not, try to give some diagnostic info.
+   */
+  private final void assertIsLocPathIterator(Expression expr1, ExpressionOwner eo) 
+    throws RuntimeException 
+  {
+		if(!(expr1 instanceof LocPathIterator))
+		{
+			String errMsg;
+			if(expr1 instanceof Variable)
+			{
+				errMsg = "Programmer's assertion: expr1 not an iterator: "+
+				          ((Variable)expr1).getQName();
+			}
+			else
+			{
+				errMsg = "Programmer's assertion: expr1 not an iterator: "+
+				          expr1.getClass().getName();
+			}
+			throw new RuntimeException(errMsg + ", "+
+				          eo.getClass().getName()+" "+
+				          expr1.exprGetParent());
+		}
+  }
+
+
+  /**
+   * Validate some assumptions about the new LocPathIterator and it's 
+   * owner and the state of the list.
+   */
+  private static void validateNewAddition(Vector paths, ExpressionOwner owner, 
+                                          LocPathIterator path) 
+		throws RuntimeException 
+  {
+  	assertion(owner.getExpression() == path, "owner.getExpression() != path!!!");
+	int n = paths.size();
+	// There should never be any duplicates in the list!
+	for(int i = 0; i < n; i++)
+	{
+		ExpressionOwner ew = (ExpressionOwner)paths.elementAt(i);
+		assertion(ew != owner, "duplicate owner on the list!!!");
+		assertion(ew.getExpression() != path, "duplicate expression on the list!!!");
+	}
+  }
+  
+  /**
+   * Simple assertion.
+   */
+  protected static void assertion(boolean b, String msg)
+  {
+  	if(!b)
+  	{
+  		throw new RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR, new Object[]{msg}));
+  		// "Programmer's assertion in RundundentExprEliminator: "+msg);
+  	}
+  }
+  
+  /**
+   * Since we want to sort multistep expressions by length, use 
+   * a linked list with elements of type MultistepExprHolder.
+   */
+  class MultistepExprHolder implements Cloneable
+  {
+	ExpressionOwner m_exprOwner; // Will change to null once we have processed this item.
+	final int m_stepCount;
+	MultistepExprHolder m_next;
+	
+	/**
+	 * Clone this object.
+	 */
+	public Object clone()
+		throws CloneNotSupportedException
+	{
+		return super.clone();
+	}
+	
+	/**
+	 * Create a MultistepExprHolder.
+	 * 
+	 * @param exprOwner the owner of the expression we are holding.
+	 *                  It must hold a LocationPathIterator.
+	 * @param stepCount The number of steps in the location path.
+	 */
+  	MultistepExprHolder(ExpressionOwner exprOwner, int stepCount, MultistepExprHolder next)
+  	{
+  		m_exprOwner = exprOwner;
+  		assertion(null != m_exprOwner, "exprOwner can not be null!");
+  		m_stepCount = stepCount;
+  		m_next = next;
+  	}
+	
+	/**
+	 * Add a new MultistepExprHolder in sorted order in the list.
+	 * 
+	 * @param exprOwner the owner of the expression we are holding.
+	 *                  It must hold a LocationPathIterator.
+	 * @param stepCount The number of steps in the location path.
+	 * @return The new head of the linked list.
+	 */
+	MultistepExprHolder addInSortedOrder(ExpressionOwner exprOwner, int stepCount)
+	{
+		MultistepExprHolder first = this;
+		MultistepExprHolder next = this;
+		MultistepExprHolder prev = null;
+		while(null != next)
+		{
+			if(stepCount >= next.m_stepCount)
+			{
+				MultistepExprHolder newholder = new MultistepExprHolder(exprOwner, stepCount, next);
+				if(null == prev)
+					first = newholder;
+				else
+					prev.m_next = newholder;
+					
+				return first;
+			}
+			prev = next;
+			next = next.m_next;
+		}
+		
+		prev.m_next = new MultistepExprHolder(exprOwner, stepCount, null);
+		return first;
+	}
+	
+	/**
+	 * Remove the given element from the list.  'this' should 
+	 * be the head of the list.  If the item to be removed is not 
+	 * found, an assertion will be made.
+	 * 
+	 * @param itemToRemove The item to remove from the list.
+	 * @return The head of the list, which may have changed if itemToRemove 
+	 * is the same as this element.  Null if the item to remove is the 
+	 * only item in the list.
+	 */
+	MultistepExprHolder unlink(MultistepExprHolder itemToRemove)
+	{
+		MultistepExprHolder first = this;
+		MultistepExprHolder next = this;
+		MultistepExprHolder prev = null;
+		while(null != next)
+		{
+			if(next == itemToRemove)
+			{
+				if(null == prev)
+					first = next.m_next;
+				else
+					prev.m_next = next.m_next;
+				
+				next.m_next = null;
+					
+				return first;
+			}
+			prev = next;
+			next = next.m_next;
+		}
+		
+		assertion(false, "unlink failed!!!");
+		return null;
+	}
+		
+	/**
+	 * Get the number of linked list items.
+	 */
+	int getLength()
+	{
+		int count = 0;
+		MultistepExprHolder next = this;
+		while(null != next)
+		{
+			count++;
+			next = next.m_next;
+		}
+		return count;
+	}
+	
+    /**
+     * Print diagnostics out for the multistep list.
+     */
+    protected void diagnose()
+    {
+      System.err.print("Found multistep iterators: " + this.getLength() + "  ");
+      MultistepExprHolder next = this;
+      while (null != next)
+      {
+        System.err.print("" + next.m_stepCount);
+        next = next.m_next;
+        if (null != next)
+              System.err.print(", ");
+      }
+      System.err.println();
+    }
+	
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/Stylesheet.java b/src/main/java/org/apache/xalan/templates/Stylesheet.java
new file mode 100644
index 0000000..11bbe9e
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/Stylesheet.java
@@ -0,0 +1,1516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Stylesheet.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Hashtable;
+import java.util.Stack;
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.StringVector;
+import org.apache.xml.utils.SystemIDResolver;
+
+/**
+ * Represents a stylesheet element.
+ * <p>All properties in this class have a fixed form of bean-style property
+ * accessors for all properties that represent XSL attributes or elements.
+ * These properties have setter method names accessed generically by the
+ * processor, and so these names must be fixed according to the system
+ * defined in the <a href="XSLTAttributeDef#getSetterMethodName">getSetterMethodName</a>
+ * function.</p>
+ * <p><pre>
+ * <!ENTITY % top-level "
+ *  (xsl:import*,
+ *   (xsl:include
+ *   | xsl:strip-space
+ *   | xsl:preserve-space
+ *   | xsl:output
+ *   | xsl:key
+ *   | xsl:decimal-format
+ *   | xsl:attribute-set
+ *   | xsl:variable
+ *   | xsl:param
+ *   | xsl:template
+ *   | xsl:namespace-alias
+ *   %non-xsl-top-level;)*)
+ * ">
+ *
+ * <!ENTITY % top-level-atts '
+ *   extension-element-prefixes CDATA #IMPLIED
+ *   exclude-result-prefixes CDATA #IMPLIED
+ *   id ID #IMPLIED
+ *   version NMTOKEN #REQUIRED
+ *   xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
+ *   %space-att;
+ * '>
+ *
+ * <!ELEMENT xsl:stylesheet %top-level;>
+ * <!ATTLIST xsl:stylesheet %top-level-atts;>
+ *
+ * <!ELEMENT xsl:transform %top-level;>
+ * <!ATTLIST xsl:transform %top-level-atts;>
+ *
+ * </p></pre>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Stylesheet-Structure">section-Stylesheet-Structure in XSLT Specification</a>
+ */
+public class Stylesheet extends ElemTemplateElement
+        implements java.io.Serializable /* , Document */
+{
+    static final long serialVersionUID = 2085337282743043776L;
+
+  /**
+   * Constructor for a Stylesheet.
+   * @param parent  The including or importing stylesheet.
+   */
+  public Stylesheet(Stylesheet parent)
+  {
+
+    if (null != parent)
+    {
+      m_stylesheetParent = parent;
+      m_stylesheetRoot = parent.getStylesheetRoot();
+    }
+  }
+
+  /**
+   * Get the owning stylesheet.  This looks up the
+   * inheritance chain until it calls getStylesheet
+   * on a Stylesheet object, which will return itself.
+   *
+   * @return The owning stylesheet, itself.
+   */
+  public Stylesheet getStylesheet()
+  {
+    return this;
+  }
+
+  /**
+   * Tell if this can be cast to a StylesheetComposed, meaning, you
+   * can ask questions from getXXXComposed functions.
+   *
+   * @return False if this is not a StylesheetComposed
+   */
+  public boolean isAggregatedType()
+  {
+    return false;
+  }
+
+  /**
+   * Tell if this is the root of the stylesheet tree.
+   *
+   * @return False is this is not the root of the stylesheet tree.
+   */
+  public boolean isRoot()
+  {
+    return false;
+  }
+
+  /**
+   * Extension to be used when serializing to disk.
+   */
+  public static final String STYLESHEET_EXT = ".lxc";
+
+  /**
+   * Read the stylesheet from a serialization stream.
+   *
+   * @param stream Input stream to read from
+   *
+   * @throws IOException
+   * @throws TransformerException
+   */
+  private void readObject(ObjectInputStream stream)
+          throws IOException, TransformerException
+  {
+
+    // System.out.println("Reading Stylesheet");
+    try
+    {
+      stream.defaultReadObject();
+    }
+    catch (ClassNotFoundException cnfe)
+    {
+      throw new TransformerException(cnfe);
+    }
+
+    // System.out.println("Done reading Stylesheet");
+  }
+
+  /**
+   * Write out the given output stream 
+   *
+   *
+   * @param stream The output stream to write out
+   *
+   * @throws IOException
+   */
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+
+    // System.out.println("Writing Stylesheet");
+    stream.defaultWriteObject();
+
+    // System.out.println("Done writing Stylesheet");
+  }
+
+  //============== XSLT Properties =================
+
+  /**
+   * The "xmlns:xsl" property.
+   * @serial
+   */
+  private String m_XmlnsXsl;
+
+  /**
+   * Set the "xmlns:xsl" property.
+   * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
+   *
+   * @param v The value to be set for the "xmlns:xsl" property.
+   */
+  public void setXmlnsXsl(String v)
+  {
+    m_XmlnsXsl = v;
+  }
+
+  /**
+   * Get the "xmlns:xsl" property.
+   * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
+   *
+   * @return The value of the "xmlns:xsl" property.
+   */
+  public String getXmlnsXsl()
+  {
+    return m_XmlnsXsl;
+  }
+
+  /**
+   * The "extension-element-prefixes" property, actually contains URIs.
+   * @serial
+   */
+  private StringVector m_ExtensionElementURIs;
+
+  /**
+   * Set the "extension-element-prefixes" property.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param v The value to be set for the "extension-element-prefixes" 
+   * property: a vector of extension element URIs.
+   */
+  public void setExtensionElementPrefixes(StringVector v)
+  {
+    m_ExtensionElementURIs = v;
+  }
+
+  /**
+   * Get and "extension-element-prefix" property.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param i Index of extension element URI in list 
+   *
+   * @return The extension element URI at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public String getExtensionElementPrefix(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_ExtensionElementURIs)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return m_ExtensionElementURIs.elementAt(i);
+  }
+
+  /**
+   * Get the number of "extension-element-prefixes" Strings.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @return Number of URIs in the list
+   */
+  public int getExtensionElementPrefixCount()
+  {
+    return (null != m_ExtensionElementURIs)
+           ? m_ExtensionElementURIs.size() : 0;
+  }
+
+  /**
+   * Find out if this contains a given "extension-element-prefix" property.
+   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
+   *
+   * @param uri URI of extension element to look for
+   *
+   * @return True if the given URI was found in the list 
+   */
+  public boolean containsExtensionElementURI(String uri)
+  {
+
+    if (null == m_ExtensionElementURIs)
+      return false;
+
+    return m_ExtensionElementURIs.contains(uri);
+  }
+
+  /**
+   * The "exclude-result-prefixes" property.
+   * @serial
+   */
+  private StringVector m_ExcludeResultPrefixs;
+
+  /**
+   * Set the "exclude-result-prefixes" property.
+   * The designation of a namespace as an excluded namespace is
+   * effective within the subtree of the stylesheet rooted at
+   * the element bearing the exclude-result-prefixes or
+   * xsl:exclude-result-prefixes attribute; a subtree rooted
+   * at an xsl:stylesheet element does not include any stylesheets
+   * imported or included by children of that xsl:stylesheet element.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param v A StringVector of prefixes to exclude 
+   */
+  public void setExcludeResultPrefixes(StringVector v)
+  {
+    m_ExcludeResultPrefixs = v;
+  }
+
+  /**
+   * Get an "exclude-result-prefix" property.
+   * The designation of a namespace as an excluded namespace is
+   * effective within the subtree of the stylesheet rooted at
+   * the element bearing the exclude-result-prefixes or
+   * xsl:exclude-result-prefixes attribute; a subtree rooted
+   * at an xsl:stylesheet element does not include any stylesheets
+   * imported or included by children of that xsl:stylesheet element.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param i Index of prefix to get in list 
+   *
+   * @return Prefix to be excluded at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public String getExcludeResultPrefix(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_ExcludeResultPrefixs)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return m_ExcludeResultPrefixs.elementAt(i);
+  }
+
+  /**
+   * Get the number of "exclude-result-prefixes" Strings.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @return The number of prefix strings to be excluded. 
+   */
+  public int getExcludeResultPrefixCount()
+  {
+    return (null != m_ExcludeResultPrefixs)
+           ? m_ExcludeResultPrefixs.size() : 0;
+  }
+
+  /**
+   * Get whether or not the passed prefix is contained flagged by
+   * the "exclude-result-prefixes" property.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param prefix non-null reference to prefix that might be excluded.
+   * @param uri reference to namespace that prefix maps to
+   *
+   * @return true if the prefix should normally be excluded.>
+   */
+  public boolean containsExcludeResultPrefix(String prefix, String uri) 
+  {
+
+    if (null == m_ExcludeResultPrefixs || uri == null )
+      return false;
+    
+    // This loop is ok here because this code only runs during
+    // stylesheet compile time.
+    for (int i =0; i< m_ExcludeResultPrefixs.size(); i++)
+    {
+      if (uri.equals(getNamespaceForPrefix(m_ExcludeResultPrefixs.elementAt(i))))
+        return true;
+    }
+    
+    return false;
+
+  /*  if (prefix.length() == 0)
+      prefix = Constants.ATTRVAL_DEFAULT_PREFIX;
+
+    return m_ExcludeResultPrefixs.contains(prefix); */
+  }
+
+  /**
+   * The "id" property.
+   * @serial
+   */
+  private String m_Id;
+
+  /**
+   * Set the "id" property.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
+   *
+   * @param v Value for the "id" property.
+   */
+  public void setId(String v)
+  {
+    m_Id = v;
+  }
+
+  /**
+   * Get the "id" property.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
+   *
+   * @return The value of the "id" property.
+   */
+  public String getId()
+  {
+    return m_Id;
+  }
+
+  /**
+   * The "version" property.
+   * @serial
+   */
+  private String m_Version;
+  
+  /**
+   * Whether or not the stylesheet is in "Forward Compatibility Mode" 
+   * @serial
+   */
+  private boolean m_isCompatibleMode = false;
+
+  /**
+   * Set the "version" property.
+   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
+   *
+   * @param v Value for the "version" property.
+   */
+  public void setVersion(String v)
+  {
+    m_Version = v;
+    m_isCompatibleMode = (Double.valueOf(v).doubleValue() > Constants.XSLTVERSUPPORTED);
+  }
+
+  /**
+   * Get whether or not the stylesheet is in "Forward Compatibility Mode"
+   * 
+   * @return true if in forward compatible mode, false otherwise
+   */
+  public boolean getCompatibleMode()
+  {
+  	return m_isCompatibleMode;
+  }
+
+  /**
+   * Get the "version" property.
+   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
+   *
+   * @return The value of the "version" property.
+   */
+  public String getVersion()
+  {
+    return m_Version;
+  }
+
+  /**
+   * The "xsl:import" list.
+   * @serial
+   */
+  private Vector m_imports;
+
+  /**
+   * Add a stylesheet to the "import" list.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @param v Stylesheet to add to the import list
+   */
+  public void setImport(StylesheetComposed v)
+  {
+
+    if (null == m_imports)
+      m_imports = new Vector();
+
+    // I'm going to insert the elements in backwards order,
+    // so I can walk them 0 to n.
+    m_imports.addElement(v);
+  }
+
+  /**
+   * Get a stylesheet from the "import" list.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @param i Index of the stylesheet to get
+   *
+   * @return The stylesheet at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public StylesheetComposed getImport(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_imports)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (StylesheetComposed) m_imports.elementAt(i);
+  }
+
+  /**
+   * Get the number of imported stylesheets.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @return the number of imported stylesheets.
+   */
+  public int getImportCount()
+  {
+    return (null != m_imports) ? m_imports.size() : 0;
+  }
+
+  /**
+   * The "xsl:include" properties.
+   * @serial
+   */
+  private Vector m_includes;
+
+  /**
+   * Add a stylesheet to the "include" list.
+   * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
+   *
+   * @param v Stylesheet to add to the "include" list  
+   */
+  public void setInclude(Stylesheet v)
+  {
+
+    if (null == m_includes)
+      m_includes = new Vector();
+
+    m_includes.addElement(v);
+  }
+
+  /**
+   * Get the stylesheet at the given in index in "include" list
+   * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
+   *
+   * @param i Index of stylesheet to get
+   *
+   * @return Stylesheet at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public Stylesheet getInclude(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_includes)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (Stylesheet) m_includes.elementAt(i);
+  }
+
+  /**
+   * Get the number of included stylesheets.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @return the number of included stylesheets.
+   */
+  public int getIncludeCount()
+  {
+    return (null != m_includes) ? m_includes.size() : 0;
+  }
+
+  /**
+   * Table of tables of element decimal-format.
+   * @see DecimalFormatProperties
+   * @serial
+   */
+  Stack m_DecimalFormatDeclarations;
+
+  /**
+   * Process the xsl:decimal-format element.
+   *
+   * @param edf Decimal-format element to push into stack  
+   */
+  public void setDecimalFormat(DecimalFormatProperties edf)
+  {
+
+    if (null == m_DecimalFormatDeclarations)
+      m_DecimalFormatDeclarations = new Stack();
+
+    // Elements are pushed in by order of importance
+    // so that when recomposed, they get overiden properly.
+    m_DecimalFormatDeclarations.push(edf);
+  }
+
+  /**
+   * Get an "xsl:decimal-format" property.
+   * 
+   * @see DecimalFormatProperties
+   * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
+   *
+   * @param name The qualified name of the decimal format property.
+   * @return null if not found, otherwise a DecimalFormatProperties
+   * object, from which you can get a DecimalFormatSymbols object.
+   */
+  public DecimalFormatProperties getDecimalFormat(QName name)
+  {
+
+    if (null == m_DecimalFormatDeclarations)
+      return null;
+
+    int n = getDecimalFormatCount();
+
+    for (int i = (n - 1); i >= 0; i++)
+    {
+      DecimalFormatProperties dfp = getDecimalFormat(i);
+
+      if (dfp.getName().equals(name))
+        return dfp;
+    }
+
+    return null;
+  }
+
+  /**
+   * Get an "xsl:decimal-format" property.
+   * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
+   * @see DecimalFormatProperties
+   *
+   * @param i Index of decimal-format property in stack
+   *
+   * @return The decimal-format property at the given index 
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public DecimalFormatProperties getDecimalFormat(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_DecimalFormatDeclarations)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (DecimalFormatProperties) m_DecimalFormatDeclarations.elementAt(i);
+  }
+
+  /**
+   * Get the number of xsl:decimal-format declarations.
+   * @see DecimalFormatProperties
+   *
+   * @return the number of xsl:decimal-format declarations.
+   */
+  public int getDecimalFormatCount()
+  {
+    return (null != m_DecimalFormatDeclarations)
+           ? m_DecimalFormatDeclarations.size() : 0;
+  }
+
+  /**
+   * The "xsl:strip-space" properties,
+   * A lookup table of all space stripping elements.
+   * @serial
+   */
+  private Vector m_whitespaceStrippingElements;
+
+  /**
+   * Set the "xsl:strip-space" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param wsi WhiteSpaceInfo element to add to list 
+   */
+  public void setStripSpaces(WhiteSpaceInfo wsi)
+  {
+
+    if (null == m_whitespaceStrippingElements)
+    {
+      m_whitespaceStrippingElements = new Vector();
+    }
+
+    m_whitespaceStrippingElements.addElement(wsi);
+  }
+
+  /**
+   * Get an "xsl:strip-space" property.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param i Index of WhiteSpaceInfo to get
+   *
+   * @return WhiteSpaceInfo at given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public WhiteSpaceInfo getStripSpace(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_whitespaceStrippingElements)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (WhiteSpaceInfo) m_whitespaceStrippingElements.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:strip-space" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @return the number of "xsl:strip-space" properties.
+   */
+  public int getStripSpaceCount()
+  {
+    return (null != m_whitespaceStrippingElements)
+           ? m_whitespaceStrippingElements.size() : 0;
+  }
+
+  /**
+   * The "xsl:preserve-space" property,
+   * A lookup table of all space preserving elements.
+   * @serial
+   */
+  private Vector m_whitespacePreservingElements;
+
+  /**
+   * Set the "xsl:preserve-space" property.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param wsi WhiteSpaceInfo element to add to list
+   */
+  public void setPreserveSpaces(WhiteSpaceInfo wsi)
+  {
+
+    if (null == m_whitespacePreservingElements)
+    {
+      m_whitespacePreservingElements = new Vector();
+    }
+
+    m_whitespacePreservingElements.addElement(wsi);
+  }
+
+  /**
+   * Get a "xsl:preserve-space" property.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param i Index of WhiteSpaceInfo to get
+   *
+   * @return WhiteSpaceInfo at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public WhiteSpaceInfo getPreserveSpace(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_whitespacePreservingElements)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (WhiteSpaceInfo) m_whitespacePreservingElements.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:preserve-space" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @return the number of "xsl:preserve-space" properties.
+   */
+  public int getPreserveSpaceCount()
+  {
+    return (null != m_whitespacePreservingElements)
+           ? m_whitespacePreservingElements.size() : 0;
+  }
+
+  /**
+   * The "xsl:output" properties.  This is a vector of OutputProperties objects.
+   * @serial
+   */
+  private Vector m_output;
+
+  /**
+   * Set the "xsl:output" property.
+   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
+   *
+   * @param v non-null reference to the OutputProperties object to be 
+   *          added to the collection.
+   */
+  public void setOutput(OutputProperties v)
+  {
+    if (null == m_output)
+    {
+      m_output = new Vector();
+    }
+
+    m_output.addElement(v);
+  }
+
+  /**
+   * Get an "xsl:output" property.
+   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
+   *
+   * @param i Index of OutputFormatExtended to get
+   *
+   * @return non-null reference to an OutputProperties object.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public OutputProperties getOutput(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_output)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (OutputProperties) m_output.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:output" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
+   *
+   * @return The number of OutputProperties objects contained in this stylesheet.
+   */
+  public int getOutputCount()
+  {
+    return (null != m_output)
+           ? m_output.size() : 0;
+  }
+
+  /**
+   * The "xsl:key" property.
+   * @serial
+   */
+  private Vector m_keyDeclarations;
+
+  /**
+   * Set the "xsl:key" property.
+   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+   *
+   * @param v KeyDeclaration element to add to the list of key declarations 
+   */
+  public void setKey(KeyDeclaration v)
+  {
+
+    if (null == m_keyDeclarations)
+      m_keyDeclarations = new Vector();
+
+    m_keyDeclarations.addElement(v);
+  }
+
+  /**
+   * Get an "xsl:key" property.
+   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+   *
+   * @param i Index of KeyDeclaration element to get
+   *
+   * @return KeyDeclaration element at given index in list 
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public KeyDeclaration getKey(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_keyDeclarations)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (KeyDeclaration) m_keyDeclarations.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:key" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+   *
+   * @return the number of "xsl:key" properties.
+   */
+  public int getKeyCount()
+  {
+    return (null != m_keyDeclarations) ? m_keyDeclarations.size() : 0;
+  }
+
+  /**
+   * The "xsl:attribute-set" property.
+   * @serial
+   */
+  private Vector m_attributeSets;
+
+  /**
+   * Set the "xsl:attribute-set" property.
+   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+   *
+   * @param attrSet ElemAttributeSet to add to the list of attribute sets
+   */
+  public void setAttributeSet(ElemAttributeSet attrSet)
+  {
+
+    if (null == m_attributeSets)
+    {
+      m_attributeSets = new Vector();
+    }
+
+    m_attributeSets.addElement(attrSet);
+  }
+
+  /**
+   * Get an "xsl:attribute-set" property.
+   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+   *
+   * @param i Index of ElemAttributeSet to get in list
+   *
+   * @return ElemAttributeSet at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public ElemAttributeSet getAttributeSet(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_attributeSets)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (ElemAttributeSet) m_attributeSets.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:attribute-set" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+   *
+   * @return the number of "xsl:attribute-set" properties.
+   */
+  public int getAttributeSetCount()
+  {
+    return (null != m_attributeSets) ? m_attributeSets.size() : 0;
+  }
+
+  /**
+   * The "xsl:variable" and "xsl:param" properties.
+   * @serial
+   */
+  private Vector m_topLevelVariables;
+
+  /**
+   * Set the "xsl:variable" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param v ElemVariable object to add to list of top level variables
+   */
+  public void setVariable(ElemVariable v)
+  {
+
+    if (null == m_topLevelVariables)
+      m_topLevelVariables = new Vector();
+
+    m_topLevelVariables.addElement(v);
+  }
+  
+  /**
+   * Get an "xsl:variable" or "xsl:param" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param qname non-null reference to the qualified name of the variable.
+   *
+   * @return The ElemVariable with the given name in the list or null
+   */
+  public ElemVariable getVariableOrParam(QName qname)
+  {
+
+    if (null != m_topLevelVariables)
+    {
+      int n = getVariableOrParamCount();
+
+      for (int i = 0; i < n; i++)
+      {
+        ElemVariable var = (ElemVariable) getVariableOrParam(i);
+
+        if (var.getName().equals(qname))
+          return var;
+      }
+    }
+
+    return null;
+  }
+
+
+  /**
+   * Get an "xsl:variable" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param qname Qualified name of the xsl:variable to get 
+   *
+   * @return reference to the variable named by qname, or null if not found.
+   */
+  public ElemVariable getVariable(QName qname)
+  {
+
+    if (null != m_topLevelVariables)
+    {
+      int n = getVariableOrParamCount();
+
+      for (int i = 0; i < n; i++)
+      {
+        ElemVariable var = getVariableOrParam(i);
+        if((var.getXSLToken() == Constants.ELEMNAME_VARIABLE) &&
+           (var.getName().equals(qname)))
+          return var;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Get an "xsl:variable" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param i Index of variable to get in the list
+   *
+   * @return ElemVariable at the given index in the list 
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public ElemVariable getVariableOrParam(int i) throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_topLevelVariables)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (ElemVariable) m_topLevelVariables.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:variable" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @return the number of "xsl:variable" properties.
+   */
+  public int getVariableOrParamCount()
+  {
+    return (null != m_topLevelVariables) ? m_topLevelVariables.size() : 0;
+  }
+
+  /**
+   * Set an "xsl:param" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param v A non-null ElemParam reference.
+   */
+  public void setParam(ElemParam v)
+  {
+    setVariable(v);
+  }
+
+  /**
+   * Get an "xsl:param" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param qname non-null reference to qualified name of the parameter.
+   *
+   * @return ElemParam with the given name in the list or null
+   */
+  public ElemParam getParam(QName qname)
+  {
+
+    if (null != m_topLevelVariables)
+    {
+      int n = getVariableOrParamCount();
+
+      for (int i = 0; i < n; i++)
+      {
+        ElemVariable var = getVariableOrParam(i);
+        if((var.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) &&
+           (var.getName().equals(qname)))
+          return (ElemParam)var;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * The "xsl:template" properties.
+   * @serial
+   */
+  private Vector m_templates;
+
+  /**
+   * Set an "xsl:template" property.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @param v ElemTemplate to add to list of templates
+   */
+  public void setTemplate(ElemTemplate v)
+  {
+
+    if (null == m_templates)
+      m_templates = new Vector();
+
+    m_templates.addElement(v);
+    v.setStylesheet(this);
+  }
+
+  /**
+   * Get an "xsl:template" property.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @param i Index of ElemTemplate in the list to get
+   *
+   * @return ElemTemplate at the given index in the list
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplate(int i) throws TransformerException
+  {
+
+    if (null == m_templates)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (ElemTemplate) m_templates.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:template" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @return the number of "xsl:template" properties.
+   */
+  public int getTemplateCount()
+  {
+    return (null != m_templates) ? m_templates.size() : 0;
+  }
+
+  /**
+   * The "xsl:namespace-alias" properties.
+   * @serial
+   */
+  private Vector m_prefix_aliases;
+
+  /**
+   * Set the "xsl:namespace-alias" property.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param na NamespaceAlias elemeent to add to the list
+   */
+  public void setNamespaceAlias(NamespaceAlias na)
+  {
+
+    if (m_prefix_aliases == null)
+      m_prefix_aliases = new Vector();
+
+    m_prefix_aliases.addElement(na);
+  }
+
+  /**
+   * Get an "xsl:namespace-alias" property.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param i Index of NamespaceAlias element to get from the list 
+   *
+   * @return NamespaceAlias element at the given index in the list
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public NamespaceAlias getNamespaceAlias(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (null == m_prefix_aliases)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (NamespaceAlias) m_prefix_aliases.elementAt(i);
+  }
+
+  /**
+   * Get the number of "xsl:namespace-alias" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @return the number of "xsl:namespace-alias" properties.
+   */
+  public int getNamespaceAliasCount()
+  {
+    return (null != m_prefix_aliases) ? m_prefix_aliases.size() : 0;
+  }
+
+  /**
+   * The "non-xsl-top-level" properties.
+   * @serial
+   */
+  private Hashtable m_NonXslTopLevel;
+
+  /**
+   * Set found a non-xslt element.
+   * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
+   *
+   * @param name Qualified name of the element
+   * @param obj The element object
+   */
+  public void setNonXslTopLevel(QName name, Object obj)
+  {
+
+    if (null == m_NonXslTopLevel)
+      m_NonXslTopLevel = new Hashtable();
+
+    m_NonXslTopLevel.put(name, obj);
+  }
+
+  /**
+   * Get a non-xslt element.
+   * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
+   *
+   * @param name Qualified name of the element to get
+   *
+   * @return The object associate with the given name 
+   */
+  public Object getNonXslTopLevel(QName name)
+  {
+    return (null != m_NonXslTopLevel) ? m_NonXslTopLevel.get(name) : null;
+  }
+
+  // =========== End top-level XSLT properties ===========
+
+  /**
+   * The base URL of the XSL document.
+   * @serial
+   */
+  private String m_href = null;
+
+  /** The doctype-public element.
+   *  @serial          */
+  private String m_publicId;
+
+  /** The doctype-system element.
+   *  @serial          */
+  private String m_systemId;
+
+  /**
+   * Get the base identifier with which this stylesheet is associated.
+   *
+   * @return the base identifier with which this stylesheet is associated.
+   */
+  public String getHref()
+  {
+    return m_href;
+  }
+
+  /**
+   * Set the base identifier with which this stylesheet is associated.
+   *
+   * @param baseIdent the base identifier with which this stylesheet is associated.
+   */
+  public void setHref(String baseIdent)
+  {
+    m_href = baseIdent;
+  }
+
+  /**
+   * Set the location information for this element.
+   *
+   * @param locator SourceLocator object with location information  
+   */
+  public void setLocaterInfo(SourceLocator locator)
+  {
+
+    if (null != locator)
+    {
+      m_publicId = locator.getPublicId();
+      m_systemId = locator.getSystemId();
+
+      if (null != m_systemId)
+      {
+        try
+        {
+          m_href = SystemIDResolver.getAbsoluteURI(m_systemId, null);
+        }
+        catch (TransformerException se)
+        {
+
+          // Ignore this for right now
+        }
+      }
+
+      super.setLocaterInfo(locator);
+    }
+  }
+
+  /**
+   * The root of the stylesheet, where all the tables common
+   * to all stylesheets are kept.
+   * @serial
+   */
+  private StylesheetRoot m_stylesheetRoot;
+
+  /**
+   * Get the root of the stylesheet, where all the tables common
+   * to all stylesheets are kept.
+   *
+   * @return the root of the stylesheet
+   */
+  public StylesheetRoot getStylesheetRoot()
+  {
+    return m_stylesheetRoot;
+  }
+
+  /**
+   * Set the root of the stylesheet, where all the tables common
+   * to all stylesheets are kept.
+   *
+   * @param v the root of the stylesheet
+   */
+  public void setStylesheetRoot(StylesheetRoot v)
+  {
+    m_stylesheetRoot = v;
+  }
+
+  /**
+   * The parent of the stylesheet.  This will be null if this
+   * is the root stylesheet.
+   * @serial
+   */
+  private Stylesheet m_stylesheetParent;
+
+  /**
+   * Get the parent of the stylesheet.  This will be null if this
+   * is the root stylesheet.
+   *
+   * @return the parent of the stylesheet.
+   */
+  public Stylesheet getStylesheetParent()
+  {
+    return m_stylesheetParent;
+  }
+
+  /**
+   * Set the parent of the stylesheet.  This should be null if this
+   * is the root stylesheet.
+   *
+   * @param v the parent of the stylesheet.
+   */
+  public void setStylesheetParent(Stylesheet v)
+  {
+    m_stylesheetParent = v;
+  }
+
+  /**
+   * Get the owning aggregated stylesheet, or this
+   * stylesheet if it is aggregated.
+   *
+   * @return the owning aggregated stylesheet or itself
+   */
+  public StylesheetComposed getStylesheetComposed()
+  {
+
+    Stylesheet sheet = this;
+
+    while (!sheet.isAggregatedType())
+    {
+      sheet = sheet.getStylesheetParent();
+    }
+
+    return (StylesheetComposed) sheet;
+  }
+
+  /**
+   * Get the type of the node.  We'll pretend we're a Document.
+   *
+   * @return the type of the node: document node.
+   */
+  public short getNodeType()
+  {
+    return DTM.DOCUMENT_NODE;
+  }
+
+  /**
+   * 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_STYLESHEET;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The node name
+   */
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_STYLESHEET_STRING;
+  }
+
+  /**
+   * Replace an "xsl:template" property.
+   * This is a hook for CompilingStylesheetHandler, to allow
+   * us to access a template, compile it, instantiate it,
+   * and replace the original with the compiled instance.
+   * ADDED 9/5/2000 to support compilation experiment
+   *
+   * @param v Compiled template to replace with
+   * @param i Index of template to be replaced
+   *
+   * @throws TransformerException
+   */
+  public void replaceTemplate(ElemTemplate v, int i) throws TransformerException
+  {
+
+    if (null == m_templates)
+      throw new ArrayIndexOutOfBoundsException();
+
+    replaceChild(v, (ElemTemplateElement)m_templates.elementAt(i));
+    m_templates.setElementAt(v, i);
+    v.setStylesheet(this);
+  }
+  
+    /**
+     * Call the children visitors.
+     * @param visitor The visitor whose appropriate method will be called.
+     */
+    protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+    {
+      int s = getImportCount();
+      for (int j = 0; j < s; j++)
+      {
+      	getImport(j).callVisitors(visitor);
+      }
+   
+      s = getIncludeCount();
+      for (int j = 0; j < s; j++)
+      {
+      	getInclude(j).callVisitors(visitor);
+      }
+
+      s = getOutputCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getOutput(j));
+      }
+
+      // Next, add in the attribute-set elements
+
+      s = getAttributeSetCount();
+      for (int j = 0; j < s; j++)
+      {
+      	ElemAttributeSet attrSet = getAttributeSet(j);
+        if (visitor.visitTopLevelInstruction(attrSet))
+        {
+          attrSet.callChildVisitors(visitor);
+        }
+      }
+      // Now the decimal-formats
+
+      s = getDecimalFormatCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getDecimalFormat(j));
+      }
+
+      // Now the keys
+
+      s = getKeyCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getKey(j));
+      }
+
+      // And the namespace aliases
+
+      s = getNamespaceAliasCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getNamespaceAlias(j));
+      }
+
+      // Next comes the templates
+
+      s = getTemplateCount();
+      for (int j = 0; j < s; j++)
+      {
+        try
+        {
+          ElemTemplate template = getTemplate(j);
+          if (visitor.visitTopLevelInstruction(template))
+          {
+            template.callChildVisitors(visitor);
+          }
+        }
+        catch (TransformerException te)
+        {
+          throw new org.apache.xml.utils.WrappedRuntimeException(te);
+        }
+      }
+
+      // Then, the variables
+
+      s = getVariableOrParamCount();
+      for (int j = 0; j < s; j++)
+      {
+      	ElemVariable var = getVariableOrParam(j);
+        if (visitor.visitTopLevelVariableOrParamDecl(var))
+        {
+          var.callChildVisitors(visitor);
+        }
+      }
+
+      // And lastly the whitespace preserving and stripping elements
+
+      s = getStripSpaceCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getStripSpace(j));
+      }
+
+      s = getPreserveSpaceCount();
+      for (int j = 0; j < s; j++)
+      {
+        visitor.visitTopLevelInstruction(getPreserveSpace(j));
+      }
+      
+      if(null != m_NonXslTopLevel)
+      {
+      	java.util.Enumeration elements = m_NonXslTopLevel.elements();
+      	while(elements.hasMoreElements())
+      	{
+      	  ElemTemplateElement elem = (ElemTemplateElement)elements.nextElement();
+          if (visitor.visitTopLevelInstruction(elem))
+          {
+            elem.callChildVisitors(visitor);
+          }
+      		
+      	}
+      }
+    }
+        
+          
+  /**
+   * Accept a visitor and call the appropriate method 
+   * for this class.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   * @return true if the children of the object should be visited.
+   */
+  protected boolean accept(XSLTVisitor visitor)
+  {
+  	return visitor.visitStylesheet(this);
+  }
+
+  
+}
diff --git a/src/main/java/org/apache/xalan/templates/StylesheetComposed.java b/src/main/java/org/apache/xalan/templates/StylesheetComposed.java
new file mode 100644
index 0000000..595410e
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/StylesheetComposed.java
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StylesheetComposed.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+/**
+ * Represents a stylesheet that has methods that resolve includes and
+ * imports.  It has methods on it that
+ * return "composed" properties, which mean that:
+ * <ol>
+ * <li>Properties that are aggregates, like OutputProperties, will
+ * be composed of properties declared in this stylsheet and all
+ * included stylesheets.</li>
+ * <li>Properties that aren't found, will be searched for first in
+ * the includes, and, if none are located, will be searched for in
+ * the imports.</li>
+ * <li>Properties in that are not atomic on a stylesheet will
+ * have the form getXXXComposed. Some properties, like version and id,
+ * are not inherited, and so won't have getXXXComposed methods.</li>
+ * </ol>
+ * <p>In some cases getXXXComposed methods may calculate the composed
+ * values dynamically, while in other cases they may store the composed
+ * values.</p>
+ */
+public class StylesheetComposed extends Stylesheet
+{
+    static final long serialVersionUID = -3444072247410233923L;
+
+  /**
+   * Uses an XSL stylesheet document.
+   * @param parent  The including or importing stylesheet.
+   */
+  public StylesheetComposed(Stylesheet parent)
+  {
+    super(parent);
+  }
+
+  /**
+   * Tell if this can be cast to a StylesheetComposed, meaning, you
+   * can ask questions from getXXXComposed functions.
+   *
+   * @return True since this is a StylesheetComposed 
+   */
+  public boolean isAggregatedType()
+  {
+    return true;
+  }
+
+  /**
+   * Adds all recomposable values for this precedence level into the recomposableElements Vector
+   * that was passed in as the first parameter.  All elements added to the
+   * recomposableElements vector should extend ElemTemplateElement.
+   * @param recomposableElements a Vector of ElemTemplateElement objects that we will add all of
+   *        our recomposable objects to.
+   */
+  public void recompose(Vector recomposableElements) throws TransformerException
+  {
+
+    //recomposeImports();         // Calculate the number of this import.
+    //recomposeIncludes(this);    // Build the global include list for this stylesheet.
+
+    // Now add in all of the recomposable elements at this precedence level
+
+    int n = getIncludeCountComposed();
+
+    for (int i = -1; i < n; i++)
+    {
+      Stylesheet included = getIncludeComposed(i);
+
+      // Add in the output elements
+
+      int s = included.getOutputCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getOutput(j));
+      }
+
+      // Next, add in the attribute-set elements
+
+      s = included.getAttributeSetCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getAttributeSet(j));
+      }
+
+      // Now the decimal-formats
+
+      s = included.getDecimalFormatCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getDecimalFormat(j));
+      }
+
+      // Now the keys
+
+      s = included.getKeyCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getKey(j));
+      }
+
+      // And the namespace aliases
+
+      s = included.getNamespaceAliasCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getNamespaceAlias(j));
+      }
+
+      // Next comes the templates
+
+      s = included.getTemplateCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getTemplate(j));
+      }
+
+      // Then, the variables
+
+      s = included.getVariableOrParamCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getVariableOrParam(j));
+      }
+
+      // And lastly the whitespace preserving and stripping elements
+
+      s = included.getStripSpaceCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getStripSpace(j));
+      }
+
+      s = included.getPreserveSpaceCount();
+      for (int j = 0; j < s; j++)
+      {
+        recomposableElements.addElement(included.getPreserveSpace(j));
+      }
+    }
+  }
+
+  /** Order in import chain.
+   *  @serial         */
+  private int m_importNumber = -1;
+
+  /** The precedence of this stylesheet in the global import list.
+   *  The lowest precedence stylesheet is 0.  A higher
+   *  number has a higher precedence.
+   *  @serial
+   */
+  private int m_importCountComposed;
+  
+  /* The count of imports composed for this stylesheet */
+  private int m_endImportCountComposed;
+
+  /**
+   * Recalculate the precedence of this stylesheet in the global
+   * import list.  The lowest precedence stylesheet is 0.  A higher
+   * number has a higher precedence.
+   */
+  void recomposeImports()
+  {
+
+    m_importNumber = getStylesheetRoot().getImportNumber(this);
+
+    StylesheetRoot root = getStylesheetRoot();
+    int globalImportCount = root.getGlobalImportCount();
+
+    m_importCountComposed = (globalImportCount - m_importNumber) - 1;
+    
+    // Now get the count of composed imports from this stylesheet's imports
+    int count = getImportCount();
+    if ( count > 0)
+    {
+      m_endImportCountComposed += count;
+      while (count > 0)
+        m_endImportCountComposed += this.getImport(--count).getEndImportCountComposed();
+    }
+    
+    // Now get the count of composed imports from this stylesheet's
+    // composed includes.
+    count = getIncludeCountComposed();
+    while (count>0)
+    {
+      int imports = getIncludeComposed(--count).getImportCount();
+      m_endImportCountComposed += imports;
+      while (imports > 0)
+        m_endImportCountComposed +=getIncludeComposed(count).getImport(--imports).getEndImportCountComposed();
+     
+    }                                                            
+  }
+
+  /**
+   * Get a stylesheet from the "import" list.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @param i Index of stylesheet in import list 
+   *
+   * @return The stylesheet at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public StylesheetComposed getImportComposed(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    StylesheetRoot root = getStylesheetRoot();
+
+    // Get the stylesheet that is offset past this stylesheet.
+    // Thus, if the index of this stylesheet is 3, an argument 
+    // to getImportComposed of 0 will return the 4th stylesheet 
+    // in the global import list.
+    return root.getGlobalImport(1 + m_importNumber + i);
+  }
+
+  /**
+   * Get the precedence of this stylesheet in the global import list.
+   * The lowest precedence is 0.  A higher number has a higher precedence.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @return the precedence of this stylesheet in the global import list.
+   */
+  public int getImportCountComposed()
+  {
+    return m_importCountComposed;
+  }
+  
+  /**
+   * Get the number of import in this stylesheet's composed list.
+   *
+   * @return the number of imports in this stylesheet's composed list.
+   */
+  public int getEndImportCountComposed()
+  {
+    return m_endImportCountComposed;
+  }
+  
+
+  /**
+   * The combined list of includes.
+   * @serial
+   */
+  private transient Vector m_includesComposed;
+
+  /**
+   * Recompose the value of the composed include list.  Builds a composite
+   * list of all stylesheets included by this stylesheet to any depth.
+   *
+   * @param including Stylesheet to recompose
+   */
+  void recomposeIncludes(Stylesheet including)
+  {
+
+    int n = including.getIncludeCount();
+
+    if (n > 0)
+    {
+      if (null == m_includesComposed)
+        m_includesComposed = new Vector();
+
+      for (int i = 0; i < n; i++)
+      {
+        Stylesheet included = including.getInclude(i);
+        m_includesComposed.addElement(included);
+        recomposeIncludes(included);
+      }
+    }
+  }
+
+  /**
+   * Get an "xsl:include" property.
+   * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
+   *
+   * @param i Index of stylesheet in "include" list 
+   *
+   * @return The stylesheet at the given index in the "include" list 
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public Stylesheet getIncludeComposed(int i)
+          throws ArrayIndexOutOfBoundsException
+  {
+
+    if (-1 == i)
+      return this;
+
+    if (null == m_includesComposed)
+      throw new ArrayIndexOutOfBoundsException();
+
+    return (Stylesheet) m_includesComposed.elementAt(i);
+  }
+
+  /**
+   * Get the number of included stylesheets.
+   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
+   *
+   * @return the number of included stylesheets.
+   */
+  public int getIncludeCountComposed()
+  {
+    return (null != m_includesComposed) ? m_includesComposed.size() : 0;
+  }
+
+  /**
+   * For compilation support, we need the option of overwriting
+   * (rather than appending to) previous composition.
+   * We could phase out the old API in favor of this one, but I'm
+   * holding off until we've made up our minds about compilation.
+   * ADDED 9/5/2000 to support compilation experiment.
+   * NOTE: GLP 29-Nov-00 I've left this method in so that CompilingStylesheetHandler will compile.  However,
+   *                     I'm not sure why it's needed or what it does and I've commented out the body.
+   *
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   * @param flushFirst Flag indicating the option of overwriting
+   * (rather than appending to) previous composition.
+   *
+   * @throws TransformerException
+   */
+  public void recomposeTemplates(boolean flushFirst) throws TransformerException
+  {
+/***************************************  KEEP METHOD IN FOR COMPILATION
+    if (flushFirst)
+      m_templateList = new TemplateList(this);
+
+    recomposeTemplates();
+*****************************************/
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/StylesheetRoot.java b/src/main/java/org/apache/xalan/templates/StylesheetRoot.java
new file mode 100644
index 0000000..2cc8935
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/StylesheetRoot.java
@@ -0,0 +1,1405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StylesheetRoot.java 476466 2006-11-18 08:22:31Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.text.DecimalFormatSymbols;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.extensions.ExtensionNamespacesManager;
+import org.apache.xalan.processor.XSLTSchema;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.ref.ExpandedNameTable;
+import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+
+/**
+ * This class represents the root object of the stylesheet tree.
+ * @xsl.usage general
+ */
+public class StylesheetRoot extends StylesheetComposed
+        implements java.io.Serializable, Templates
+{
+    static final long serialVersionUID = 3875353123529147855L;
+    
+    /**
+     * The flag for the setting of the optimize feature;
+     */    
+    private boolean m_optimizer = true;
+
+    /**
+     * The flag for the setting of the incremental feature;
+     */    
+    private boolean m_incremental = false;
+
+    /**
+     * The flag for the setting of the source_location feature;
+     */  
+    private boolean m_source_location = false;
+
+    /**
+     * State of the secure processing feature.
+     */
+    private boolean m_isSecureProcessing = false;
+
+  /**
+   * Uses an XSL stylesheet document.
+   * @throws TransformerConfigurationException if the baseIdentifier can not be resolved to a URL.
+   */
+  public StylesheetRoot(ErrorListener errorListener) throws TransformerConfigurationException
+  {
+
+    super(null);
+
+    setStylesheetRoot(this);
+
+    try
+    {
+      m_selectDefault = new XPath("node()", this, this, XPath.SELECT, errorListener);
+
+      initDefaultRule(errorListener);
+    }
+    catch (TransformerException se)
+    {
+      throw new TransformerConfigurationException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_INIT_DEFAULT_TEMPLATES, null), se); //"Can't init default templates!", se);
+    }
+  }
+
+  /**
+   * The schema used when creating this StylesheetRoot
+   * @serial
+   */
+  private HashMap m_availElems;
+  
+  /**
+   * Creates a StylesheetRoot and retains a pointer to the schema used to create this
+   * StylesheetRoot.  The schema may be needed later for an element-available() function call.
+   * 
+   * @param schema The schema used to create this stylesheet
+   * @throws TransformerConfigurationException if the baseIdentifier can not be resolved to a URL.
+   */
+  public StylesheetRoot(XSLTSchema schema, ErrorListener listener) throws TransformerConfigurationException
+  {
+
+    this(listener);
+    m_availElems = schema.getElemsAvailable();
+  }
+
+  /**
+   * Tell if this is the root of the stylesheet tree.
+   *
+   * @return True since this is the root of the stylesheet tree.
+   */
+  public boolean isRoot()
+  {
+    return true;
+  }
+
+  /**
+   * Set the state of the secure processing feature.
+   */
+  public void setSecureProcessing(boolean flag)
+  {
+    m_isSecureProcessing = flag;
+  }
+  
+  /**
+   * Return the state of the secure processing feature.
+   */
+  public boolean isSecureProcessing()
+  {
+    return m_isSecureProcessing;
+  }
+
+  /**
+   * Get the hashtable of available elements.
+   *
+   * @return table of available elements, keyed by qualified names, and with 
+   * values of the same qualified names.
+   */
+  public HashMap getAvailableElements()
+  {
+    return m_availElems;
+  }
+  
+  private transient ExtensionNamespacesManager m_extNsMgr = null;
+  
+  /**
+   * Only instantiate an ExtensionNamespacesManager if one is called for
+   * (i.e., if the stylesheet contains  extension functions and/or elements).
+   */
+  public ExtensionNamespacesManager getExtensionNamespacesManager()
+  {
+     if (m_extNsMgr == null)
+       m_extNsMgr = new ExtensionNamespacesManager();
+     return m_extNsMgr;
+  }
+  
+  /**
+   * Get the vector of extension namespaces. Used to provide
+   * the extensions table access to a list of extension
+   * namespaces encountered during composition of a stylesheet.
+   */
+  public Vector getExtensions()
+  {
+    return m_extNsMgr != null ? m_extNsMgr.getExtensions() : null;
+  }  
+
+/*
+  public void runtimeInit(TransformerImpl transformer) throws TransformerException
+  {
+    System.out.println("StylesheetRoot.runtimeInit()");
+      
+  //    try{throw new Exception("StylesheetRoot.runtimeInit()");} catch(Exception e){e.printStackTrace();}
+
+    }
+*/  
+
+  //============== Templates Interface ================
+
+  /**
+   * Create a new transformation context for this Templates object.
+   *
+   * @return A Transformer instance, never null.
+   */
+  public Transformer newTransformer()
+  {
+    return new TransformerImpl(this);
+  }
+  
+
+  public Properties getDefaultOutputProps()
+  {
+    return m_outputProperties.getProperties();
+  }
+  
+  /**
+   * Get the static properties for xsl:output.  The object returned will
+   * be a clone of the internal values, and thus it can be mutated
+   * without mutating the Templates object, and then handed in to
+   * the process method.
+   *
+   * <p>For XSLT, Attribute Value Templates attribute values will
+   * be returned unexpanded (since there is no context at this point).</p>
+   *
+   * @return A Properties object, not null.
+   */
+  public Properties getOutputProperties()
+  {    
+    return (Properties)getDefaultOutputProps().clone();
+  }
+
+  //============== End Templates Interface ================
+
+  /**
+   * Recompose the values of all "composed" properties, meaning
+   * properties that need to be combined or calculated from
+   * the combination of imported and included stylesheets.  This
+   * method determines the proper import precedence of all imported
+   * stylesheets.  It then iterates through all of the elements and 
+   * properties in the proper order and triggers the individual recompose
+   * methods.
+   *
+   * @throws TransformerException
+   */
+  public void recompose() throws TransformerException
+  {
+    // Now we make a Vector that is going to hold all of the recomposable elements
+
+      Vector recomposableElements = new Vector();
+
+    // First, we build the global import tree.
+
+    if (null == m_globalImportList)
+    {
+
+      Vector importList = new Vector();
+
+      addImports(this, true, importList);            
+
+      // Now we create an array and reverse the order of the importList vector.
+      // We built the importList vector backwards so that we could use addElement
+      // to append to the end of the vector instead of constantly pushing new
+      // stylesheets onto the front of the vector and having to shift the rest
+      // of the vector each time.
+
+      m_globalImportList = new StylesheetComposed[importList.size()];
+
+      for (int i =  0, j= importList.size() -1; i < importList.size(); i++)
+      {  
+        m_globalImportList[j] = (StylesheetComposed) importList.elementAt(i);
+        // Build the global include list for this stylesheet.
+        // This needs to be done ahead of the recomposeImports
+        // because we need the info from the composed includes. 
+        m_globalImportList[j].recomposeIncludes(m_globalImportList[j]);
+        // Calculate the number of this import.    
+        m_globalImportList[j--].recomposeImports();        
+      }
+    }    
+    // Next, we walk the import tree and add all of the recomposable elements to the vector.
+    int n = getGlobalImportCount();
+
+    for (int i = 0; i < n; i++)
+    {
+      StylesheetComposed imported = getGlobalImport(i);
+      imported.recompose(recomposableElements);
+    }
+
+    // We sort the elements into ascending order.
+
+    QuickSort2(recomposableElements, 0, recomposableElements.size() - 1);
+
+    // We set up the global variables that will hold the recomposed information.
+
+
+    m_outputProperties = new OutputProperties(org.apache.xml.serializer.Method.UNKNOWN);
+//  m_outputProperties = new OutputProperties(Method.XML);
+    
+    m_attrSets = new HashMap();
+    m_decimalFormatSymbols = new Hashtable();
+    m_keyDecls = new Vector();
+    m_namespaceAliasComposed = new Hashtable();
+    m_templateList = new TemplateList();
+    m_variables = new Vector();
+
+    // Now we sequence through the sorted elements, 
+    // calling the recompose() function on each one.  This will call back into the
+    // appropriate routine here to actually do the recomposition.
+    // Note that we're going backwards, encountering the highest precedence items first.
+    for (int i = recomposableElements.size() - 1; i >= 0; i--)
+      ((ElemTemplateElement) recomposableElements.elementAt(i)).recompose(this);
+    
+/*
+ * Backing out REE again, as it seems to cause some new failures
+ * which need to be investigated. -is
+ */      
+    // This has to be done before the initialization of the compose state, because 
+    // eleminateRedundentGlobals will add variables to the m_variables vector, which 
+    // it then copied in the ComposeState constructor.
+    
+//    if(true && org.apache.xalan.processor.TransformerFactoryImpl.m_optimize)
+//    {
+//          RedundentExprEliminator ree = new RedundentExprEliminator();
+//          callVisitors(ree);
+//          ree.eleminateRedundentGlobals(this);
+//    }
+          
+    initComposeState();
+
+    // Need final composition of TemplateList.  This adds the wild cards onto the chains.
+    m_templateList.compose(this);
+    
+    // Need to clear check for properties at the same import level.
+    m_outputProperties.compose(this);
+    m_outputProperties.endCompose(this);
+    
+    // Now call the compose() method on every element to give it a chance to adjust
+    // based on composed values.
+    
+    n = getGlobalImportCount();
+
+    for (int i = 0; i < n; i++)
+    {
+      StylesheetComposed imported = this.getGlobalImport(i);
+      int includedCount = imported.getIncludeCountComposed();
+      for (int j = -1; j < includedCount; j++)
+      {
+        Stylesheet included = imported.getIncludeComposed(j);
+        composeTemplates(included);
+      }
+    }
+    // Attempt to register any remaining unregistered extension namespaces.
+    if (m_extNsMgr != null)
+      m_extNsMgr.registerUnregisteredNamespaces();
+
+    clearComposeState();
+  }
+
+  /**
+   * Call the compose function for each ElemTemplateElement.
+   *
+   * @param templ non-null reference to template element that will have 
+   * the composed method called on it, and will have it's children's composed 
+   * methods called.
+   */
+  void composeTemplates(ElemTemplateElement templ) throws TransformerException
+  {
+
+    templ.compose(this);
+
+    for (ElemTemplateElement child = templ.getFirstChildElem();
+            child != null; child = child.getNextSiblingElem())
+    {
+      composeTemplates(child);
+    }
+    
+    templ.endCompose(this);
+  }
+
+  /**
+   * The combined list of imports.  The stylesheet with the highest
+   * import precedence will be at element 0.  The one with the lowest
+   * import precedence will be at element length - 1.
+   * @serial
+   */
+  private StylesheetComposed[] m_globalImportList;
+
+  /**
+   * Add the imports in the given sheet to the working importList vector.
+   * The will be added from highest import precedence to
+   * least import precedence.  This is a post-order traversal of the
+   * import tree as described in <a href="http://www.w3.org/TR/xslt.html#import">the
+   * XSLT Recommendation</a>.
+   * <p>For example, suppose</p>
+   * <p>stylesheet A imports stylesheets B and C in that order;</p>
+   * <p>stylesheet B imports stylesheet D;</p>
+   * <p>stylesheet C imports stylesheet E.</p>
+   * <p>Then the order of import precedence (highest first) is
+   * A, C, E, B, D.</p>
+   *
+   * @param stylesheet Stylesheet to examine for imports.
+   * @param addToList  <code>true</code> if this template should be added to the import list
+   * @param importList The working import list.  Templates are added here in the reverse
+   *        order of priority.  When we're all done, we'll reverse this to the correct
+   *        priority in an array.
+   */
+  protected void addImports(Stylesheet stylesheet, boolean addToList, Vector importList)
+  {
+
+    // Get the direct imports of this sheet.
+
+    int n = stylesheet.getImportCount();
+
+    if (n > 0)
+    {
+      for (int i = 0; i < n; i++)
+      {
+        Stylesheet imported = stylesheet.getImport(i);
+
+        addImports(imported, true, importList);
+      }
+    }
+
+    n = stylesheet.getIncludeCount();
+
+    if (n > 0)
+    {
+      for (int i = 0; i < n; i++)
+      {
+        Stylesheet included = stylesheet.getInclude(i);
+
+        addImports(included, false, importList);
+      }
+    }
+
+    if (addToList)
+      importList.addElement(stylesheet);
+
+  }
+
+  /**
+   * Get a stylesheet from the global import list. 
+   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH COUNT.
+   * 
+   * @param i Index of stylesheet to get from global import list 
+   *
+   * @return The stylesheet at the given index 
+   */
+  public StylesheetComposed getGlobalImport(int i)
+  {
+    return m_globalImportList[i];
+  }
+
+  /**
+   * Get the total number of imports in the global import list.
+   * 
+   * @return The total number of imported stylesheets, including
+   * the root stylesheet, thus the number will always be 1 or
+   * greater.
+   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH DESCRIPTION.
+   */
+  public int getGlobalImportCount()
+  {
+          return (m_globalImportList!=null)
+                        ? m_globalImportList.length 
+                          : 1;
+  }
+
+  /**
+   * Given a stylesheet, return the number of the stylesheet
+   * in the global import list.
+   * @param sheet The stylesheet which will be located in the
+   * global import list.
+   * @return The index into the global import list of the given stylesheet,
+   * or -1 if it is not found (which should never happen).
+   */
+  public int getImportNumber(StylesheetComposed sheet)
+  {
+
+    if (this == sheet)
+      return 0;
+
+    int n = getGlobalImportCount();
+
+    for (int i = 0; i < n; i++)
+    {
+      if (sheet == getGlobalImport(i))
+        return i;
+    }
+
+    return -1;
+  }
+
+  /**
+   * This will be set up with the default values, and then the values
+   * will be set as stylesheets are encountered.
+   * @serial
+   */
+  private OutputProperties m_outputProperties;
+
+  /**
+   * Recompose the output format object from the included elements.
+   *
+   * @param oprops non-null reference to xsl:output properties representation.
+   */
+  void recomposeOutput(OutputProperties oprops)
+    throws TransformerException
+  {
+    
+    m_outputProperties.copyFrom(oprops);
+  }
+
+  /**
+   * Get the combined "xsl:output" property with the properties
+   * combined from the included stylesheets.  If a xsl:output
+   * is not declared in this stylesheet or an included stylesheet,
+   * look in the imports.
+   * Please note that this returns a reference to the OutputProperties
+   * object, not a cloned object, like getOutputProperties does.
+   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
+   *
+   * @return non-null reference to composed output properties object.
+   */
+  public OutputProperties getOutputComposed()
+  {
+
+    // System.out.println("getOutputComposed.getIndent: "+m_outputProperties.getIndent());
+    // System.out.println("getOutputComposed.getIndenting: "+m_outputProperties.getIndenting());
+    return m_outputProperties;
+  }
+
+  /** Flag indicating whether an output method has been set by the user.
+   *  @serial           */
+  private boolean m_outputMethodSet = false;
+
+  /**
+   * Find out if an output method has been set by the user.
+   *
+   * @return Value indicating whether an output method has been set by the user
+   * @xsl.usage internal
+   */
+  public boolean isOutputMethodSet()
+  {
+    return m_outputMethodSet;
+  }
+
+  /**
+   * Composed set of all included and imported attribute set properties.
+   * Each entry is a vector of ElemAttributeSet objects.
+   * @serial
+   */
+  private HashMap m_attrSets;
+
+  /**
+   * Recompose the attribute-set declarations.
+   *
+   * @param attrSet An attribute-set to add to the hashtable of attribute sets.
+   */
+  void recomposeAttributeSets(ElemAttributeSet attrSet)
+  {
+    ArrayList attrSetList = (ArrayList) m_attrSets.get(attrSet.getName());
+
+    if (null == attrSetList)
+    {
+      attrSetList = new ArrayList();
+
+      m_attrSets.put(attrSet.getName(), attrSetList);
+    }
+
+    attrSetList.add(attrSet);
+  }
+
+  /**
+   * Get a list "xsl:attribute-set" properties that match the qname.
+   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
+   *
+   * @param name Qualified name of attribute set properties to get
+   *
+   * @return A vector of attribute sets matching the given name
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   */
+  public ArrayList getAttributeSetComposed(QName name)
+          throws ArrayIndexOutOfBoundsException
+  {
+    return (ArrayList) m_attrSets.get(name);
+  }
+
+  /**
+   * Table of DecimalFormatSymbols, keyed by QName.
+   * @serial
+   */
+  private Hashtable m_decimalFormatSymbols;
+
+  /**
+   * Recompose the decimal-format declarations.
+   *
+   * @param dfp A DecimalFormatProperties to add to the hashtable of decimal formats.
+   */
+  void recomposeDecimalFormats(DecimalFormatProperties dfp)
+  {
+    DecimalFormatSymbols oldDfs =
+                  (DecimalFormatSymbols) m_decimalFormatSymbols.get(dfp.getName());
+    if (null == oldDfs)
+    {
+      m_decimalFormatSymbols.put(dfp.getName(), dfp.getDecimalFormatSymbols());
+    }
+    else if (!dfp.getDecimalFormatSymbols().equals(oldDfs))
+    {
+      String themsg;
+      if (dfp.getName().equals(new QName("")))
+      {
+        // "Only one default xsl:decimal-format declaration is allowed."
+        themsg = XSLMessages.createWarning(
+                          XSLTErrorResources.WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED,
+                          new Object[0]);
+      }
+      else
+      {
+        // "xsl:decimal-format names must be unique. Name {0} has been duplicated."
+        themsg = XSLMessages.createWarning(
+                          XSLTErrorResources.WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE,
+                          new Object[] {dfp.getName()});
+      }
+
+      error(themsg);   // Should we throw TransformerException instead?
+    }
+
+  }
+
+  /**
+   * Given a valid element decimal-format name, return the
+   * decimalFormatSymbols with that name.
+   * <p>It is an error to declare either the default decimal-format or
+   * a decimal-format with a given name more than once (even with
+   * different import precedence), unless it is declared every
+   * time with the same value for all attributes (taking into
+   * account any default values).</p>
+   * <p>Which means, as far as I can tell, the decimal-format
+   * properties are not additive.</p>
+   *
+   * @param name Qualified name of the decimal format to find 
+   * @return DecimalFormatSymbols object matching the given name or
+   * null if name is not found.
+   */
+  public DecimalFormatSymbols getDecimalFormatComposed(QName name)
+  {
+    return (DecimalFormatSymbols) m_decimalFormatSymbols.get(name);
+  }
+
+  /**
+   * A list of all key declarations visible from this stylesheet and all
+   * lesser stylesheets.
+   * @serial
+   */
+  private Vector m_keyDecls;
+
+  /**
+   * Recompose the key declarations.
+   *
+   * @param keyDecl A KeyDeclaration to be added to the vector of key declarations.
+   */
+  void recomposeKeys(KeyDeclaration keyDecl)
+  {
+    m_keyDecls.addElement(keyDecl);
+  }
+
+  /**
+   * Get the composed "xsl:key" properties.
+   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
+   *
+   * @return A vector of the composed "xsl:key" properties.
+   */
+  public Vector getKeysComposed()
+  {
+    return m_keyDecls;
+  }
+
+  /**
+   * Composed set of all namespace aliases.
+   * @serial
+   */
+  private Hashtable m_namespaceAliasComposed;
+
+  /**
+   * Recompose the namespace-alias declarations.
+   *
+   * @param nsAlias A NamespaceAlias object to add to the hashtable of namespace aliases.
+   */
+  void recomposeNamespaceAliases(NamespaceAlias nsAlias)
+  {
+    m_namespaceAliasComposed.put(nsAlias.getStylesheetNamespace(),
+                                 nsAlias);
+  }
+
+  /**
+   * Get the "xsl:namespace-alias" property.
+   * Return the NamespaceAlias for a given namespace uri.
+   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
+   *
+   * @param uri non-null reference to namespace that is to be aliased.
+   *
+   * @return NamespaceAlias that matches uri, or null if no match.
+   */
+  public NamespaceAlias getNamespaceAliasComposed(String uri)
+  {
+    return (NamespaceAlias) ((null == m_namespaceAliasComposed) 
+                    ? null : m_namespaceAliasComposed.get(uri));
+  }
+
+  /**
+   * The "xsl:template" properties.
+   * @serial
+   */
+  private TemplateList m_templateList;
+
+  /**
+   * Recompose the template declarations.
+   *
+   * @param template An ElemTemplate object to add to the template list.
+   */
+  void recomposeTemplates(ElemTemplate template)
+  {
+    m_templateList.setTemplate(template);
+  }
+
+  /**
+   * Accessor method to retrieve the <code>TemplateList</code> associated with
+   * this StylesheetRoot.
+   * 
+   * @return The composed <code>TemplateList</code>.
+   */
+  public final TemplateList getTemplateListComposed()
+  {
+    return m_templateList;
+  }
+
+  /**
+   * Mutator method to set the <code>TemplateList</code> associated with this
+   * StylesheetRoot.  This method should only be used by the compiler.  Normally,
+   * the template list is built during the recompose process and should not be
+   * altered by the user.
+   * @param templateList The new <code>TemplateList</code> for this StylesheetRoot.
+   */
+  public final void setTemplateListComposed(TemplateList templateList)
+  {
+    m_templateList = templateList;
+  }
+
+  /**
+   * Get an "xsl:template" property by node match. This looks in the imports as
+   * well as this stylesheet.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @param xctxt non-null reference to XPath runtime execution context.
+   * @param targetNode non-null reference of node that the template must match.
+   * @param mode qualified name of the node, or null.
+   * @param quietConflictWarnings true if conflict warnings should not be reported.
+   *
+   * @return reference to ElemTemplate that is the best match for targetNode, or 
+   *         null if no match could be made.
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplateComposed(XPathContext xctxt,
+                                          int targetNode,
+                                          QName mode,
+                                          boolean quietConflictWarnings,
+                                          DTM dtm)
+            throws TransformerException
+  {
+    return m_templateList.getTemplate(xctxt, targetNode, mode, 
+                                      quietConflictWarnings,
+                                      dtm);
+  }
+  
+  /**
+   * Get an "xsl:template" property by node match. This looks in the imports as
+   * well as this stylesheet.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @param xctxt non-null reference to XPath runtime execution context.
+   * @param targetNode non-null reference of node that the template must match.
+   * @param mode qualified name of the node, or null.
+   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
+   *        if we should consider all import levels.  This is used by apply-imports to
+   *        access templates that have been overridden.
+   * @param endImportLevel The count of composed imports
+   * @param quietConflictWarnings true if conflict warnings should not be reported.
+   *
+   * @return reference to ElemTemplate that is the best match for targetNode, or 
+   *         null if no match could be made.
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplateComposed(XPathContext xctxt,
+                                          int targetNode,
+                                          QName mode,
+                                          int maxImportLevel, int endImportLevel,
+                                          boolean quietConflictWarnings,
+                                          DTM dtm)
+            throws TransformerException
+  {
+    return m_templateList.getTemplate(xctxt, targetNode, mode, 
+                                      maxImportLevel, endImportLevel,
+                                      quietConflictWarnings,
+                                      dtm);
+  }
+
+  /**
+   * Get an "xsl:template" property. This looks in the imports as
+   * well as this stylesheet.
+   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
+   *
+   * @param qname non-null reference to qualified name of template.
+   *
+   * @return reference to named template, or null if not found.
+   */
+  public ElemTemplate getTemplateComposed(QName qname)
+  {
+    return m_templateList.getTemplate(qname);
+  }
+  
+  /**
+   * Composed set of all variables and params.
+   * @serial
+   */
+  private Vector m_variables;
+
+  /**
+   * Recompose the top level variable and parameter declarations.
+   *
+   * @param elemVar A top level variable or parameter to be added to the Vector.
+   */
+  void recomposeVariables(ElemVariable elemVar)
+  {
+    // Don't overide higher priority variable        
+    if (getVariableOrParamComposed(elemVar.getName()) == null)
+    {
+      elemVar.setIsTopLevel(true);        // Mark as a top-level variable or param
+      elemVar.setIndex(m_variables.size());
+      m_variables.addElement(elemVar);
+    }
+  }
+
+  /**
+   * Get an "xsl:variable" property.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @param qname Qualified name of variable or param
+   *
+   * @return The ElemVariable with the given qualified name
+   */
+  public ElemVariable getVariableOrParamComposed(QName qname)
+  {
+    if (null != m_variables)
+    {
+      int n = m_variables.size();
+
+      for (int i = 0; i < n; i++)
+      {
+        ElemVariable var = (ElemVariable)m_variables.elementAt(i);
+        if(var.getName().equals(qname))
+          return var;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Get all global "xsl:variable" properties in scope for this stylesheet.
+   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
+   *
+   * @return Vector of all variables and params in scope
+   */
+  public Vector getVariablesAndParamsComposed()
+  {
+    return m_variables;
+  }
+
+  /**
+   * A list of properties that specify how to do space
+   * stripping. This uses the same exact mechanism as Templates.
+   * @serial
+   */
+  private TemplateList m_whiteSpaceInfoList;
+
+  /**
+   * Recompose the strip-space and preserve-space declarations.
+   *
+   * @param wsi A WhiteSpaceInfo element to add to the list of WhiteSpaceInfo elements.
+   */
+  void recomposeWhiteSpaceInfo(WhiteSpaceInfo wsi)
+  {
+    if (null == m_whiteSpaceInfoList)
+      m_whiteSpaceInfoList = new TemplateList();
+
+    m_whiteSpaceInfoList.setTemplate(wsi);
+  }
+
+  /**
+   * Check to see if the caller should bother with check for
+   * whitespace nodes.
+   *
+   * @return Whether the caller should bother with check for
+   * whitespace nodes.
+   */
+  public boolean shouldCheckWhitespace()
+  {
+    return null != m_whiteSpaceInfoList;
+  }
+
+  /**
+   * Get information about whether or not an element should strip whitespace.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param support The XPath runtime state.
+   * @param targetElement Element to check
+   *
+   * @return WhiteSpaceInfo for the given element
+   *
+   * @throws TransformerException
+   */
+  public WhiteSpaceInfo getWhiteSpaceInfo(
+          XPathContext support, int targetElement, DTM dtm) throws TransformerException
+  {
+
+    if (null != m_whiteSpaceInfoList)
+      return (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
+              targetElement, null, false, dtm);
+    else
+      return null;
+  }
+  
+  /**
+   * Get information about whether or not an element should strip whitespace.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param support The XPath runtime state.
+   * @param targetElement Element to check
+   *
+   * @return true if the whitespace should be stripped.
+   *
+   * @throws TransformerException
+   */
+  public boolean shouldStripWhiteSpace(
+          XPathContext support, int targetElement) throws TransformerException
+  {
+    if (null != m_whiteSpaceInfoList)
+    {
+      while(DTM.NULL != targetElement)
+      {
+        DTM dtm = support.getDTM(targetElement);
+        WhiteSpaceInfo info = (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
+                targetElement, null, false, dtm);
+        if(null != info)
+          return info.getShouldStripSpace();
+        
+        int parent = dtm.getParent(targetElement);
+        if(DTM.NULL != parent && DTM.ELEMENT_NODE == dtm.getNodeType(parent))
+          targetElement = parent;
+        else
+          targetElement = DTM.NULL;
+      }
+    }
+    return false;
+  }
+  
+  /**
+   * Get information about whether or not whitespace can be stripped.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @return true if the whitespace can be stripped.
+   */
+  public boolean canStripWhiteSpace()
+  {
+    return (null != m_whiteSpaceInfoList);
+  }
+  
+
+
+  /**
+   * The default template to use for text nodes if we don't find
+   * anything else.  This is initialized in initDefaultRule().
+   * @serial
+   * @xsl.usage advanced
+   */
+  private ElemTemplate m_defaultTextRule;
+
+  /**
+   * Get the default template for text.
+   *
+   * @return the default template for text.
+   * @xsl.usage advanced
+   */
+  public final ElemTemplate getDefaultTextRule()
+  {
+    return m_defaultTextRule;
+  }
+
+  /**
+   * The default template to use if we don't find anything
+   * else.  This is initialized in initDefaultRule().
+   * @serial
+   * @xsl.usage advanced
+   */
+  private ElemTemplate m_defaultRule;
+
+  /**
+   * Get the default template for elements.
+   *
+   * @return the default template for elements.
+   * @xsl.usage advanced
+   */
+  public final ElemTemplate getDefaultRule()
+  {
+    return m_defaultRule;
+  }
+
+  /**
+   * The default template to use for the root if we don't find
+   * anything else.  This is initialized in initDefaultRule().
+   * We kind of need this because the defaultRule isn't good
+   * enough because it doesn't supply a document context.
+   * For now, I default the root document element to "HTML".
+   * Don't know if this is really a good idea or not.
+   * I suspect it is not.
+   * @serial
+   * @xsl.usage advanced
+   */
+  private ElemTemplate m_defaultRootRule;
+
+  /**
+   * Get the default template for a root node.
+   *
+   * @return The default template for a root node.
+   * @xsl.usage advanced
+   */
+  public final ElemTemplate getDefaultRootRule()
+  {
+    return m_defaultRootRule;
+  }
+  
+  /**
+   * The start rule to kick off the transformation.
+   * @serial
+   * @xsl.usage advanced
+   */
+  private ElemTemplate m_startRule;
+
+  /**
+   * Get the default template for a root node.
+   *
+   * @return The default template for a root node.
+   * @xsl.usage advanced
+   */
+  public final ElemTemplate getStartRule()
+  {
+    return m_startRule;
+  }
+
+
+  /**
+   * Used for default selection.
+   * @serial
+   */
+  XPath m_selectDefault;
+
+  /**
+   * Create the default rule if needed.
+   *
+   * @throws TransformerException
+   */
+  private void initDefaultRule(ErrorListener errorListener) throws TransformerException
+  {
+
+    // Then manufacture a default
+    m_defaultRule = new ElemTemplate();
+
+    m_defaultRule.setStylesheet(this);
+
+    XPath defMatch = new XPath("*", this, this, XPath.MATCH, errorListener);
+
+    m_defaultRule.setMatch(defMatch);
+
+    ElemApplyTemplates childrenElement = new ElemApplyTemplates();
+
+    childrenElement.setIsDefaultTemplate(true);
+    childrenElement.setSelect(m_selectDefault);
+    m_defaultRule.appendChild(childrenElement);
+    
+    m_startRule = m_defaultRule;
+
+    // -----------------------------
+    m_defaultTextRule = new ElemTemplate();
+
+    m_defaultTextRule.setStylesheet(this);
+
+    defMatch = new XPath("text() | @*", this, this, XPath.MATCH, errorListener);
+
+    m_defaultTextRule.setMatch(defMatch);
+
+    ElemValueOf elemValueOf = new ElemValueOf();
+
+    m_defaultTextRule.appendChild(elemValueOf);
+
+    XPath selectPattern = new XPath(".", this, this, XPath.SELECT, errorListener);
+
+    elemValueOf.setSelect(selectPattern);
+
+    //--------------------------------
+    m_defaultRootRule = new ElemTemplate();
+
+    m_defaultRootRule.setStylesheet(this);
+
+    defMatch = new XPath("/", this, this, XPath.MATCH, errorListener);
+
+    m_defaultRootRule.setMatch(defMatch);
+
+    childrenElement = new ElemApplyTemplates();
+
+    childrenElement.setIsDefaultTemplate(true);
+    m_defaultRootRule.appendChild(childrenElement);
+    childrenElement.setSelect(m_selectDefault);
+  }
+
+  /**
+   * This is a generic version of C.A.R Hoare's Quick Sort
+   * algorithm.  This will handle arrays that are already
+   * sorted, and arrays with duplicate keys.  It was lifted from
+   * the NodeSorter class but should probably be eliminated and replaced
+   * with a call to Collections.sort when we migrate to Java2.<BR>
+   *
+   * If you think of a one dimensional array as going from
+   * the lowest index on the left to the highest index on the right
+   * then the parameters to this function are lowest index or
+   * left and highest index or right.  The first time you call
+   * this function it will be with the parameters 0, a.length - 1.
+   *
+   * @param v       a vector of ElemTemplateElement elements 
+   * @param lo0     left boundary of partition
+   * @param hi0     right boundary of partition
+   *
+   */
+
+  private void QuickSort2(Vector v, int lo0, int hi0)
+    {
+      int lo = lo0;
+      int hi = hi0;
+
+      if ( hi0 > lo0)
+      {
+        // Arbitrarily establishing partition element as the midpoint of
+        // the array.
+        ElemTemplateElement midNode = (ElemTemplateElement) v.elementAt( ( lo0 + hi0 ) / 2 );
+
+        // loop through the array until indices cross
+        while( lo <= hi )
+        {
+          // find the first element that is greater than or equal to
+          // the partition element starting from the left Index.
+          while( (lo < hi0) && (((ElemTemplateElement) v.elementAt(lo)).compareTo(midNode) < 0) )
+          {
+            ++lo;
+          } // end while
+
+          // find an element that is smaller than or equal to
+          // the partition element starting from the right Index.
+          while( (hi > lo0) && (((ElemTemplateElement) v.elementAt(hi)).compareTo(midNode) > 0) )          {
+            --hi;
+          }
+
+          // if the indexes have not crossed, swap
+          if( lo <= hi )
+          {
+            ElemTemplateElement node = (ElemTemplateElement) v.elementAt(lo);
+            v.setElementAt(v.elementAt(hi), lo);
+            v.setElementAt(node, hi);
+
+            ++lo;
+            --hi;
+          }
+        }
+
+        // If the right index has not reached the left side of array
+        // must now sort the left partition.
+        if( lo0 < hi )
+        {
+          QuickSort2( v, lo0, hi );
+        }
+
+        // If the left index has not reached the right side of array
+        // must now sort the right partition.
+        if( lo < hi0 )
+        {
+          QuickSort2( v, lo, hi0 );
+        }
+      }
+    } // end QuickSort2  */
+    
+    private transient ComposeState m_composeState;
+    
+    /**
+     * Initialize a new ComposeState.
+     */
+    void initComposeState()
+    {
+      m_composeState = new ComposeState();
+    }
+
+    /**
+     * Return class to track state global state during the compose() operation.
+     * @return ComposeState reference, or null if endCompose has been called.
+     */
+    ComposeState getComposeState()
+    {
+      return m_composeState;
+    }
+    
+    /**
+     * Clear the compose state.
+     */
+    private void clearComposeState()
+    {
+      m_composeState = null;
+    }
+
+    private String m_extensionHandlerClass = 
+        "org.apache.xalan.extensions.ExtensionHandlerExsltFunction";
+    
+    /**
+     * This internal method allows the setting of the java class
+     * to handle the extension function (if other than the default one).
+     * 
+     * @xsl.usage internal
+     */
+    public String setExtensionHandlerClass(String handlerClassName) {
+        String oldvalue = m_extensionHandlerClass;
+        m_extensionHandlerClass = handlerClassName;
+        return oldvalue;
+    } 
+    /**
+     * 
+     * @xsl.usage internal
+     */
+    public String getExtensionHandlerClass() {
+        return m_extensionHandlerClass;
+    }
+        
+    /**
+     * Class to track state global state during the compose() operation.
+     */
+    class ComposeState
+    {
+      ComposeState()
+      {
+        int size = m_variables.size();
+        for (int i = 0; i < size; i++) 
+        {
+          ElemVariable ev = (ElemVariable)m_variables.elementAt(i);
+          m_variableNames.addElement(ev.getName());
+        }
+        
+      }
+      
+      private ExpandedNameTable m_ent = new ExpandedNameTable();
+      
+      /**
+       * Given a qualified name, return an integer ID that can be 
+       * quickly compared.
+       *
+       * @param qname a qualified name object, must not be null.
+       *
+       * @return the expanded-name id of the qualified name.
+       */
+      public int getQNameID(QName qname)
+      {
+        
+        return m_ent.getExpandedTypeID(qname.getNamespace(), 
+                                       qname.getLocalName(),
+                                       // The type doesn't matter for our 
+                                       // purposes. 
+                                       org.apache.xml.dtm.DTM.ELEMENT_NODE);
+      }
+      
+      /**
+       * A Vector of the current params and QNames within the current template.
+       * Set by ElemTemplate and used by ProcessorVariable.
+       */
+      private java.util.Vector m_variableNames = new java.util.Vector();
+            
+      /**
+       * Add the name of a qualified name within the template.  The position in 
+       * the vector is its ID.
+       * @param qname A qualified name of a param or variable, should be non-null.
+       * @return the index where the variable was added.
+       */
+      int addVariableName(final org.apache.xml.utils.QName qname)
+      {
+        int pos = m_variableNames.size();
+        m_variableNames.addElement(qname);
+        int frameSize = m_variableNames.size() - getGlobalsSize();
+        if(frameSize > m_maxStackFrameSize)
+          m_maxStackFrameSize++;
+        return pos;
+      }
+      
+      void resetStackFrameSize()
+      {
+        m_maxStackFrameSize = 0;
+      }
+      
+      int getFrameSize()
+      {
+        return m_maxStackFrameSize;
+      }
+      
+      /**
+       * Get the current size of the stack frame.  Use this to record the position 
+       * in a template element at startElement, so that it can be popped 
+       * at endElement.
+       */
+      int getCurrentStackFrameSize()
+      {
+        return m_variableNames.size();
+      }
+      
+      /**
+       * Set the current size of the stack frame.
+       */
+      void setCurrentStackFrameSize(int sz)
+      {
+        m_variableNames.setSize(sz);
+      }
+      
+      int getGlobalsSize()
+      {
+        return m_variables.size();
+      }
+      
+      IntStack m_marks = new IntStack();
+      
+      void pushStackMark()
+      {
+        m_marks.push(getCurrentStackFrameSize());
+      }
+      
+      void popStackMark()
+      {
+        int mark = m_marks.pop();
+        setCurrentStackFrameSize(mark);
+      }
+      
+      /**
+       * Get the Vector of the current params and QNames to be collected 
+       * within the current template.
+       * @return A reference to the vector of variable names.  The reference 
+       * returned is owned by this class, and so should not really be mutated, or 
+       * stored anywhere.
+       */
+      java.util.Vector getVariableNames()
+      {
+        return m_variableNames;
+      }
+      
+      private int m_maxStackFrameSize;
+
+    }
+    
+    /**
+     * @return Optimization flag
+     */
+    public boolean getOptimizer() {
+        return m_optimizer;
+    }
+
+    /**
+     * @param b Optimization flag
+     */
+    public void setOptimizer(boolean b) {
+        m_optimizer = b;
+    }
+
+    /**
+     * @return Incremental flag
+     */
+    public boolean getIncremental() {
+        return m_incremental;
+    }
+
+    /**
+     * @return source location flag
+     */
+    public boolean getSource_location() {
+        return m_source_location;
+    }
+
+    /**
+     * @param b Incremental flag
+     */
+    public void setIncremental(boolean b) {
+        m_incremental = b;
+    }
+
+    /**
+     * @param b Source location flag
+     */
+    public void setSource_location(boolean b) {
+        m_source_location = b;
+    }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/TemplateList.java b/src/main/java/org/apache/xalan/templates/TemplateList.java
new file mode 100644
index 0000000..90c3169
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/TemplateList.java
@@ -0,0 +1,923 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TemplateList.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.PsuedoNames;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.patterns.StepPattern;
+import org.apache.xpath.patterns.UnionPattern;
+
+/**
+ * Encapsulates a template list, and helps locate individual templates.
+ * @xsl.usage advanced
+ */
+public class TemplateList implements java.io.Serializable
+{
+    static final long serialVersionUID = 5803675288911728791L;
+
+  /**
+   * Construct a TemplateList object. Needs to be public so it can
+   * be invoked from the CompilingStylesheetHandler.
+   */
+  public TemplateList()
+  {
+    super();
+  }
+
+  /**
+   * Add a template to the table of named templates and/or the table of templates
+   * with match patterns.  This routine should
+   * be called in decreasing order of precedence but it checks nonetheless.
+   *
+   * @param template
+   */
+  public void setTemplate(ElemTemplate template)
+  {
+    XPath matchXPath = template.getMatch();
+    
+    if (null == template.getName() && null == matchXPath)
+    {  
+      template.error(XSLTErrorResources.ER_NEED_NAME_OR_MATCH_ATTRIB,
+          new Object[]{ "xsl:template" });
+    }
+    
+    if (null != template.getName())
+    {
+      ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName());
+      if (null == existingTemplate)
+      {
+        m_namedTemplates.put(template.getName(), template);
+      }
+      else
+      {
+        int existingPrecedence =
+                        existingTemplate.getStylesheetComposed().getImportCountComposed();
+        int newPrecedence = template.getStylesheetComposed().getImportCountComposed();
+        if (newPrecedence > existingPrecedence)
+        {
+          // This should never happen
+          m_namedTemplates.put(template.getName(), template);
+        }
+        else if (newPrecedence == existingPrecedence)
+          template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE,
+                       new Object[]{ template.getName() });
+      }
+    }
+
+    
+
+    if (null != matchXPath)
+    {
+      Expression matchExpr = matchXPath.getExpression();
+
+      if (matchExpr instanceof StepPattern)
+      {
+        insertPatternInTable((StepPattern) matchExpr, template);
+      }
+      else if (matchExpr instanceof UnionPattern)
+      {
+        UnionPattern upat = (UnionPattern) matchExpr;
+        StepPattern[] pats = upat.getPatterns();
+        int n = pats.length;
+
+        for (int i = 0; i < n; i++)
+        {
+          insertPatternInTable(pats[i], template);
+        }
+      }
+      else
+      {
+
+        // TODO: assert error
+      }
+    }
+  }
+
+  /** Flag to indicate whether in DEBUG mode          */
+  final static boolean DEBUG = false;
+
+  /**
+   * Dump all patterns and elements that match those patterns
+   *
+   */
+  void dumpAssociationTables()
+  {
+
+    Enumeration associations = m_patternTable.elements();
+
+    while (associations.hasMoreElements())
+    {
+      TemplateSubPatternAssociation head =
+        (TemplateSubPatternAssociation) associations.nextElement();
+
+      while (null != head)
+      {
+        System.out.print("(" + head.getTargetString() + ", "
+                         + head.getPattern() + ")");
+
+        head = head.getNext();
+      }
+
+      System.out.println("\n.....");
+    }
+
+    TemplateSubPatternAssociation head = m_wildCardPatterns;
+
+    System.out.print("wild card list: ");
+
+    while (null != head)
+    {
+      System.out.print("(" + head.getTargetString() + ", "
+                       + head.getPattern() + ")");
+
+      head = head.getNext();
+    }
+
+    System.out.println("\n.....");
+  }
+
+  /**
+   * After all templates have been added, this function
+   * should be called.
+   */
+  public void compose(StylesheetRoot sroot)
+  {
+
+    if (DEBUG)
+    {
+      System.out.println("Before wildcard insert...");
+      dumpAssociationTables();
+    }
+
+    if (null != m_wildCardPatterns)
+    {
+      Enumeration associations = m_patternTable.elements();
+
+      while (associations.hasMoreElements())
+      {
+        TemplateSubPatternAssociation head =
+          (TemplateSubPatternAssociation) associations.nextElement();
+        TemplateSubPatternAssociation wild = m_wildCardPatterns;
+
+        while (null != wild)
+        {
+          try
+          {
+            head = insertAssociationIntoList(
+              head, (TemplateSubPatternAssociation) wild.clone(), true);
+          }
+          catch (CloneNotSupportedException cnse){}
+
+          wild = wild.getNext();
+        }
+      }
+    }
+
+    if (DEBUG)
+    {
+      System.out.println("After wildcard insert...");
+      dumpAssociationTables();
+    }
+  }
+
+  /**
+   * Insert the given TemplateSubPatternAssociation into the the linked
+   * list.  Sort by import precedence, then priority, then by document order.
+   *
+   * @param head The first TemplateSubPatternAssociation in the linked list.
+   * @param item The item that we want to insert into the proper place.
+   * @param isWildCardInsert <code>true</code> if we are inserting a wild card 
+   *             template onto this list.
+   * @return the new head of the list.
+   */
+  private TemplateSubPatternAssociation
+              insertAssociationIntoList(TemplateSubPatternAssociation head,
+                                         TemplateSubPatternAssociation item,
+                                         boolean isWildCardInsert)
+  {
+
+    // Sort first by import level (higher level is at front),
+    // then by priority (highest priority is at front),
+    // then by document order (later in document is at front).
+
+    double priority = getPriorityOrScore(item);
+    double workPriority;
+    int importLevel = item.getImportLevel();
+    int docOrder = item.getDocOrderPos();
+    TemplateSubPatternAssociation insertPoint = head;
+    TemplateSubPatternAssociation next;
+    boolean insertBefore;         // true means insert before insertPoint; otherwise after
+                                  // This can only be true if insertPoint is pointing to
+                                  // the first or last template.
+
+    // Spin down so that insertPoint points to:
+    // (a) the template immediately _before_ the first template on the chain with
+    // a precedence that is either (i) less than ours or (ii) the same as ours but
+    // the template document position is less than ours
+    // -or-
+    // (b) the last template on the chain if no such template described in (a) exists.
+    // If we are pointing to the first template or the last template (that is, case b),
+    // we need to determine whether to insert before or after the template.  Otherwise,
+    // we always insert after the insertPoint.
+
+    while (true)
+    {
+      next = insertPoint.getNext();
+      if (null == next)
+        break;
+      else
+      {
+        workPriority = getPriorityOrScore(next);
+        if (importLevel > next.getImportLevel())
+          break;
+        else if (importLevel < next.getImportLevel())
+          insertPoint = next;
+        else if (priority > workPriority)               // import precedence is equal
+          break;
+        else if (priority < workPriority)
+          insertPoint = next;
+        else if (docOrder >= next.getDocOrderPos())     // priorities, import are equal
+          break;
+        else
+          insertPoint = next;
+      }
+    }
+
+    if ( (null == next) || (insertPoint == head) )      // insert point is first or last
+    {
+      workPriority = getPriorityOrScore(insertPoint);
+      if (importLevel > insertPoint.getImportLevel())
+        insertBefore = true;
+      else if (importLevel < insertPoint.getImportLevel())
+        insertBefore = false;
+      else if (priority > workPriority)
+        insertBefore = true;
+      else if (priority < workPriority)
+        insertBefore = false;
+      else if (docOrder >= insertPoint.getDocOrderPos())
+        insertBefore = true;
+      else
+        insertBefore = false;
+    }
+    else
+      insertBefore = false;
+
+    // System.out.println("appending: "+target+" to "+matchPat.getPattern());
+    
+    if (isWildCardInsert)
+    {
+      if (insertBefore)
+      {
+        item.setNext(insertPoint);
+
+        String key = insertPoint.getTargetString();
+
+        item.setTargetString(key);
+        putHead(key, item);
+        return item;
+      }
+      else
+      {
+        item.setNext(next);
+        insertPoint.setNext(item);
+        return head;
+      }
+    }
+    else
+    {
+      if (insertBefore)
+      {
+        item.setNext(insertPoint);
+
+        if (insertPoint.isWild() || item.isWild())
+          m_wildCardPatterns = item;
+        else
+          putHead(item.getTargetString(), item);
+        return item;
+      }
+      else
+      {
+        item.setNext(next);
+        insertPoint.setNext(item);
+        return head;
+      }
+    }
+  }
+
+  /**
+   * Add a template to the template list.
+   *
+   * @param pattern
+   * @param template
+   */
+  private void insertPatternInTable(StepPattern pattern, ElemTemplate template)
+  {
+
+    String target = pattern.getTargetString();
+
+    if (null != target)
+    {
+      String pstring = template.getMatch().getPatternString();
+      TemplateSubPatternAssociation association =
+        new TemplateSubPatternAssociation(template, pattern, pstring);
+
+      // See if there's already one there
+      boolean isWildCard = association.isWild();
+      TemplateSubPatternAssociation head = isWildCard
+                                           ? m_wildCardPatterns
+                                           : getHead(target);
+
+      if (null == head)
+      {
+        if (isWildCard)
+          m_wildCardPatterns = association;
+        else
+          putHead(target, association);
+      }
+      else
+      {
+        insertAssociationIntoList(head, association, false);
+      }
+    }
+  }
+
+  /**
+   * Given a match pattern and template association, return the 
+   * score of that match.  This score or priority can always be 
+   * statically calculated.
+   *
+   * @param matchPat The match pattern to template association.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST}, 
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE}, 
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD}, 
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}, or 
+   *         the value defined by the priority attribute of the template.
+   *
+   */
+  private double getPriorityOrScore(TemplateSubPatternAssociation matchPat)
+  {
+
+    double priority = matchPat.getTemplate().getPriority();
+
+    if (priority == XPath.MATCH_SCORE_NONE)
+    {
+      Expression ex = matchPat.getStepPattern();
+
+      if (ex instanceof NodeTest)
+      {
+        return ((NodeTest) ex).getDefaultScore();
+      }
+    }
+
+    return priority;
+  }
+
+  /**
+   * Locate a named template.
+   *
+   * @param qname  Qualified name of the template.
+   *
+   * @return Template argument with the requested name, or null if not found.
+   */
+  public ElemTemplate getTemplate(QName qname)
+  {
+    return (ElemTemplate) m_namedTemplates.get(qname);
+  }
+
+  /**
+   * Get the head of the most likely list of associations to check, based on 
+   * the name and type of the targetNode argument.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param targetNode The target node that will be checked for a match.
+   * @param dtm The dtm owner for the target node.
+   *
+   * @return The head of a linked list that contains all possible match pattern to 
+   * template associations.
+   */
+  public TemplateSubPatternAssociation getHead(XPathContext xctxt, 
+                                               int targetNode, DTM dtm)
+  {
+    short targetNodeType = dtm.getNodeType(targetNode);
+    TemplateSubPatternAssociation head;
+
+    switch (targetNodeType)
+    {
+    case DTM.ELEMENT_NODE :
+    case DTM.ATTRIBUTE_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getLocalName(targetNode));
+      break;
+    case DTM.TEXT_NODE :
+    case DTM.CDATA_SECTION_NODE :
+      head = m_textPatterns;
+      break;
+    case DTM.ENTITY_REFERENCE_NODE :
+    case DTM.ENTITY_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
+      break;
+    case DTM.PROCESSING_INSTRUCTION_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getLocalName(targetNode));
+      break;
+    case DTM.COMMENT_NODE :
+      head = m_commentPatterns;
+      break;
+    case DTM.DOCUMENT_NODE :
+    case DTM.DOCUMENT_FRAGMENT_NODE :
+      head = m_docPatterns;
+      break;
+    case DTM.NOTATION_NODE :
+    default :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
+    }
+
+    return (null == head) ? m_wildCardPatterns : head;
+  }
+  
+  /**
+   * Given a target element, find the template that best
+   * matches in the given XSL document, according
+   * to the rules specified in the xsl draft.  This variation of getTemplate 
+   * assumes the current node and current expression node have already been 
+   * pushed. 
+   *
+   * @param xctxt
+   * @param targetNode
+   * @param mode A string indicating the display mode.
+   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
+   *        if we should consider all import levels.  This is used by apply-imports to
+   *        access templates that have been overridden.
+   * @param quietConflictWarnings
+   * @return Rule that best matches targetElem.
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplateFast(XPathContext xctxt,
+                                int targetNode,
+                                int expTypeID,
+                                QName mode,
+                                int maxImportLevel,
+                                boolean quietConflictWarnings,
+                                DTM dtm)
+            throws TransformerException
+  {
+    
+    TemplateSubPatternAssociation head;
+
+    switch (dtm.getNodeType(targetNode))
+    {
+    case DTM.ELEMENT_NODE :
+    case DTM.ATTRIBUTE_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getLocalNameFromExpandedNameID(expTypeID));
+      break;
+    case DTM.TEXT_NODE :
+    case DTM.CDATA_SECTION_NODE :
+      head = m_textPatterns;
+      break;
+    case DTM.ENTITY_REFERENCE_NODE :
+    case DTM.ENTITY_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
+      break;
+    case DTM.PROCESSING_INSTRUCTION_NODE :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getLocalName(targetNode));
+      break;
+    case DTM.COMMENT_NODE :
+      head = m_commentPatterns;
+      break;
+    case DTM.DOCUMENT_NODE :
+    case DTM.DOCUMENT_FRAGMENT_NODE :
+      head = m_docPatterns;
+      break;
+    case DTM.NOTATION_NODE :
+    default :
+      head = (TemplateSubPatternAssociation) m_patternTable.get(
+        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
+    }
+
+    if(null == head)
+    {
+      head = m_wildCardPatterns;
+      if(null == head)
+        return null;
+    }                                              
+
+    // XSLT functions, such as xsl:key, need to be able to get to 
+    // current ElemTemplateElement via a cast to the prefix resolver.
+    // Setting this fixes bug idkey03.
+    xctxt.pushNamespaceContextNull();
+    try
+    {
+      do
+      {
+        if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel) )
+        {
+          continue;
+        }
+        ElemTemplate template = head.getTemplate();        
+        xctxt.setNamespaceContext(template);
+        
+        if ((head.m_stepPattern.execute(xctxt, targetNode, dtm, expTypeID) != NodeTest.SCORE_NONE)
+                && head.matchMode(mode))
+        {
+          if (quietConflictWarnings)
+            checkConflicts(head, xctxt, targetNode, mode);
+
+          return template;
+        }
+      }
+      while (null != (head = head.getNext()));
+    }
+    finally
+    {
+      xctxt.popNamespaceContext();
+    }
+
+    return null;
+  }  // end findTemplate
+
+  /**
+   * Given a target element, find the template that best
+   * matches in the given XSL document, according
+   * to the rules specified in the xsl draft.
+   *
+   * @param xctxt
+   * @param targetNode
+   * @param mode A string indicating the display mode.
+   * @param quietConflictWarnings
+   * @return Rule that best matches targetElem.
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplate(XPathContext xctxt,
+                                int targetNode,
+                                QName mode,
+                                boolean quietConflictWarnings,
+                                DTM dtm)
+            throws TransformerException
+  {
+
+    TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm);
+
+    if (null != head)
+    {
+      // XSLT functions, such as xsl:key, need to be able to get to 
+      // current ElemTemplateElement via a cast to the prefix resolver.
+      // Setting this fixes bug idkey03.
+      xctxt.pushNamespaceContextNull();
+      xctxt.pushCurrentNodeAndExpression(targetNode, targetNode);
+      try
+      {
+        do
+        {
+          ElemTemplate template = head.getTemplate();        
+          xctxt.setNamespaceContext(template);
+          
+          if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
+                  && head.matchMode(mode))
+          {
+            if (quietConflictWarnings)
+              checkConflicts(head, xctxt, targetNode, mode);
+
+            return template;
+          }
+        }
+        while (null != (head = head.getNext()));
+      }
+      finally
+      {
+        xctxt.popCurrentNodeAndExpression();
+        xctxt.popNamespaceContext();
+      }
+    }
+
+    return null;
+  }  // end findTemplate
+  
+  /**
+   * Given a target element, find the template that best
+   * matches in the given XSL document, according
+   * to the rules specified in the xsl draft.
+   *
+   * @param xctxt
+   * @param targetNode
+   * @param mode A string indicating the display mode.
+   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
+   *        if we should consider all import levels.  This is used by apply-imports to
+   *        access templates that have been overridden.
+   * @param endImportLevel The count of composed imports
+   * @param quietConflictWarnings
+   * @return Rule that best matches targetElem.
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   */
+  public ElemTemplate getTemplate(XPathContext xctxt,
+                                int targetNode,
+                                QName mode,
+                                int maxImportLevel, int endImportLevel,
+                                boolean quietConflictWarnings,
+                                DTM dtm)
+            throws TransformerException
+  {
+
+    TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm);
+
+    if (null != head)
+    {
+      // XSLT functions, such as xsl:key, need to be able to get to 
+      // current ElemTemplateElement via a cast to the prefix resolver.
+      // Setting this fixes bug idkey03.
+      xctxt.pushNamespaceContextNull();
+      xctxt.pushCurrentNodeAndExpression(targetNode, targetNode);
+      try
+      {
+        do
+        {
+          if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel))
+          {
+            continue;
+          }
+          if (head.getImportLevel()<= maxImportLevel - endImportLevel)
+            return null;
+          ElemTemplate template = head.getTemplate();        
+          xctxt.setNamespaceContext(template);
+          
+          if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
+                  && head.matchMode(mode))
+          {
+            if (quietConflictWarnings)
+              checkConflicts(head, xctxt, targetNode, mode);
+
+            return template;
+          }
+        }
+        while (null != (head = head.getNext()));
+      }
+      finally
+      {
+        xctxt.popCurrentNodeAndExpression();
+        xctxt.popNamespaceContext();
+      }
+    }
+
+    return null;
+  }  // end findTemplate
+
+  /**
+   * Get a TemplateWalker for use by a compiler.  See the documentation for
+   * the TreeWalker inner class for further details.
+   */
+  public TemplateWalker getWalker()
+  {
+    return new TemplateWalker();
+  }
+
+  /**
+   * Check for match conflicts, and warn the stylesheet author.
+   *
+   * @param head Template pattern
+   * @param xctxt Current XPath context
+   * @param targetNode Node matching the pattern
+   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
+   */
+  private void checkConflicts(TemplateSubPatternAssociation head,
+                              XPathContext xctxt, int targetNode, QName mode)
+  {
+
+    // TODO: Check for conflicts.
+  }
+
+  /**
+   * Add object to vector if not already there.
+   *
+   * @param obj
+   * @param v
+   */
+  private void addObjectIfNotFound(Object obj, Vector v)
+  {
+
+    int n = v.size();
+    boolean addIt = true;
+
+    for (int i = 0; i < n; i++)
+    {
+      if (v.elementAt(i) == obj)
+      {
+        addIt = false;
+
+        break;
+      }
+    }
+
+    if (addIt)
+    {
+      v.addElement(obj);
+    }
+  }
+
+  /**
+   * Keyed on string macro names, and holding values
+   * that are macro elements in the XSL DOM tree.
+   * Initialized in initMacroLookupTable, and used in
+   * findNamedTemplate.
+   * @serial
+   */
+  private Hashtable m_namedTemplates = new Hashtable(89);
+
+  /**
+   * This table is keyed on the target elements
+   * of patterns, and contains linked lists of
+   * the actual patterns that match the target element
+   * to some degree of specifity.
+   * @serial
+   */
+  private Hashtable m_patternTable = new Hashtable(89);
+
+  /** Wildcard patterns.
+   *  @serial          */
+  private TemplateSubPatternAssociation m_wildCardPatterns = null;
+
+  /** Text Patterns.
+   *  @serial          */
+  private TemplateSubPatternAssociation m_textPatterns = null;
+
+  /** Root document Patterns.
+   *  @serial          */
+  private TemplateSubPatternAssociation m_docPatterns = null;
+
+  /** Comment Patterns.
+   *  @serial          */
+  private TemplateSubPatternAssociation m_commentPatterns = null;
+
+  /**
+   * Get table of named Templates.
+   * These are keyed on template names, and holding values
+   * that are template elements.
+   *
+   * @return A Hashtable dictionary that contains {@link java.lang.String}s 
+   * as the keys, and {@link org.apache.xalan.templates.ElemTemplate}s as the 
+   * values. 
+   */
+  private Hashtable getNamedTemplates()
+  {
+    return m_namedTemplates;
+  }
+
+  /**
+   * Set table of named Templates.
+   * These are keyed on string macro names, and holding values
+   * that are template elements in the XSL DOM tree.
+   *
+   * @param v Hashtable dictionary that contains {@link java.lang.String}s 
+   * as the keys, and {@link org.apache.xalan.templates.ElemTemplate}s as the 
+   * values.
+   */
+  private void setNamedTemplates(Hashtable v)
+  {
+    m_namedTemplates = v;
+  }
+
+  /**
+   * Get the head of the assocation list that is keyed by target.
+   *
+   * @param key The name of a node. 
+   *
+   * @return The head of a linked list that contains all possible match pattern to 
+   * template associations for the given key.
+   */
+  private TemplateSubPatternAssociation getHead(String key)
+  {
+    return (TemplateSubPatternAssociation) m_patternTable.get(key);
+  }
+
+  /**
+   * Get the head of the assocation list that is keyed by target.
+   *
+   * @param key
+   * @param assoc
+   */
+  private void putHead(String key, TemplateSubPatternAssociation assoc)
+  {
+
+    if (key.equals(PsuedoNames.PSEUDONAME_TEXT))
+      m_textPatterns = assoc;
+    else if (key.equals(PsuedoNames.PSEUDONAME_ROOT))
+      m_docPatterns = assoc;
+    else if (key.equals(PsuedoNames.PSEUDONAME_COMMENT))
+      m_commentPatterns = assoc;
+
+    m_patternTable.put(key, assoc);
+  }
+
+  /**
+   * An inner class used by a compiler to iterate over all of the ElemTemplates
+   * stored in this TemplateList.  The compiler can replace returned templates
+   * with their compiled equivalent.
+   */
+  public class TemplateWalker
+  {
+    private Enumeration hashIterator;
+    private boolean inPatterns;
+    private TemplateSubPatternAssociation curPattern;
+
+    private Hashtable m_compilerCache = new Hashtable();
+
+    private TemplateWalker()
+    {
+      hashIterator = m_patternTable.elements();
+      inPatterns = true;
+      curPattern = null;
+    }
+
+    public ElemTemplate next()
+    {
+
+      ElemTemplate retValue = null;
+      ElemTemplate ct;
+
+      while (true)
+      {
+        if (inPatterns)
+        {
+          if (null != curPattern)
+            curPattern = curPattern.getNext();
+
+          if (null != curPattern)
+            retValue = curPattern.getTemplate();
+          else
+          {
+            if (hashIterator.hasMoreElements())
+            {
+              curPattern = (TemplateSubPatternAssociation) hashIterator.nextElement();
+              retValue =  curPattern.getTemplate();
+            }
+            else
+            {
+              inPatterns = false;
+              hashIterator = m_namedTemplates.elements();
+            }
+          }
+        }
+
+        if (!inPatterns)
+        {
+          if (hashIterator.hasMoreElements())
+            retValue = (ElemTemplate) hashIterator.nextElement();
+          else
+            return null;
+        }
+
+        ct = (ElemTemplate) m_compilerCache.get(new Integer(retValue.getUid()));
+        if (null == ct)
+        {
+          m_compilerCache.put(new Integer(retValue.getUid()), retValue);
+          return retValue;
+        }
+      }
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/TemplateSubPatternAssociation.java b/src/main/java/org/apache/xalan/templates/TemplateSubPatternAssociation.java
new file mode 100644
index 0000000..40477aa
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/TemplateSubPatternAssociation.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TemplateSubPatternAssociation.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.io.Serializable;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.patterns.StepPattern;
+
+/**
+ * A class to contain a match pattern and it's corresponding template.
+ * This class also defines a node in a match pattern linked list.
+ */
+class TemplateSubPatternAssociation implements Serializable, Cloneable
+{
+    static final long serialVersionUID = -8902606755229903350L;
+
+  /** Step pattern           */
+  StepPattern m_stepPattern;
+
+  /** Template pattern          */
+  private String m_pattern;
+
+  /** The template element         */
+  private ElemTemplate m_template;
+
+  /** Next pattern         */
+  private TemplateSubPatternAssociation m_next = null;
+
+  /** Flag indicating whether this is wild card pattern          */
+  private boolean m_wild;
+
+  /** Target string for this match pattern           */
+  private String m_targetString;
+
+  /**
+   * Construct a match pattern from a pattern and template.
+   * @param template The node that contains the template for this pattern.
+   * @param pattern An executable XSLT StepPattern.
+   * @param pat For now a Nodelist that contains old-style element patterns.
+   */
+  TemplateSubPatternAssociation(ElemTemplate template, StepPattern pattern, String pat)
+  {
+
+    m_pattern = pat;
+    m_template = template;
+    m_stepPattern = pattern;
+    m_targetString = m_stepPattern.getTargetString();
+    m_wild = m_targetString.equals("*");
+  }
+
+  /**
+   * Clone this object.
+   *
+   * @return The cloned object.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    TemplateSubPatternAssociation tspa =
+      (TemplateSubPatternAssociation) super.clone();
+
+    tspa.m_next = null;
+
+    return tspa;
+  }
+
+  /**
+   * Get the target string of the pattern.  For instance, if the pattern is
+   * "foo/baz/boo[@daba]", this string will be "boo".
+   *
+   * @return The "target" string.
+   */
+  public final String getTargetString()
+  {
+    return m_targetString;
+  }
+
+  /**
+   * Set Target String for this template pattern  
+   *
+   *
+   * @param key Target string to set
+   */
+  public void setTargetString(String key)
+  {
+    m_targetString = key;
+  }
+
+  /**
+   * Tell if two modes match according to the rules of XSLT.
+   *
+   * @param m1 mode to match
+   *
+   * @return True if the given mode matches this template's mode
+   */
+  boolean matchMode(QName m1)
+  {
+    return matchModes(m1, m_template.getMode());
+  }
+
+  /**
+   * Tell if two modes match according to the rules of XSLT.
+   *
+   * @param m1 First mode to match
+   * @param m2 Second mode to match
+   *
+   * @return True if the two given modes match
+   */
+  private boolean matchModes(QName m1, QName m2)
+  {
+    return (((null == m1) && (null == m2))
+            || ((null != m1) && (null != m2) && m1.equals(m2)));
+  }
+
+  /**
+   * Return the mode associated with the template.
+   *
+   *
+   * @param xctxt XPath context to use with this template
+   * @param targetNode Target node
+   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
+   * @return The mode associated with the template.
+   *
+   * @throws TransformerException
+   */
+  public boolean matches(XPathContext xctxt, int targetNode, QName mode)
+          throws TransformerException
+  {
+
+    double score = m_stepPattern.getMatchScore(xctxt, targetNode);
+
+    return (XPath.MATCH_SCORE_NONE != score)
+           && matchModes(mode, m_template.getMode());
+  }
+
+  /**
+   * Tell if the pattern for this association is a wildcard.
+   *
+   * @return true if this pattern is considered to be a wild match.
+   */
+  public final boolean isWild()
+  {
+    return m_wild;
+  }
+
+  /**
+   * Get associated XSLT StepPattern.
+   *
+   * @return An executable StepPattern object, never null.
+   *
+   */
+  public final StepPattern getStepPattern()
+  {
+    return m_stepPattern;
+  }
+
+  /**
+   * Get the pattern string for diagnostic purposes.
+   *
+   * @return The pattern string for diagnostic purposes.
+   *
+   */
+  public final String getPattern()
+  {
+    return m_pattern;
+  }
+
+  /**
+   * Return the position of the template in document
+   * order in the stylesheet.
+   *
+   * @return The position of the template in the overall template order.
+   */
+  public int getDocOrderPos()
+  {
+    return m_template.getUid();
+  }
+
+  /**
+   * Return the import level associated with the stylesheet into which  
+   * this template is composed.
+   *
+   * @return The import level of this template.
+   */
+  public final int getImportLevel()
+  {
+    return m_template.getStylesheetComposed().getImportCountComposed();
+  }
+
+  /**
+   * Get the assocated xsl:template.
+   *
+   * @return An ElemTemplate, never null.
+   *
+   */
+  public final ElemTemplate getTemplate()
+  {
+    return m_template;
+  }
+
+  /**
+   * Get the next association.
+   *
+   * @return A valid TemplateSubPatternAssociation, or null.
+   */
+  public final TemplateSubPatternAssociation getNext()
+  {
+    return m_next;
+  }
+
+  /**
+   * Set the next element on this association
+   * list, which should be equal or less in priority to
+   * this association, and, if equal priority, should occur
+   * before this template in document order.
+   *
+   * @param mp The next association to score if this one fails.
+   *
+   */
+  public void setNext(TemplateSubPatternAssociation mp)
+  {
+    m_next = mp;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/VarNameCollector.java b/src/main/java/org/apache/xalan/templates/VarNameCollector.java
new file mode 100644
index 0000000..c9842fc
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/VarNameCollector.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: VarNameCollector.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import org.apache.xml.utils.QName;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * This class visits variable refs in an XPath and collects their QNames.
+ */
+public class VarNameCollector extends XPathVisitor
+{
+	Vector m_refs = new Vector();
+	
+	/**
+	 * Reset the list for a fresh visitation and collection.
+	 */
+	public void reset()
+	{
+		m_refs.removeAllElements(); //.clear();
+	}
+	
+	/**
+	 * Get the number of variable references that were collected.
+	 * @return the size of the list.
+	 */
+	public int getVarCount()
+	{
+		return m_refs.size();
+	}
+	
+	/**
+	 * Tell if the given qualified name occurs in 
+	 * the list of qualified names collected.
+	 * 
+	 * @param refName Must be a valid qualified name.
+	 * @return true if the list contains the qualified name.
+	 */
+	boolean doesOccur(QName refName)
+	{
+		return m_refs.contains(refName);
+	}
+
+	/**
+	 * Visit a variable reference.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param var The variable reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitVariableRef(ExpressionOwner owner, Variable var)
+	{
+		m_refs.addElement(var.getQName());
+		return true;
+	}
+
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/WhiteSpaceInfo.java b/src/main/java/org/apache/xalan/templates/WhiteSpaceInfo.java
new file mode 100644
index 0000000..5bf45b7
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/WhiteSpaceInfo.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WhiteSpaceInfo.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xpath.XPath;
+
+/**
+ * This is used as a special "fake" template that can be
+ * handled by the TemplateList to do pattern matching
+ * on nodes.
+ */
+public class WhiteSpaceInfo extends ElemTemplate
+{
+    static final long serialVersionUID = 6389208261999943836L;
+
+  /** Flag indicating whether whitespaces should be stripped.
+   *  @serial        */
+  private boolean m_shouldStripSpace;
+
+  /**
+   * Return true if this element specifies that the node that
+   * matches the match pattern should be stripped, otherwise
+   * the space should be preserved.
+   *
+   * @return value of m_shouldStripSpace flag
+   */
+  public boolean getShouldStripSpace()
+  {
+    return m_shouldStripSpace;
+  }
+  
+  /**
+   * Constructor WhiteSpaceInfo
+   * @param thisSheet The current stylesheet
+   */
+  public WhiteSpaceInfo(Stylesheet thisSheet)
+  {
+  	setStylesheet(thisSheet);
+  }
+
+
+  /**
+   * Constructor WhiteSpaceInfo
+   *
+   *
+   * @param matchPattern Match pattern
+   * @param shouldStripSpace Flag indicating whether or not
+   * to strip whitespaces
+   * @param thisSheet The current stylesheet
+   */
+  public WhiteSpaceInfo(XPath matchPattern, boolean shouldStripSpace, Stylesheet thisSheet)
+  {
+
+    m_shouldStripSpace = shouldStripSpace;
+
+    setMatch(matchPattern);
+
+    setStylesheet(thisSheet);
+  }
+
+  /**
+   * This function is called to recompose() all of the WhiteSpaceInfo elements.
+   */
+  public void recompose(StylesheetRoot root)
+  {
+    root.recomposeWhiteSpaceInfo(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/XMLNSDecl.java b/src/main/java/org/apache/xalan/templates/XMLNSDecl.java
new file mode 100644
index 0000000..4bc1523
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/XMLNSDecl.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLNSDecl.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+/**
+ * Represents an xmlns declaration
+ */
+public class XMLNSDecl
+        implements java.io.Serializable // 20001009 jkess
+{
+    static final long serialVersionUID = 6710237366877605097L;
+
+  /**
+   * Constructor XMLNSDecl
+   *
+   * @param prefix non-null reference to prefix, using "" for default namespace.
+   * @param uri non-null reference to namespace URI.
+   * @param isExcluded true if this namespace declaration should normally be excluded.
+   */
+  public XMLNSDecl(String prefix, String uri, boolean isExcluded)
+  {
+
+    m_prefix = prefix;
+    m_uri = uri;
+    m_isExcluded = isExcluded;
+  }
+
+  /** non-null reference to prefix, using "" for default namespace.
+   *  @serial */
+  private String m_prefix;
+
+  /**
+   * Return the prefix.
+   * @return The prefix that is associated with this URI, or null
+   * if the XMLNSDecl is declaring the default namespace.
+   */
+  public String getPrefix()
+  {
+    return m_prefix;
+  }
+
+  /** non-null reference to namespace URI.
+   *  @serial  */
+  private String m_uri;
+
+  /**
+   * Return the URI.
+   * @return The URI that is associated with this declaration.
+   */
+  public String getURI()
+  {
+    return m_uri;
+  }
+
+  /** true if this namespace declaration should normally be excluded.
+   *  @serial  */
+  private boolean m_isExcluded;
+
+  /**
+   * Tell if this declaration should be excluded from the
+   * result namespace.
+   *
+   * @return true if this namespace declaration should normally be excluded.
+   */
+  public boolean getIsExcluded()
+  {
+    return m_isExcluded;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/templates/XSLTVisitable.java b/src/main/java/org/apache/xalan/templates/XSLTVisitable.java
new file mode 100644
index 0000000..a35a6e1
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/XSLTVisitable.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTVisitable.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+/**
+ * A class that implements this interface will call a XSLTVisitor 
+ * for itself and members within it's heararchy.  If the XSLTVistor's 
+ * method returns false, the sub-member heararchy will not be 
+ * traversed.
+ */
+public interface XSLTVisitable
+{
+	/**
+	 * This will traverse the heararchy, calling the visitor for 
+	 * each member.  If the called visitor method returns 
+	 * false, the subtree should not be called.
+	 * 
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callVisitors(XSLTVisitor visitor);
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/XSLTVisitor.java b/src/main/java/org/apache/xalan/templates/XSLTVisitor.java
new file mode 100644
index 0000000..cb68f1f
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/XSLTVisitor.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLTVisitor.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * A derivation from this class can be passed to a class that implements 
+ * the XSLTVisitable interface, to have the appropriate method called 
+ * for each component of an XSLT stylesheet.  Aside from possible other uses,
+ * the main intention is to provide a reasonable means to perform expression 
+ * rewriting.
+ */
+public class XSLTVisitor extends XPathVisitor
+{
+	/**
+	 * Visit an XSLT instruction.  Any element that isn't called by one 
+	 * of the other visit methods, will be called by this method.
+	 * 
+	 * @param elem The xsl instruction element object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitInstruction(ElemTemplateElement elem)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit an XSLT stylesheet instruction.
+	 * 
+	 * @param elem The xsl instruction element object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitStylesheet(ElemTemplateElement elem)
+	{
+		return true;
+	}
+
+	
+	/**
+	 * Visit an XSLT top-level instruction.
+	 * 
+	 * @param elem The xsl instruction element object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitTopLevelInstruction(ElemTemplateElement elem)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit an XSLT top-level instruction.
+	 * 
+	 * @param elem The xsl instruction element object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitTopLevelVariableOrParamDecl(ElemTemplateElement elem)
+	{
+		return true;
+	}
+
+	
+	/**
+	 * Visit an XSLT variable or parameter declaration.
+	 * 
+	 * @param elem The xsl instruction element object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitVariableOrParamDecl(ElemVariable elem)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a LiteralResultElement.
+	 * 
+	 * @param elem The literal result object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitLiteralResultElement(ElemLiteralResult elem)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit an Attribute Value Template (at the top level).
+	 * 
+	 * @param elem The attribute value template object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitAVT(AVT elem)
+	{
+		return true;
+	}
+
+
+	/**
+	 * Visit an extension element.
+	 * @param elem The extension object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitExtensionElement(ElemExtensionCall elem)
+	{
+		return true;
+	}
+
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/XUnresolvedVariable.java b/src/main/java/org/apache/xalan/templates/XUnresolvedVariable.java
new file mode 100644
index 0000000..e821c80
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/XUnresolvedVariable.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XUnresolvedVariable.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * An instance of this class holds unto a variable until 
+ * it is executed.  It is used at this time for global 
+ * variables which must (we think) forward reference.
+ */
+public class XUnresolvedVariable extends XObject
+{  
+    static final long serialVersionUID = -256779804767950188L;
+  /** The node context for execution. */
+  transient private int m_context;
+  
+  /** The transformer context for execution. */
+  transient private TransformerImpl m_transformer;
+  
+  /** An index to the point in the variable stack where we should
+   * begin variable searches for evaluation of expressions.
+   * This is -1 if m_isTopLevel is false. 
+   **/
+  transient private int m_varStackPos = -1;
+
+  /** An index into the variable stack where the variable context 
+   * ends, i.e. at the point we should terminate the search. 
+   **/
+  transient private int m_varStackContext;
+  
+  /** true if this variable or parameter is a global.
+   *  @serial */
+  private boolean m_isGlobal;
+  
+  /** true if this variable or parameter is not currently being evaluated. */
+  transient private boolean m_doneEval = true;
+  
+  /**
+   * Create an XUnresolvedVariable, that may be executed at a later time.
+   * This is primarily used so that forward referencing works with 
+   * global variables.  An XUnresolvedVariable is initially pushed 
+   * into the global variable stack, and then replaced with the real 
+   * thing when it is accessed.
+   *
+   * @param obj Must be a non-null reference to an ElemVariable.
+   * @param sourceNode The node context for execution.
+   * @param transformer The transformer execution context.
+   * @param varStackPos An index to the point in the variable stack where we should
+   * begin variable searches for evaluation of expressions.
+   * @param varStackContext An index into the variable stack where the variable context 
+   * ends, i.e. at the point we should terminate the search.
+   * @param isGlobal true if this is a global variable.
+   */
+  public XUnresolvedVariable(ElemVariable obj, int sourceNode, 
+                             TransformerImpl transformer,
+                             int varStackPos, int varStackContext,
+                             boolean isGlobal)
+  {
+    super(obj);
+    m_context = sourceNode;
+    m_transformer = transformer;
+    
+    // For globals, this value will have to be updated once we 
+    // have determined how many global variables have been pushed.
+    m_varStackPos = varStackPos;
+    
+    // For globals, this should zero.
+    m_varStackContext = varStackContext;
+    
+    m_isGlobal = isGlobal;
+  }
+    
+  /**
+   * For support of literal objects in xpaths.
+   *
+   * @param xctxt The XPath execution context.
+   *
+   * @return This object.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    if (!m_doneEval) 
+    {
+      this.m_transformer.getMsgMgr().error      
+        (xctxt.getSAXLocator(), XSLTErrorResources.ER_REFERENCING_ITSELF, 
+          new Object[]{((ElemVariable)this.object()).getName().getLocalName()}); 
+    }
+    VariableStack vars = xctxt.getVarStack();
+    
+    // These three statements need to be combined into one operation.
+    int currentFrame = vars.getStackFrame();
+    //// vars.setStackFrame(m_varStackPos);
+   
+
+    ElemVariable velem = (ElemVariable)m_obj;
+    try
+    {
+      m_doneEval = false;
+      if(-1 != velem.m_frameSize)
+      	vars.link(velem.m_frameSize);
+      XObject var = velem.getValue(m_transformer, m_context);
+      m_doneEval = true;
+      return var;
+    }
+    finally
+    {
+      // These two statements need to be combined into one operation.
+      // vars.setStackFrame(currentFrame);
+      
+      if(-1 != velem.m_frameSize)
+	  	vars.unlink(currentFrame);
+    }
+  }
+  
+  /**
+   * Set an index to the point in the variable stack where we should
+   * begin variable searches for evaluation of expressions.
+   * This is -1 if m_isTopLevel is false. 
+   * 
+   * @param top A valid value that specifies where in the variable 
+   * stack the search should begin.
+   */
+  public void setVarStackPos(int top)
+  {
+    m_varStackPos = top;
+  }
+
+  /**
+   * Set an index into the variable stack where the variable context 
+   * ends, i.e. at the point we should terminate the search.
+   * 
+   * @param bottom The point at which the search should terminate, normally 
+   * zero for global variables.
+   */
+  public void setVarStackContext(int bottom)
+  {
+    m_varStackContext = bottom;
+  }
+  
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return CLASS_UNRESOLVEDVARIABLE
+   */
+  public int getType()
+  {
+    return CLASS_UNRESOLVEDVARIABLE;
+  }
+  
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return An informational string.
+   */
+  public String getTypeString()
+  {
+    return "XUnresolvedVariable (" + object().getClass().getName() + ")";
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/XUnresolvedVariableSimple.java b/src/main/java/org/apache/xalan/templates/XUnresolvedVariableSimple.java
new file mode 100644
index 0000000..92e8654
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/XUnresolvedVariableSimple.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XUnresolvedVariableSimple.java 468643 2006-10-28 06:56:03Z minchau $
+ */
+package org.apache.xalan.templates;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+
+/**
+ * This is the same as XUnresolvedVariable, but it assumes that the 
+ * context is already set up.  For use with psuedo variables.
+ * Also, it holds an Expression object, instead of an ElemVariable.
+ * It must only hold static context, since a single copy will be 
+ * held in the template.
+ */
+public class XUnresolvedVariableSimple extends XObject
+{
+    static final long serialVersionUID = -1224413807443958985L;
+  public XUnresolvedVariableSimple(ElemVariable obj)
+  {
+    super(obj);
+  }
+    
+	
+  /**
+   * For support of literal objects in xpaths.
+   *
+   * @param xctxt The XPath execution context.
+   *
+   * @return This object.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+  	Expression expr = ((ElemVariable)m_obj).getSelect().getExpression();
+    XObject xobj = expr.execute(xctxt);
+    xobj.allowDetachToRelease(false);
+    return xobj;
+  }
+  
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return CLASS_UNRESOLVEDVARIABLE
+   */
+  public int getType()
+  {
+    return CLASS_UNRESOLVEDVARIABLE;
+  }
+  
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return An informational string.
+   */
+  public String getTypeString()
+  {
+    return "XUnresolvedVariableSimple (" + object().getClass().getName() + ")";
+  }
+
+
+}
+
diff --git a/src/main/java/org/apache/xalan/templates/package.html b/src/main/java/org/apache/xalan/templates/package.html
new file mode 100644
index 0000000..240f6a5
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/package.html
@@ -0,0 +1,44 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468643 2006-10-28 06:56:03Z minchau $ -->
+<html>
+  <title>Xalan Templates Package.</title>
+  <body>
+    <p>Implements the {@link javax.xml.transform.Templates} interface, 
+    and defines a set of classes that represent an XSLT stylesheet.</p>
+    
+    <p>{@link org.apache.xalan.templates.StylesheetRoot} implements the {@link javax.xml.transform.Templates} interface, and 
+    extends {@link org.apache.xalan.templates.StylesheetComposed}, 
+    which is a {@link org.apache.xalan.templates.Stylesheet} composed of itself 
+    and its included Stylesheet objects. A StylesheetRoot also contains a 
+    global list of all imported StylesheetComposed objects. The
+    role of these objects is to hold immutable stylesheet data, not to perform 
+    procedural tasks associated with the
+    construction of the data (the org.apache.xalan.processor package) or with the transformation (the org.apache.xalan.transformer
+    package).</p>
+    <p>{@link org.apache.xalan.templates.ElemTemplateElement} is the superclass of 
+    all XSLT instruction elements, including Stylesheet. The <i>x</i>Func classes
+    extend members of the org.apache.xpath package and implement XSLT functions. Unlike 
+    the Stylesheet "container" objects, the
+    instruction element and function classes do contain procedural execute() 
+    methods that are called during the transformation.</p>
+    <p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xalan/transformer/ClonerToResultTree.java b/src/main/java/org/apache/xalan/transformer/ClonerToResultTree.java
new file mode 100644
index 0000000..cc7ea6c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/ClonerToResultTree.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ClonerToResultTree.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.serialize.SerializerUtils;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.XMLString;
+
+/**
+ * Class used to clone a node, possibly including its children to 
+ * a result tree.
+ * @xsl.usage internal
+ */
+public class ClonerToResultTree
+{
+
+//  /**
+//   * Clone an element with or without children.
+//   * TODO: Fix or figure out node clone failure!
+//   * the error condition is severe enough to halt processing.
+//   *
+//   * @param node The node to clone
+//   * @param shouldCloneAttributes Flag indicating whether to 
+//   * clone children attributes
+//   * 
+//   * @throws TransformerException
+//   */
+//  public void cloneToResultTree(int node, boolean shouldCloneAttributes)
+//    throws TransformerException
+//  {
+//
+//    try
+//    {
+//      XPathContext xctxt = m_transformer.getXPathContext();
+//      DTM dtm = xctxt.getDTM(node);
+//
+//      int type = dtm.getNodeType(node);
+//      switch (type)
+//      {
+//      case DTM.TEXT_NODE :
+//        dtm.dispatchCharactersEvents(node, m_rth, false);
+//        break;
+//      case DTM.DOCUMENT_FRAGMENT_NODE :
+//      case DTM.DOCUMENT_NODE :
+//
+//        // Can't clone a document, but refrain from throwing an error
+//        // so that copy-of will work
+//        break;
+//      case DTM.ELEMENT_NODE :
+//        {
+//          Attributes atts;
+//
+//          if (shouldCloneAttributes)
+//          {
+//            m_rth.addAttributes(node);
+//            m_rth.processNSDecls(node, type, dtm);
+//          }
+//
+//          String ns = dtm.getNamespaceURI(node);
+//          String localName = dtm.getLocalName(node);
+//
+//          m_rth.startElement(ns, localName, dtm.getNodeNameX(node), null);
+//        }
+//        break;
+//      case DTM.CDATA_SECTION_NODE :
+//        m_rth.startCDATA();          
+//        dtm.dispatchCharactersEvents(node, m_rth, false);
+//        m_rth.endCDATA();
+//        break;
+//      case DTM.ATTRIBUTE_NODE :
+//        m_rth.addAttribute(node);
+//        break;
+//      case DTM.COMMENT_NODE :
+//        XMLString xstr = dtm.getStringValue (node);
+//        xstr.dispatchAsComment(m_rth);
+//        break;
+//      case DTM.ENTITY_REFERENCE_NODE :
+//        m_rth.entityReference(dtm.getNodeNameX(node));
+//        break;
+//      case DTM.PROCESSING_INSTRUCTION_NODE :
+//        {
+//          // %REVIEW% Is the node name the same as the "target"?
+//          m_rth.processingInstruction(dtm.getNodeNameX(node), 
+//                                      dtm.getNodeValue(node));
+//        }
+//        break;
+//      default :
+//        //"Can not create item in result tree: "+node.getNodeName());
+//        m_transformer.getMsgMgr().error(null, 
+//                         XSLTErrorResources.ER_CANT_CREATE_ITEM,
+//                         new Object[]{ dtm.getNodeName(node) });  
+//      }
+//    }
+//    catch(org.xml.sax.SAXException se)
+//    {
+//      throw new TransformerException(se);
+//    }
+//  }  // end cloneToResultTree function
+  
+  /**
+   * Clone an element with or without children.
+   * TODO: Fix or figure out node clone failure!
+   * the error condition is severe enough to halt processing.
+   *
+   * @param node The node to clone
+   * @param shouldCloneAttributes Flag indicating whether to 
+   * clone children attributes
+   * 
+   * @throws TransformerException
+   */
+  public static void cloneToResultTree(int node, int nodeType, DTM dtm, 
+                                             SerializationHandler rth,
+                                             boolean shouldCloneAttributes)
+    throws TransformerException
+  {
+
+    try
+    {
+      switch (nodeType)
+      {
+      case DTM.TEXT_NODE :
+        dtm.dispatchCharactersEvents(node, rth, false);
+        break;
+      case DTM.DOCUMENT_FRAGMENT_NODE :
+      case DTM.DOCUMENT_NODE :
+        // Can't clone a document, but refrain from throwing an error
+        // so that copy-of will work
+        break;
+      case DTM.ELEMENT_NODE :
+        {
+          // Note: SAX apparently expects "no namespace" to be
+          // represented as "" rather than null.
+          String ns = dtm.getNamespaceURI(node);
+          if (ns==null) ns="";
+          String localName = dtm.getLocalName(node);
+      //  rth.startElement(ns, localName, dtm.getNodeNameX(node), null);
+      //  don't call a real SAX startElement (as commented out above),
+      //  call a SAX-like startElement, to be able to add attributes after this call
+          rth.startElement(ns, localName, dtm.getNodeNameX(node));
+          
+	  // If outputting attrs as separate events, they must
+	  // _follow_ the startElement event. (Think of the
+	  // xsl:attribute directive.)
+          if (shouldCloneAttributes)
+          {
+            SerializerUtils.addAttributes(rth, node);
+            SerializerUtils.processNSDecls(rth, node, nodeType, dtm);
+          }
+        }
+        break;
+      case DTM.CDATA_SECTION_NODE :
+        rth.startCDATA();          
+        dtm.dispatchCharactersEvents(node, rth, false);
+        rth.endCDATA();
+        break;
+      case DTM.ATTRIBUTE_NODE :
+        SerializerUtils.addAttribute(rth, node);
+        break;
+			case DTM.NAMESPACE_NODE:
+				// %REVIEW% Normally, these should have been handled with element.
+				// It's possible that someone may write a stylesheet that tries to
+				// clone them explicitly. If so, we need the equivalent of
+				// rth.addAttribute().
+  			    SerializerUtils.processNSDecls(rth,node,DTM.NAMESPACE_NODE,dtm);
+				break;
+      case DTM.COMMENT_NODE :
+        XMLString xstr = dtm.getStringValue (node);
+        xstr.dispatchAsComment(rth);
+        break;
+      case DTM.ENTITY_REFERENCE_NODE :
+        rth.entityReference(dtm.getNodeNameX(node));
+        break;
+      case DTM.PROCESSING_INSTRUCTION_NODE :
+        {
+          // %REVIEW% Is the node name the same as the "target"?
+          rth.processingInstruction(dtm.getNodeNameX(node), 
+                                      dtm.getNodeValue(node));
+        }
+        break;
+      default :
+        //"Can not create item in result tree: "+node.getNodeName());
+        throw new  TransformerException(
+                         "Can't clone node: "+dtm.getNodeName(node));
+      }
+    }
+    catch(org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+  }  // end cloneToResultTree function
+}
diff --git a/src/main/java/org/apache/xalan/transformer/Counter.java b/src/main/java/org/apache/xalan/transformer/Counter.java
new file mode 100644
index 0000000..a8aabd8
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/Counter.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Counter.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemNumber;
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+
+/**
+ * A class that does incremental counting for support of xsl:number.
+ * This class stores a cache of counted nodes (m_countNodes).
+ * It tries to cache the counted nodes in document order...
+ * the node count is based on its position in the cache list
+ * @xsl.usage internal
+ */
+public class Counter
+{
+
+  /**
+   * Set the maximum ammount the m_countNodes list can
+   * grow to.
+   */
+  static final int MAXCOUNTNODES = 500;
+
+  /**
+   * The start count from where m_countNodes counts
+   * from.  In other words, the count of a given node
+   * in the m_countNodes vector is node position +
+   * m_countNodesStartCount.
+   */
+  int m_countNodesStartCount = 0;
+
+  /**
+   * A vector of all nodes counted so far.
+   */
+  NodeSetDTM m_countNodes;
+
+  /**
+   * The node from where the counting starts.  This is needed to
+   * find a counter if the node being counted is not immediatly
+   * found in the m_countNodes vector.
+   */
+  int m_fromNode = DTM.NULL;
+
+  /**
+   * The owning xsl:number element.
+   */
+  ElemNumber m_numberElem;
+
+  /**
+   * Value to store result of last getCount call, for benifit
+   * of returning val from CountersTable.getCounterByCounted,
+   * who calls getCount.
+   */
+  int m_countResult;
+
+  /**
+   * Construct a counter object.
+   *
+   * @param numberElem The owning xsl:number element. 
+   * @param countNodes A vector of all nodes counted so far.
+   *
+   * @throws TransformerException
+   */
+  Counter(ElemNumber numberElem, NodeSetDTM countNodes) throws TransformerException
+  {
+    m_countNodes = countNodes;
+    m_numberElem = numberElem;
+  }
+
+  /**
+   * Construct a counter object.
+   *
+   * @param numberElem The owning xsl:number element. 
+   *
+   * @throws TransformerException
+   *
+  Counter(ElemNumber numberElem) throws TransformerException
+  {
+    m_numberElem = numberElem;
+  }*/
+
+  /**
+   * Try and find a node that was previously counted. If found,
+   * return a positive integer that corresponds to the count.
+   *
+   * @param support The XPath context to use
+   * @param node The node to be counted.
+   * 
+   * @return The count of the node, or -1 if not found.
+   */
+  int getPreviouslyCounted(XPathContext support, int node)
+  {
+
+    int n = m_countNodes.size();
+
+    m_countResult = 0;
+
+    for (int i = n - 1; i >= 0; i--)
+    {
+      int countedNode = m_countNodes.elementAt(i);
+
+      if (node == countedNode)
+      {
+
+        // Since the list is in backwards order, the count is 
+        // how many are in the rest of the list.
+        m_countResult = i + 1 + m_countNodesStartCount;
+
+        break;
+      }
+      
+      DTM dtm = support.getDTM(countedNode);
+
+      // Try to see if the given node falls after the counted node...
+      // if it does, don't keep searching backwards.
+      if (dtm.isNodeAfter(countedNode, node))
+        break;
+    }
+
+    return m_countResult;
+  }
+
+  /**
+   * Get the last node in the list.
+   *
+   * @return the last node in the list.
+   */
+  int getLast()
+  {
+
+    int size = m_countNodes.size();
+
+    return (size > 0) ? m_countNodes.elementAt(size - 1) : DTM.NULL;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/CountersTable.java b/src/main/java/org/apache/xalan/transformer/CountersTable.java
new file mode 100644
index 0000000..258fdb1
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/CountersTable.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: CountersTable.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.ElemNumber;
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+
+/**
+ * This is a table of counters, keyed by ElemNumber objects, each
+ * of which has a list of Counter objects.  This really isn't a true
+ * table, it is more like a list of lists (there must be a technical
+ * term for that...).
+ * @xsl.usage internal
+ */
+public class CountersTable extends Hashtable
+{
+    static final long serialVersionUID = 2159100770924179875L;
+
+  /**
+   * Construct a CountersTable.
+   */
+  public CountersTable(){}
+
+  /**
+   * Get the list of counters that corresponds to
+   * the given ElemNumber object.
+   *
+   * @param numberElem the given xsl:number element.
+   *
+   * @return the list of counters that corresponds to
+   * the given ElemNumber object.
+   */
+  Vector getCounters(ElemNumber numberElem)
+  {
+
+    Vector counters = (Vector) this.get(numberElem);
+
+    return (null == counters) ? putElemNumber(numberElem) : counters;
+  }
+
+  /**
+   * Put a counter into the table and create an empty
+   * vector as it's value.
+   *
+   * @param numberElem the given xsl:number element.
+   *
+   * @return an empty vector to be used to store counts
+   * for this number element.
+   */
+  Vector putElemNumber(ElemNumber numberElem)
+  {
+
+    Vector counters = new Vector();
+
+    this.put(numberElem, counters);
+
+    return counters;
+  }
+
+  /**
+   * Place to collect new counters.
+   */
+  transient private NodeSetDTM m_newFound;
+
+  /**
+   * Add a list of counted nodes that were built in backwards document
+   * order, or a list of counted nodes that are in forwards document
+   * order.
+   *
+   * @param flist Vector of nodes built in forwards document order
+   * @param blist Vector of nodes built in backwards document order
+   */
+  void appendBtoFList(NodeSetDTM flist, NodeSetDTM blist)
+  {
+
+    int n = blist.size();
+
+    for (int i = (n - 1); i >= 0; i--)
+    {
+      flist.addElement(blist.item(i));
+    }
+  }
+
+  // For diagnostics
+
+  /** Number of counters created so far          */
+  transient int m_countersMade = 0;
+
+  /**
+   * Count forward until the given node is found, or until
+   * we have looked to the given amount.
+   *
+   * @param support The XPath context to use  
+   * @param numberElem The given xsl:number element.
+   * @param node The node to count.
+   * 
+   * @return The node count, or 0 if not found.
+   *
+   * @throws TransformerException
+   */
+  public int countNode(XPathContext support, ElemNumber numberElem, int node)
+          throws TransformerException
+  {
+
+    int count = 0;
+    Vector counters = getCounters(numberElem);
+    int nCounters = counters.size();
+
+    // XPath countMatchPattern = numberElem.getCountMatchPattern(support, node);
+    // XPath fromMatchPattern = numberElem.m_fromMatchPattern;
+    int target = numberElem.getTargetNode(support, node);
+
+    if (DTM.NULL != target)
+    {
+      for (int i = 0; i < nCounters; i++)
+      {
+        Counter counter = (Counter) counters.elementAt(i);
+
+        count = counter.getPreviouslyCounted(support, target);
+
+        if (count > 0)
+          return count;
+      }
+
+      // In the loop below, we collect the nodes in backwards doc order, so 
+      // we don't have to do inserts, but then we store the nodes in forwards 
+      // document order, so we don't have to insert nodes into that list, 
+      // so that's what the appendBtoFList stuff is all about.  In cases 
+      // of forward counting by one, this will mean a single node copy from 
+      // the backwards list (m_newFound) to the forwards list (counter.m_countNodes).
+      count = 0;
+      if (m_newFound == null)
+        m_newFound = new NodeSetDTM(support.getDTMManager());
+
+      for (; DTM.NULL != target;
+              target = numberElem.getPreviousNode(support, target))
+      {
+
+        // First time in, we should not have to check for previous counts, 
+        // since the original target node was already checked in the 
+        // block above.
+        if (0 != count)
+        {
+          for (int i = 0; i < nCounters; i++)
+          {
+            Counter counter = (Counter) counters.elementAt(i);
+            int cacheLen = counter.m_countNodes.size();
+
+            if ((cacheLen > 0)
+                    && (counter.m_countNodes.elementAt(cacheLen
+                                                      - 1) == target))
+            {
+              count += (cacheLen + counter.m_countNodesStartCount);
+
+              if (cacheLen > 0)
+                appendBtoFList(counter.m_countNodes, m_newFound);
+
+              m_newFound.removeAllElements();
+
+              return count;
+            }
+          }
+        }
+
+        m_newFound.addElement(target);
+
+        count++;
+      }
+
+      // If we got to this point, then we didn't find a counter, so make 
+      // one and add it to the list.
+      Counter counter = new Counter(numberElem, new NodeSetDTM(support.getDTMManager()));
+
+      m_countersMade++;  // for diagnostics
+
+      appendBtoFList(counter.m_countNodes, m_newFound);
+      m_newFound.removeAllElements();
+      counters.addElement(counter);
+    }
+
+    return count;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/DecimalToRoman.java b/src/main/java/org/apache/xalan/transformer/DecimalToRoman.java
new file mode 100644
index 0000000..3a600d0
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/DecimalToRoman.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DecimalToRoman.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+/**
+ * Structure to help in converting integers to roman numerals
+ * @xsl.usage internal
+ */
+public class DecimalToRoman
+{
+
+  /**
+   * Constructor DecimalToRoman
+   *
+   *
+   * @param postValue Minimum value for a given range of 
+   * roman numbers
+   * @param postLetter Correspoding letter (roman) to postValue
+   * @param preValue Value of last prefixed number within 
+   * that same range (i.e. IV if postval is 5 (V))
+   * @param preLetter Correspoding letter(roman) to preValue
+   */
+  public DecimalToRoman(long postValue, String postLetter, long preValue,
+                        String preLetter)
+  {
+
+    this.m_postValue = postValue;
+    this.m_postLetter = postLetter;
+    this.m_preValue = preValue;
+    this.m_preLetter = preLetter;
+  }
+
+  /** Minimum value for a given range of roman numbers          */
+  public long m_postValue;
+
+  /** Correspoding letter (roman) to m_postValue          */
+  public String m_postLetter;
+
+  /** Value of last prefixed number within that same range  */
+  public long m_preValue;
+
+  /** Correspoding letter (roman) to m_preValue          */
+  public String m_preLetter;
+}
diff --git a/src/main/java/org/apache/xalan/transformer/KeyIterator.java b/src/main/java/org/apache/xalan/transformer/KeyIterator.java
new file mode 100644
index 0000000..588f0eb
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/KeyIterator.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: KeyIterator.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.KeyDeclaration;
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.XPath;
+import org.apache.xpath.axes.OneStepIteratorForward;
+
+/**
+ * This class implements an optimized iterator for 
+ * "key()" patterns, matching each node to the 
+ * match attribute in one or more xsl:key declarations.
+ * @xsl.usage internal
+ */
+public class KeyIterator extends OneStepIteratorForward
+{
+    static final long serialVersionUID = -1349109910100249661L;
+
+  /** Key name.
+   *  @serial           */
+  private QName m_name;
+
+  /**
+   * Get the key name from a key declaration this iterator will process
+   *
+   *
+   * @return Key name
+   */
+  public QName getName()
+  {
+    return m_name;
+  }
+
+  /** Vector of Key declarations in the stylesheet.
+   *  @serial          */
+  private Vector m_keyDeclarations;
+
+  /**
+   * Get the key declarations from the stylesheet 
+   *
+   *
+   * @return Vector containing the key declarations from the stylesheet
+   */
+  public Vector getKeyDeclarations()
+  {
+    return m_keyDeclarations;
+  }
+
+  /**
+    * Create a KeyIterator object.
+    *
+    * @throws javax.xml.transform.TransformerException
+    */
+  KeyIterator(QName name, Vector keyDeclarations)
+  {
+    super(Axis.ALL);
+    m_keyDeclarations = keyDeclarations;
+    // m_prefixResolver = nscontext;
+    m_name = name;
+  }
+
+  /**
+   *  Test whether a specified node is visible in the logical view of a
+   * TreeWalker or NodeIterator. This function will be called by the
+   * implementation of TreeWalker and NodeIterator; it is not intended to
+   * be called directly from user code.
+   * 
+   * @param testNode  The node to check to see if it passes the filter or not.
+   *
+   * @return  a constant to determine whether the node is accepted,
+   *   rejected, or skipped, as defined  above .
+   */
+  public short acceptNode(int testNode)
+  {
+    boolean foundKey = false;
+    KeyIterator ki = (KeyIterator) m_lpi;
+    org.apache.xpath.XPathContext xctxt = ki.getXPathContext();
+    Vector keys = ki.getKeyDeclarations();
+
+    QName name = ki.getName();
+    try
+    {
+      // System.out.println("lookupKey: "+lookupKey);
+      int nDeclarations = keys.size();
+
+      // Walk through each of the declarations made with xsl:key
+      for (int i = 0; i < nDeclarations; i++)
+      {
+        KeyDeclaration kd = (KeyDeclaration) keys.elementAt(i);
+
+        // Only continue if the name on this key declaration
+        // matches the name on the iterator for this walker. 
+        if (!kd.getName().equals(name))
+          continue;
+
+        foundKey = true;
+        // xctxt.setNamespaceContext(ki.getPrefixResolver());
+
+        // See if our node matches the given key declaration according to 
+        // the match attribute on xsl:key.
+        XPath matchExpr = kd.getMatch();
+        double score = matchExpr.getMatchScore(xctxt, testNode);
+
+        if (score == kd.getMatch().MATCH_SCORE_NONE)
+          continue;
+
+        return DTMIterator.FILTER_ACCEPT;
+
+      } // end for(int i = 0; i < nDeclarations; i++)
+    }
+    catch (TransformerException se)
+    {
+
+      // TODO: What to do?
+    }
+
+    if (!foundKey)
+      throw new RuntimeException(
+        XSLMessages.createMessage(
+          XSLTErrorResources.ER_NO_XSLKEY_DECLARATION,
+          new Object[] { name.getLocalName()}));
+          
+    return DTMIterator.FILTER_REJECT;
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/transformer/KeyManager.java b/src/main/java/org/apache/xalan/transformer/KeyManager.java
new file mode 100644
index 0000000..884783c
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/KeyManager.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: KeyManager.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.util.Vector;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+
+/**
+ * This class manages the key tables.
+ */
+public class KeyManager
+{
+
+  /**
+   * Table of tables of element keys.
+   * @see org.apache.xalan.transformer.KeyTable
+   */
+  private transient Vector m_key_tables = null;
+
+  /**
+   * Given a valid element key, return the corresponding node list.
+   *
+   * @param xctxt The XPath runtime state
+   * @param doc The document node
+   * @param name The key element name
+   * @param ref The key value we're looking for 
+   * @param nscontext The prefix resolver for the execution context
+   *
+   * @return A nodelist of nodes mathing the given key
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XNodeSet getNodeSetDTMByKey(
+          XPathContext xctxt, int doc, QName name, XMLString ref, PrefixResolver nscontext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    XNodeSet nl = null;
+    ElemTemplateElement template = (ElemTemplateElement) nscontext;  // yuck -sb
+
+    if ((null != template)
+            && null != template.getStylesheetRoot().getKeysComposed())
+    {
+      boolean foundDoc = false;
+
+      if (null == m_key_tables)
+      {
+        m_key_tables = new Vector(4);
+      }
+      else
+      {
+        int nKeyTables = m_key_tables.size();
+
+        for (int i = 0; i < nKeyTables; i++)
+        {
+          KeyTable kt = (KeyTable) m_key_tables.elementAt(i);
+
+          if (kt.getKeyTableName().equals(name) && doc == kt.getDocKey())
+          {
+            nl = kt.getNodeSetDTMByKey(name, ref);
+
+            if (nl != null)
+            {
+              foundDoc = true;
+
+              break;
+            }
+          }
+        }
+      }
+
+      if ((null == nl) &&!foundDoc /* && m_needToBuildKeysTable */)
+      {
+        KeyTable kt =
+          new KeyTable(doc, nscontext, name,
+                       template.getStylesheetRoot().getKeysComposed(),
+                       xctxt);
+
+        m_key_tables.addElement(kt);
+
+        if (doc == kt.getDocKey())
+        {
+          foundDoc = true;
+          nl = kt.getNodeSetDTMByKey(name, ref);
+        }
+      }
+    }
+
+    return nl;
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/KeyTable.java b/src/main/java/org/apache/xalan/transformer/KeyTable.java
new file mode 100644
index 0000000..fcfa366
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/KeyTable.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: KeyTable.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.KeyDeclaration;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.WrappedRuntimeException;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Table of element keys, keyed by document node.  An instance of this
+ * class is keyed by a Document node that should be matched with the
+ * root of the current context.
+ * @xsl.usage advanced
+ */
+public class KeyTable
+{
+  /**
+   * The document key.  This table should only be used with contexts
+   * whose Document roots match this key.
+   */
+  private int m_docKey;
+
+  /**
+   * Vector of KeyDeclaration instances holding the key declarations.
+   */
+  private Vector m_keyDeclarations;
+
+  /**
+   * Hold a cache of key() function result for each ref.
+   * Key is XMLString, the ref value
+   * Value is XNodeSet, the key() function result for the given ref value.
+   */
+  private Hashtable m_refsTable = null;
+
+  /**
+   * Get the document root matching this key.  
+   *
+   * @return the document root matching this key
+   */
+  public int getDocKey()
+  {
+    return m_docKey;
+  }
+
+  /** 
+   * The main iterator that will walk through the source  
+   * tree for this key.
+   */
+  private XNodeSet m_keyNodes;
+  
+  KeyIterator getKeyIterator()
+  {
+  	return (KeyIterator)(m_keyNodes.getContainedIter());
+  }
+
+  /**
+   * Build a keys table.
+   * @param doc The owner document key.
+   * @param nscontext The stylesheet's namespace context.
+   * @param name The key name
+   * @param keyDeclarations The stylesheet's xsl:key declarations.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public KeyTable(
+          int doc, PrefixResolver nscontext, QName name, Vector keyDeclarations, XPathContext xctxt)
+            throws javax.xml.transform.TransformerException
+  {
+    m_docKey = doc;
+    m_keyDeclarations = keyDeclarations;
+    KeyIterator ki = new KeyIterator(name, keyDeclarations);
+
+    m_keyNodes = new XNodeSet(ki);
+    m_keyNodes.allowDetachToRelease(false);
+    m_keyNodes.setRoot(doc, xctxt);
+  }
+
+  /**
+   * Given a valid element key, return the corresponding node list.
+   * 
+   * @param name The name of the key, which must match the 'name' attribute on xsl:key.
+   * @param ref The value that must match the value found by the 'match' attribute on xsl:key.
+   * @return a set of nodes referenced by the key named <CODE>name</CODE> and the reference <CODE>ref</CODE>. If no node is referenced by this key, an empty node set is returned.
+   */
+  public XNodeSet getNodeSetDTMByKey(QName name, XMLString ref)
+
+  {
+    XNodeSet refNodes = (XNodeSet) getRefsTable().get(ref);
+    // clone wiht reset the node set
+   try
+    {
+      if (refNodes != null)
+      {
+         refNodes = (XNodeSet) refNodes.cloneWithReset();
+       }
+    }
+    catch (CloneNotSupportedException e)
+    {
+      refNodes = null;
+    }
+
+    if (refNodes == null) {
+     //  create an empty XNodeSet
+      KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
+      XPathContext xctxt = ki.getXPathContext();
+      refNodes = new XNodeSet(xctxt.getDTMManager()) {
+        public void setRoot(int nodeHandle, Object environment) {
+          // Root cannot be set on non-iterated node sets. Ignore it.
+        }
+      };
+      refNodes.reset();
+    }
+
+    return refNodes;
+  }
+
+  /**
+   * Get Key Name for this KeyTable  
+   *
+   * @return Key name
+   */
+  public QName getKeyTableName()
+  {
+    return getKeyIterator().getName();
+  }
+
+  /**
+   * @return key declarations for the key associated to this KeyTable
+   */
+  private Vector getKeyDeclarations() {
+    int nDeclarations = m_keyDeclarations.size();
+    Vector keyDecls = new Vector(nDeclarations);
+
+    // Walk through each of the declarations made with xsl:key
+    for (int i = 0; i < nDeclarations; i++)
+    {
+      KeyDeclaration kd = (KeyDeclaration) m_keyDeclarations.elementAt(i);
+
+      // Add the declaration if the name on this key declaration
+      // matches the name on the iterator for this walker.
+      if (kd.getName().equals(getKeyTableName())) {
+        keyDecls.add(kd);
+      }
+    }
+
+    return keyDecls;
+  }
+
+  /**
+   * @return lazy initialized refs table associating evaluation of key function
+   *         with a XNodeSet
+   */
+  private Hashtable getRefsTable()
+  {
+    if (m_refsTable == null) {
+      // initial capacity set to a prime number to improve hash performance
+      m_refsTable = new Hashtable(89);
+
+      KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
+      XPathContext xctxt = ki.getXPathContext();
+
+      Vector keyDecls = getKeyDeclarations();
+      int nKeyDecls = keyDecls.size();
+
+      int currentNode;
+      m_keyNodes.reset();
+      while (DTM.NULL != (currentNode = m_keyNodes.nextNode()))
+      {
+        try
+        {
+          for (int keyDeclIdx = 0; keyDeclIdx < nKeyDecls; keyDeclIdx++) {
+            KeyDeclaration keyDeclaration =
+                (KeyDeclaration) keyDecls.elementAt(keyDeclIdx);
+            XObject xuse =
+                keyDeclaration.getUse().execute(xctxt,
+                                                currentNode,
+                                                ki.getPrefixResolver());
+
+            if (xuse.getType() != xuse.CLASS_NODESET) {
+              XMLString exprResult = xuse.xstr();
+              addValueInRefsTable(xctxt, exprResult, currentNode);
+            } else {
+              DTMIterator i = ((XNodeSet)xuse).iterRaw();
+              int currentNodeInUseClause;
+
+              while (DTM.NULL != (currentNodeInUseClause = i.nextNode())) {
+                DTM dtm = xctxt.getDTM(currentNodeInUseClause);
+                XMLString exprResult =
+                    dtm.getStringValue(currentNodeInUseClause);
+                addValueInRefsTable(xctxt, exprResult, currentNode);
+              }
+            }
+          }
+        } catch (TransformerException te) {
+          throw new WrappedRuntimeException(te);
+        }
+      }
+    }
+    return m_refsTable;
+  }
+
+  /**
+   * Add an association between a ref and a node in the m_refsTable.
+   * Requires that m_refsTable != null
+   * @param xctxt XPath context
+   * @param ref the value of the use clause of the current key for the given node
+   * @param node the node to reference
+   */
+  private void addValueInRefsTable(XPathContext xctxt, XMLString ref, int node) {
+    
+    XNodeSet nodes = (XNodeSet) m_refsTable.get(ref);
+    if (nodes == null)
+    {
+      nodes = new XNodeSet(node, xctxt.getDTMManager());
+      nodes.nextNode();
+      m_refsTable.put(ref, nodes);
+    }
+    else
+    {
+      // Nodes are passed to this method in document order.  Since we need to
+      // suppress duplicates, we only need to check against the last entry
+      // in each nodeset.  We use nodes.nextNode after each entry so we can
+      // easily compare node against the current node.
+      if (nodes.getCurrentNode() != node) {
+          nodes.mutableNodeset().addNode(node);
+          nodes.nextNode();
+      }    
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/MsgMgr.java b/src/main/java/org/apache/xalan/transformer/MsgMgr.java
new file mode 100644
index 0000000..7f42c29
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/MsgMgr.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: MsgMgr.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class will manage error messages, warning messages, and other types of
+ * message events.
+ */
+public class MsgMgr
+{
+
+  /**
+   * Create a message manager object.
+   *
+   * @param transformer non transformer instance
+   */
+  public MsgMgr(TransformerImpl transformer)
+  {
+    m_transformer = transformer;
+  }
+
+  /** Transformer instance          */
+  private TransformerImpl m_transformer;
+
+  /**
+   * Warn the user of a problem.
+   * This is public for access by extensions.
+   *
+   * @param msg The message text to issue
+   * @param terminate Flag indicating whether to terminate this process
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   */
+  public void message(SourceLocator srcLctr, String msg, boolean terminate) throws TransformerException
+  {
+
+    ErrorListener errHandler = m_transformer.getErrorListener();
+
+    if (null != errHandler)
+    {
+      errHandler.warning(new TransformerException(msg, srcLctr));
+    }
+    else
+    {
+      if (terminate)
+        throw new TransformerException(msg, srcLctr);
+      else
+        System.out.println(msg);
+    }
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param msg Message text to issue
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void warn(SourceLocator srcLctr, String msg) throws TransformerException
+  {
+    warn(srcLctr, null, null, msg, null);
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param msg Message text to issue
+   * @param args Arguments to pass to the message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void warn(SourceLocator srcLctr, String msg, Object[] args) throws TransformerException
+  {
+    warn(srcLctr, null, null, msg, args);
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * 
+   * @param styleNode Stylesheet node
+   * @param sourceNode Source tree node
+   * @param msg Message text to issue
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void warn(SourceLocator srcLctr, Node styleNode, Node sourceNode, String msg)
+          throws TransformerException
+  {
+    warn(srcLctr, styleNode, sourceNode, msg, null);
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param styleNode Stylesheet node
+   * @param sourceNode Source tree node
+   * @param msg Message text to issue
+   * @param args Arguments to pass to the message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void warn(SourceLocator srcLctr, Node styleNode, Node sourceNode, String msg, Object args[])
+          throws TransformerException
+  {
+
+    String formattedMsg = XSLMessages.createWarning(msg, args);
+    ErrorListener errHandler = m_transformer.getErrorListener();
+
+    if (null != errHandler)
+      errHandler.warning(new TransformerException(formattedMsg, srcLctr));
+    else
+      System.out.println(formattedMsg);
+  }
+
+  /* This method is not properly i18nized. We need to use the following method
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Message text to issue
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   *
+  public void error(SourceLocator srcLctr, String msg) throws TransformerException
+  {
+
+    // Locator locator = m_stylesheetLocatorStack.isEmpty()
+    //                  ? null :
+    //                    ((Locator)m_stylesheetLocatorStack.peek());
+    // Locator locator = null;
+    ErrorListener errHandler = m_transformer.getErrorListener();
+
+    if (null != errHandler)
+      errHandler.fatalError(new TransformerException(msg, srcLctr));
+    else
+      throw new TransformerException(msg, srcLctr);
+  }
+
+ * @xsl.usage internal
+ */
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Message text to issue
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, String msg) throws TransformerException
+  {
+    error(srcLctr, null, null, msg, null);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Message text to issue
+   * @param args Arguments to be passed to the message 
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, String msg, Object[] args) throws TransformerException
+  {
+    error(srcLctr, null, null, msg, args);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Message text to issue
+   * @param e Exception to throw
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, String msg, Exception e) throws TransformerException
+  {
+    error(srcLctr, msg, null, e);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Message text to issue
+   * @param args Arguments to use in message
+   * @param e Exception to throw
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, String msg, Object args[], Exception e) throws TransformerException
+  {
+
+    //msg  = (null == msg) ? XSLTErrorResources.ER_PROCESSOR_ERROR : msg;
+    String formattedMsg = XSLMessages.createMessage(msg, args);
+
+    // Locator locator = m_stylesheetLocatorStack.isEmpty()
+    //                   ? null :
+    //                    ((Locator)m_stylesheetLocatorStack.peek());
+    // Locator locator = null;
+    ErrorListener errHandler = m_transformer.getErrorListener();
+
+    if (null != errHandler)
+      errHandler.fatalError(new TransformerException(formattedMsg, srcLctr));
+    else
+      throw new TransformerException(formattedMsg, srcLctr);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param styleNode Stylesheet node
+   * @param sourceNode Source tree node
+   * @param msg Message text to issue
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, Node styleNode, Node sourceNode, String msg)
+          throws TransformerException
+  {
+    error(srcLctr, styleNode, sourceNode, msg, null);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param styleNode Stylesheet node
+   * @param sourceNode Source tree node
+   * @param msg Message text to issue
+   * @param args Arguments to use in message
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws TransformerException
+   * @xsl.usage internal
+   */
+  public void error(SourceLocator srcLctr, Node styleNode, Node sourceNode, String msg, Object args[])
+          throws TransformerException
+  {
+
+    String formattedMsg = XSLMessages.createMessage(msg, args);
+
+    // Locator locator = m_stylesheetLocatorStack.isEmpty()
+    //                   ? null :
+    //                    ((Locator)m_stylesheetLocatorStack.peek());
+    // Locator locator = null;
+    ErrorListener errHandler = m_transformer.getErrorListener();
+
+    if (null != errHandler)
+      errHandler.fatalError(new TransformerException(formattedMsg, srcLctr));
+    else
+      throw new TransformerException(formattedMsg, srcLctr);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/NodeSortKey.java b/src/main/java/org/apache/xalan/transformer/NodeSortKey.java
new file mode 100644
index 0000000..91a1fd5
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/NodeSortKey.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeSortKey.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.text.Collator;
+import java.util.Locale;
+
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xpath.XPath;
+
+/**
+ * Data structure for use by the NodeSorter class.
+ * @xsl.usage internal
+ */
+class NodeSortKey
+{
+
+  /** Select pattern for this sort key          */
+  XPath m_selectPat;
+
+  /** Flag indicating whether to treat thee result as a number     */
+  boolean m_treatAsNumbers;
+
+  /** Flag indicating whether to sort in descending order      */
+  boolean m_descending;
+
+  /** Flag indicating by case          */
+  boolean m_caseOrderUpper;
+
+  /** Collator instance          */
+  Collator m_col;
+
+  /** Locale we're in          */
+  Locale m_locale;
+
+  /** Prefix resolver to use          */
+  org.apache.xml.utils.PrefixResolver m_namespaceContext;
+
+  /** Transformer instance          */
+  TransformerImpl m_processor;  // needed for error reporting.
+
+  /**
+   * Constructor NodeSortKey
+   *
+   *
+   * @param transformer non null transformer instance
+   * @param selectPat Select pattern for this key 
+   * @param treatAsNumbers Flag indicating whether the result will be a number
+   * @param descending Flag indicating whether to sort in descending order
+   * @param langValue Lang value to use to get locale
+   * @param caseOrderUpper Flag indicating whether case is relevant
+   * @param namespaceContext Prefix resolver
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  NodeSortKey(
+          TransformerImpl transformer, XPath selectPat, boolean treatAsNumbers, 
+          boolean descending, String langValue, boolean caseOrderUpper, 
+          org.apache.xml.utils.PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    m_processor = transformer;
+    m_namespaceContext = namespaceContext;
+    m_selectPat = selectPat;
+    m_treatAsNumbers = treatAsNumbers;
+    m_descending = descending;
+    m_caseOrderUpper = caseOrderUpper;
+
+    if (null != langValue && m_treatAsNumbers == false)
+    {
+      // See http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2851
+      // The constructor of Locale is defined as 
+      //   public Locale(String language, String country)
+      // with
+      //   language - lowercase two-letter ISO-639 code
+      //   country - uppercase two-letter ISO-3166 code
+      // a) language must be provided as a lower-case ISO-code 
+      //    instead of an upper-case code
+      // b) country must be provided as an ISO-code 
+      //    instead of a full localized country name (e.g. "France")
+      m_locale = new Locale(langValue.toLowerCase(), 
+                  Locale.getDefault().getCountry());
+                  
+      // (old, before bug report 2851).
+      //  m_locale = new Locale(langValue.toUpperCase(),
+      //                        Locale.getDefault().getDisplayCountry());                    
+
+      if (null == m_locale)
+      {
+
+        // m_processor.warn("Could not find locale for <sort xml:lang="+langValue);
+        m_locale = Locale.getDefault();
+      }
+    }
+    else
+    {
+      m_locale = Locale.getDefault();
+    }
+
+    m_col = Collator.getInstance(m_locale);
+
+    if (null == m_col)
+    {
+      m_processor.getMsgMgr().warn(null, XSLTErrorResources.WG_CANNOT_FIND_COLLATOR,
+                                   new Object[]{ langValue });  //"Could not find Collator for <sort xml:lang="+langValue);
+
+      m_col = Collator.getInstance();
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/NodeSorter.java b/src/main/java/org/apache/xalan/transformer/NodeSorter.java
new file mode 100644
index 0000000..d7977b2
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/NodeSorter.java
@@ -0,0 +1,557 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeSorter.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.text.CollationKey;
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This class can sort vectors of DOM nodes according to a select pattern.
+ * @xsl.usage internal
+ */
+public class NodeSorter
+{
+
+  /** Current XPath context           */
+  XPathContext m_execContext;
+
+  /** Vector of NodeSortKeys          */
+  Vector m_keys;  // vector of NodeSortKeys
+
+//  /**
+//   * TODO: Adjust this for locale.
+//   */
+//  NumberFormat m_formatter = NumberFormat.getNumberInstance();
+
+  /**
+   * Construct a NodeSorter, passing in the XSL TransformerFactory
+   * so it can know how to get the node data according to
+   * the proper whitespace rules.
+   *
+   * @param p Xpath context to use
+   */
+  public NodeSorter(XPathContext p)
+  {
+    m_execContext = p;
+  }
+
+  /**
+   * Given a vector of nodes, sort each node according to
+   * the criteria in the keys.
+   * @param v an vector of Nodes.
+   * @param keys a vector of NodeSortKeys.
+   * @param support XPath context to use
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void sort(DTMIterator v, Vector keys, XPathContext support)
+          throws javax.xml.transform.TransformerException
+  {
+
+    m_keys = keys;
+
+    // QuickSort2(v, 0, v.size() - 1 );
+    int n = v.getLength();
+
+    // %OPT% Change mergesort to just take a DTMIterator?
+    // We would also have to adapt DTMIterator to have the function 
+    // of NodeCompareElem.
+    
+    // Create a vector of node compare elements
+    // based on the input vector of nodes
+    Vector nodes = new Vector();
+
+    for (int i = 0; i < n; i++)
+    {
+      NodeCompareElem elem = new NodeCompareElem(v.item(i));
+
+      nodes.addElement(elem);
+    }
+
+    Vector scratchVector = new Vector();
+
+    mergesort(nodes, scratchVector, 0, n - 1, support);
+
+    // return sorted vector of nodes
+    for (int i = 0; i < n; i++)
+    {
+      v.setItem(((NodeCompareElem) nodes.elementAt(i)).m_node, i);
+    }
+    v.setCurrentPos(0);
+
+    // old code...
+    //NodeVector scratchVector = new NodeVector(n);
+    //mergesort(v, scratchVector, 0, n - 1, support);
+  }
+
+  /**
+   * Return the results of a compare of two nodes.
+   * TODO: Optimize compare -- cache the getStringExpr results, key by m_selectPat + hash of node.
+   *
+   * @param n1 First node to use in compare
+   * @param n2 Second node to use in compare
+   * @param kIndex Index of NodeSortKey to use for sort
+   * @param support XPath context to use
+   *
+   * @return The results of the compare of the two nodes.
+   *
+   * @throws TransformerException
+   */
+  int compare(
+          NodeCompareElem n1, NodeCompareElem n2, int kIndex, XPathContext support)
+            throws TransformerException
+  {
+
+    int result = 0;
+    NodeSortKey k = (NodeSortKey) m_keys.elementAt(kIndex);
+
+    if (k.m_treatAsNumbers)
+    {
+      double n1Num, n2Num;
+
+      if (kIndex == 0)
+      {
+        n1Num = ((Double) n1.m_key1Value).doubleValue();
+        n2Num = ((Double) n2.m_key1Value).doubleValue();
+      }
+      else if (kIndex == 1)
+      {
+        n1Num = ((Double) n1.m_key2Value).doubleValue();
+        n2Num = ((Double) n2.m_key2Value).doubleValue();
+      }
+
+      /* Leave this in case we decide to use an array later
+      if (kIndex < maxkey)
+      {
+      double n1Num = (double)n1.m_keyValue[kIndex];
+      double n2Num = (double)n2.m_keyValue[kIndex];
+      }*/
+      else
+      {
+
+        // Get values dynamically
+        XObject r1 = k.m_selectPat.execute(m_execContext, n1.m_node,
+                                           k.m_namespaceContext);
+        XObject r2 = k.m_selectPat.execute(m_execContext, n2.m_node,
+                                           k.m_namespaceContext);
+        n1Num = r1.num();
+
+        // Can't use NaN for compare. They are never equal. Use zero instead.
+        // That way we can keep elements in document order. 
+        //n1Num = Double.isNaN(d) ? 0.0 : d;
+        n2Num = r2.num();
+        //n2Num = Double.isNaN(d) ? 0.0 : d;
+      }
+
+      if ((n1Num == n2Num) && ((kIndex + 1) < m_keys.size()))
+      {
+        result = compare(n1, n2, kIndex + 1, support);
+      }
+      else
+      {
+        double diff;
+        if (Double.isNaN(n1Num))
+        {
+          if (Double.isNaN(n2Num))
+            diff = 0.0;
+          else
+            diff = -1;
+        }
+        else if (Double.isNaN(n2Num))
+           diff = 1;
+        else
+          diff = n1Num - n2Num;
+
+        // process order parameter 
+        result = (int) ((diff < 0.0)
+                        ? (k.m_descending ? 1 : -1)
+                        : (diff > 0.0) ? (k.m_descending ? -1 : 1) : 0);
+      }
+    }  // end treat as numbers 
+    else
+    {
+      CollationKey n1String, n2String;
+
+      if (kIndex == 0)
+      {
+        n1String = (CollationKey) n1.m_key1Value;
+        n2String = (CollationKey) n2.m_key1Value;
+      }
+      else if (kIndex == 1)
+      {
+        n1String = (CollationKey) n1.m_key2Value;
+        n2String = (CollationKey) n2.m_key2Value;
+      }
+
+      /* Leave this in case we decide to use an array later
+      if (kIndex < maxkey)
+      {
+        String n1String = (String)n1.m_keyValue[kIndex];
+        String n2String = (String)n2.m_keyValue[kIndex];
+      }*/
+      else
+      {
+
+        // Get values dynamically
+        XObject r1 = k.m_selectPat.execute(m_execContext, n1.m_node,
+                                           k.m_namespaceContext);
+        XObject r2 = k.m_selectPat.execute(m_execContext, n2.m_node,
+                                           k.m_namespaceContext);
+
+        n1String = k.m_col.getCollationKey(r1.str());
+        n2String = k.m_col.getCollationKey(r2.str());
+      }
+
+      // Use collation keys for faster compare, but note that whitespaces 
+      // etc... are treated differently from if we were comparing Strings.
+      result = n1String.compareTo(n2String);
+
+      //Process caseOrder parameter
+      if (k.m_caseOrderUpper)
+      {
+        String tempN1 = n1String.getSourceString().toLowerCase();
+        String tempN2 = n2String.getSourceString().toLowerCase();
+
+        if (tempN1.equals(tempN2))
+        {
+
+          //java defaults to upper case is greater.
+          result = result == 0 ? 0 : -result;
+        }
+      }
+
+      //Process order parameter
+      if (k.m_descending)
+      {
+        result = -result;
+      }
+    }  //end else
+
+    if (0 == result)
+    {
+      if ((kIndex + 1) < m_keys.size())
+      {
+        result = compare(n1, n2, kIndex + 1, support);
+      }
+    }
+
+    if (0 == result)
+    {
+
+      // I shouldn't have to do this except that there seems to 
+      // be a glitch in the mergesort
+      // if(r1.getType() == r1.CLASS_NODESET)
+      // {
+      DTM dtm = support.getDTM(n1.m_node); // %OPT%
+      result = dtm.isNodeAfter(n1.m_node, n2.m_node) ? -1 : 1;
+
+      // }
+    }
+
+    return result;
+  }
+
+  /**
+   * This implements a standard Mergesort, as described in
+   * Robert Sedgewick's Algorithms book.  This is a better
+   * sort for our purpose than the Quicksort because it
+   * maintains the original document order of the input if
+   * the order isn't changed by the sort.
+   *
+   * @param a First vector of nodes to compare
+   * @param b Second vector of  nodes to compare 
+   * @param l Left boundary of  partition
+   * @param r Right boundary of  partition
+   * @param support XPath context to use
+   *
+   * @throws TransformerException
+   */
+  void mergesort(Vector a, Vector b, int l, int r, XPathContext support)
+          throws TransformerException
+  {
+
+    if ((r - l) > 0)
+    {
+      int m = (r + l) / 2;
+
+      mergesort(a, b, l, m, support);
+      mergesort(a, b, m + 1, r, support);
+
+      int i, j, k;
+
+      for (i = m; i >= l; i--)
+      {
+
+        // b[i] = a[i];
+        // Use insert if we need to increment vector size.
+        if (i >= b.size())
+          b.insertElementAt(a.elementAt(i), i);
+        else
+          b.setElementAt(a.elementAt(i), i);
+      }
+
+      i = l;
+
+      for (j = (m + 1); j <= r; j++)
+      {
+
+        // b[r+m+1-j] = a[j];
+        if (r + m + 1 - j >= b.size())
+          b.insertElementAt(a.elementAt(j), r + m + 1 - j);
+        else
+          b.setElementAt(a.elementAt(j), r + m + 1 - j);
+      }
+
+      j = r;
+
+      int compVal;
+
+      for (k = l; k <= r; k++)
+      {
+
+        // if(b[i] < b[j])
+        if (i == j)
+          compVal = -1;
+        else
+          compVal = compare((NodeCompareElem) b.elementAt(i),
+                            (NodeCompareElem) b.elementAt(j), 0, support);
+
+        if (compVal < 0)
+        {
+
+          // a[k]=b[i];
+          a.setElementAt(b.elementAt(i), k);
+
+          i++;
+        }
+        else if (compVal > 0)
+        {
+
+          // a[k]=b[j]; 
+          a.setElementAt(b.elementAt(j), k);
+
+          j--;
+        }
+      }
+    }
+  }
+
+  /**
+   * This is a generic version of C.A.R Hoare's Quick Sort
+   * algorithm.  This will handle arrays that are already
+   * sorted, and arrays with duplicate keys.<BR>
+   *
+   * If you think of a one dimensional array as going from
+   * the lowest index on the left to the highest index on the right
+   * then the parameters to this function are lowest index or
+   * left and highest index or right.  The first time you call
+   * this function it will be with the parameters 0, a.length - 1.
+   *
+   * @param v       a vector of integers 
+   * @param lo0     left boundary of array partition
+   * @param hi0     right boundary of array partition
+   *
+   */
+
+  /*  private void QuickSort2(Vector v, int lo0, int hi0, XPathContext support)
+      throws javax.xml.transform.TransformerException,
+             java.net.MalformedURLException,
+             java.io.FileNotFoundException,
+             java.io.IOException
+    {
+      int lo = lo0;
+      int hi = hi0;
+
+      if ( hi0 > lo0)
+      {
+        // Arbitrarily establishing partition element as the midpoint of
+        // the array.
+        Node midNode = (Node)v.elementAt( ( lo0 + hi0 ) / 2 );
+
+        // loop through the array until indices cross
+        while( lo <= hi )
+        {
+          // find the first element that is greater than or equal to
+          // the partition element starting from the left Index.
+          while( (lo < hi0) && (compare((Node)v.elementAt(lo), midNode, 0, support) < 0) )
+          {
+            ++lo;
+          } // end while
+
+          // find an element that is smaller than or equal to
+          // the partition element starting from the right Index.
+          while( (hi > lo0) && (compare((Node)v.elementAt(hi), midNode, 0, support) > 0) )
+          {
+            --hi;
+          }
+
+          // if the indexes have not crossed, swap
+          if( lo <= hi )
+          {
+            swap(v, lo, hi);
+            ++lo;
+            --hi;
+          }
+        }
+
+        // If the right index has not reached the left side of array
+        // must now sort the left partition.
+        if( lo0 < hi )
+        {
+          QuickSort2( v, lo0, hi, support );
+        }
+
+        // If the left index has not reached the right side of array
+        // must now sort the right partition.
+        if( lo < hi0 )
+        {
+          QuickSort2( v, lo, hi0, support );
+        }
+      }
+    } // end QuickSort2  */
+
+//  /**
+//   * Simple function to swap two elements in
+//   * a vector.
+//   * 
+//   * @param v Vector of nodes to swap
+//   * @param i Index of first node to swap
+//   * @param i Index of second node to swap
+//   */
+//  private void swap(Vector v, int i, int j)
+//  {
+//
+//    int node = (Node) v.elementAt(i);
+//
+//    v.setElementAt(v.elementAt(j), i);
+//    v.setElementAt(node, j);
+//  }
+
+  /**
+   * This class holds the value(s) from executing the given
+   * node against the sort key(s). 
+   * @xsl.usage internal
+   */
+  class NodeCompareElem
+  {
+
+    /** Current node          */
+    int m_node;
+
+    /** This maxkey value was chosen arbitrarily. We are assuming that the    
+    // maxkey + 1 keys will only hit fairly rarely and therefore, we
+    // will get the node values for those keys dynamically.
+    */
+    int maxkey = 2;
+
+    // Keep this in case we decide to use an array. Right now
+    // using two variables is cheaper.
+    //Object[] m_KeyValue = new Object[2];
+
+    /** Value from first sort key           */
+    Object m_key1Value;
+
+    /** Value from second sort key            */
+    Object m_key2Value;
+
+    /**
+     * Constructor NodeCompareElem
+     *
+     *
+     * @param node Current node
+     *
+     * @throws javax.xml.transform.TransformerException
+     */
+    NodeCompareElem(int node) throws javax.xml.transform.TransformerException
+    {
+      m_node = node;
+
+      if (!m_keys.isEmpty())
+      {
+        NodeSortKey k1 = (NodeSortKey) m_keys.elementAt(0);
+        XObject r = k1.m_selectPat.execute(m_execContext, node,
+                                           k1.m_namespaceContext);
+
+        double d;
+
+        if (k1.m_treatAsNumbers)
+        {
+          d = r.num();
+
+          // Can't use NaN for compare. They are never equal. Use zero instead.  
+          m_key1Value = new Double(d);
+        }
+        else
+        {
+          m_key1Value = k1.m_col.getCollationKey(r.str());
+        }
+
+        if (r.getType() == XObject.CLASS_NODESET)
+        {
+          // %REVIEW%
+          DTMIterator ni = ((XNodeSet)r).iterRaw();
+          int current = ni.getCurrentNode();
+          if(DTM.NULL == current)
+            current = ni.nextNode();
+
+          // if (ni instanceof ContextNodeList) // %REVIEW%
+          // tryNextKey = (DTM.NULL != current);
+
+          // else abdicate... should never happen, but... -sb
+        }
+
+        if (m_keys.size() > 1)
+        {
+          NodeSortKey k2 = (NodeSortKey) m_keys.elementAt(1);
+
+          XObject r2 = k2.m_selectPat.execute(m_execContext, node,
+                                              k2.m_namespaceContext);
+
+          if (k2.m_treatAsNumbers) {
+            d = r2.num();
+            m_key2Value = new Double(d);
+          } else {
+            m_key2Value = k2.m_col.getCollationKey(r2.str());
+          }
+        }
+
+        /* Leave this in case we decide to use an array later
+        while (kIndex <= m_keys.size() && kIndex < maxkey)
+        {
+          NodeSortKey k = (NodeSortKey)m_keys.elementAt(kIndex);
+          XObject r = k.m_selectPat.execute(m_execContext, node, k.m_namespaceContext);
+          if(k.m_treatAsNumbers)
+            m_KeyValue[kIndex] = r.num();
+          else
+            m_KeyValue[kIndex] = r.str();
+        } */
+      }  // end if not empty    
+    }
+  }  // end NodeCompareElem class
+}
diff --git a/src/main/java/org/apache/xalan/transformer/SerializerSwitcher.java b/src/main/java/org/apache/xalan/transformer/SerializerSwitcher.java
new file mode 100644
index 0000000..73ec2d4
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/SerializerSwitcher.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerSwitcher.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Properties;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xml.serializer.Method;
+import org.apache.xalan.templates.OutputProperties;
+
+import org.xml.sax.ContentHandler;
+
+/**
+ * This is a helper class that decides if Xalan needs to switch
+ * serializers, based on the first output element.
+ */
+public class SerializerSwitcher
+{
+
+  /**
+   * Switch to HTML serializer if element is HTML
+   *
+   *
+   * @param transformer Non-null transformer instance
+   * @param ns Namespace URI of the element
+   * @param localName Local part of name of element
+   *
+   * @throws TransformerException
+   */
+  public static void switchSerializerIfHTML(
+          TransformerImpl transformer, String ns, String localName)
+            throws TransformerException
+  {
+
+    if (null == transformer)
+      return;
+
+    if (((null == ns) || (ns.length() == 0))
+            && localName.equalsIgnoreCase("html"))
+    {
+      // System.out.println("transformer.getOutputPropertyNoDefault(OutputKeys.METHOD): "+
+      //              transformer.getOutputPropertyNoDefault(OutputKeys.METHOD));     
+      // Access at level of hashtable to see if the method has been set.
+      if (null != transformer.getOutputPropertyNoDefault(OutputKeys.METHOD))
+        return;
+
+      // Getting the output properties this way won't cause a clone of 
+      // the properties.
+      Properties prevProperties = transformer.getOutputFormat().getProperties();
+      
+      // We have to make sure we get an output properties with the proper 
+      // defaults for the HTML method.  The easiest way to do this is to 
+      // have the OutputProperties class do it.
+      OutputProperties htmlOutputProperties = new OutputProperties(Method.HTML);
+
+      htmlOutputProperties.copyFrom(prevProperties, true);
+      Properties htmlProperties = htmlOutputProperties.getProperties();
+
+      try
+      {
+//        Serializer oldSerializer = transformer.getSerializer();
+        Serializer oldSerializer = null;
+
+        if (null != oldSerializer)
+        {
+          Serializer serializer =
+            SerializerFactory.getSerializer(htmlProperties);
+
+          Writer writer = oldSerializer.getWriter();
+
+          if (null != writer)
+            serializer.setWriter(writer);
+          else
+          {
+            OutputStream os = oldSerializer.getOutputStream();
+
+            if (null != os)
+              serializer.setOutputStream(os);
+          }
+
+//          transformer.setSerializer(serializer);
+
+          ContentHandler ch = serializer.asContentHandler();
+
+          transformer.setContentHandler(ch);
+        }
+      }
+      catch (java.io.IOException e)
+      {
+        throw new TransformerException(e);
+      }
+    }
+  }
+  
+  /**
+   * Get the value of a property, without using the default properties.  This 
+   * can be used to test if a property has been explicitly set by the stylesheet 
+   * or user.
+   *
+   * @param name The property name, which is a fully-qualified URI.
+   *
+   * @return The value of the property, or null if not found.
+   *
+   * @throws IllegalArgumentException If the property is not supported, 
+   * and is not namespaced.
+   */
+  private static String getOutputPropertyNoDefault(String qnameString, Properties props)
+    throws IllegalArgumentException
+  {    
+    String value = (String)props.get(qnameString);
+    
+    return value;
+  }
+  
+  /**
+   * Switch to HTML serializer if element is HTML
+   *
+   *
+   * @param ns Namespace URI of the element
+   * @param localName Local part of name of element
+   *
+   * @throws TransformerException
+   * @return new contentHandler.
+   */
+  public static Serializer switchSerializerIfHTML(
+          String ns, String localName, Properties props, Serializer oldSerializer)
+            throws TransformerException
+  {
+    Serializer newSerializer = oldSerializer;
+
+    if (((null == ns) || (ns.length() == 0))
+            && localName.equalsIgnoreCase("html"))
+    {
+      // System.out.println("transformer.getOutputPropertyNoDefault(OutputKeys.METHOD): "+
+      //              transformer.getOutputPropertyNoDefault(OutputKeys.METHOD));     
+      // Access at level of hashtable to see if the method has been set.
+      if (null != getOutputPropertyNoDefault(OutputKeys.METHOD, props))
+        return newSerializer;
+
+      // Getting the output properties this way won't cause a clone of 
+      // the properties.
+      Properties prevProperties = props;
+      
+      // We have to make sure we get an output properties with the proper 
+      // defaults for the HTML method.  The easiest way to do this is to 
+      // have the OutputProperties class do it.
+      OutputProperties htmlOutputProperties = new OutputProperties(Method.HTML);
+
+      htmlOutputProperties.copyFrom(prevProperties, true);
+      Properties htmlProperties = htmlOutputProperties.getProperties();
+
+//      try
+      {
+        if (null != oldSerializer)
+        {
+          Serializer serializer =
+            SerializerFactory.getSerializer(htmlProperties);
+
+          Writer writer = oldSerializer.getWriter();
+
+          if (null != writer)
+            serializer.setWriter(writer);
+          else
+          {
+            OutputStream os = serializer.getOutputStream();
+
+            if (null != os)
+              serializer.setOutputStream(os);
+          }
+          newSerializer = serializer;
+        }
+      }
+//      catch (java.io.IOException e)
+//      {
+//        throw new TransformerException(e);
+//      }
+    }
+    return newSerializer;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TrAXFilter.java b/src/main/java/org/apache/xalan/transformer/TrAXFilter.java
new file mode 100644
index 0000000..c32a081
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TrAXFilter.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TrAXFilter.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.io.IOException;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Templates;
+import javax.xml.transform.TransformerConfigurationException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLFilterImpl;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+
+public class TrAXFilter extends XMLFilterImpl
+{
+  private Templates m_templates;
+  private TransformerImpl m_transformer;
+    
+  /**
+   * Construct an empty XML filter, with no parent.
+   *
+   * <p>This filter will have no parent: you must assign a parent
+   * before you start a parse or do any configuration with
+   * setFeature or setProperty.</p>
+   *
+   * @see org.xml.sax.XMLReader#setFeature
+   * @see org.xml.sax.XMLReader#setProperty
+   */
+  public TrAXFilter (Templates templates)
+    throws TransformerConfigurationException
+  {
+    m_templates = templates;
+    m_transformer = (TransformerImpl)templates.newTransformer();
+  }
+  
+  /**
+   * Return the Transformer object used for this XML filter.
+   */
+  public TransformerImpl getTransformer()
+  {
+    return m_transformer;
+  }
+  
+  /** Set the parent reader.
+   *
+   * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 
+   * this filter will obtain its events and to which it will pass its 
+   * configuration requests.  The parent may itself be another filter.</p>
+   *
+   * <p>If there is no parent reader set, any attempt to parse
+   * or to set or get a feature or property will fail.</p>
+   *
+   * @param parent The parent XML reader.
+   * @throws java.lang.NullPointerException If the parent is null.
+   */
+  public void setParent (XMLReader parent)
+  { 
+    super.setParent(parent);
+    
+    if(null != parent.getContentHandler())
+      this.setContentHandler(parent.getContentHandler());
+
+    // Not really sure if we should do this here, but 
+    // it seems safer in case someone calls parse() on 
+    // the parent.
+    setupParse ();
+  }
+  
+  /**
+   * Parse a document.
+   *
+   * @param input The input source for the document entity.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @throws java.io.IOException An IO exception from the parser,
+   *            possibly from a byte stream or character stream
+   *            supplied by the application.
+   * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
+   */
+  public void parse (InputSource input)
+    throws org.xml.sax.SAXException, IOException
+  {
+    if(null == getParent())
+    {
+      XMLReader reader=null;
+
+      // Use JAXP1.1 ( if possible )
+      try {
+          javax.xml.parsers.SAXParserFactory factory=
+              javax.xml.parsers.SAXParserFactory.newInstance();
+          factory.setNamespaceAware( true );
+          
+          if (m_transformer.getStylesheet().isSecureProcessing()) {
+              try {
+                  factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+              }
+              catch (org.xml.sax.SAXException se) {}
+          }
+          
+          javax.xml.parsers.SAXParser jaxpParser=
+              factory.newSAXParser();
+          reader=jaxpParser.getXMLReader();
+          
+      } catch( javax.xml.parsers.ParserConfigurationException ex ) {
+          throw new org.xml.sax.SAXException( ex );
+      } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
+          throw new org.xml.sax.SAXException( ex1.toString() );
+      } catch( NoSuchMethodError ex2 ) {
+      }
+      catch (AbstractMethodError ame){}
+
+      XMLReader parent;
+      if( reader==null )
+          parent= XMLReaderFactory.createXMLReader();
+      else
+          parent=reader;
+      try
+      {
+        parent.setFeature("http://xml.org/sax/features/namespace-prefixes",
+                          true);
+      }
+      catch (org.xml.sax.SAXException se){}
+      // setParent calls setupParse...
+      setParent(parent);
+    }
+    else
+    {
+      // Make sure everything is set up.
+      setupParse ();
+    }
+    if(null == m_transformer.getContentHandler())
+    {
+      throw new org.xml.sax.SAXException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_CALL_PARSE, null)); //"parse can not be called if the ContentHandler has not been set!");
+    }
+
+    getParent().parse(input);
+    Exception e = m_transformer.getExceptionThrown();
+    if(null != e)
+    {
+      if(e instanceof org.xml.sax.SAXException)
+        throw (org.xml.sax.SAXException)e;
+      else
+        throw new org.xml.sax.SAXException(e);
+    }
+  }
+  
+  /**
+   * Parse a document.
+   *
+   * @param systemId The system identifier as a fully-qualified URI.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @throws java.io.IOException An IO exception from the parser,
+   *            possibly from a byte stream or character stream
+   *            supplied by the application.
+   * @see org.xml.sax.XMLReader#parse(java.lang.String)
+   */
+  public void parse (String systemId)
+    throws org.xml.sax.SAXException, IOException
+  {
+    parse(new InputSource(systemId));
+  }
+
+
+  /**
+   * Set up before a parse.
+   *
+   * <p>Before every parse, check whether the parent is
+   * non-null, and re-register the filter for all of the 
+   * events.</p>
+   */
+  private void setupParse ()
+  {
+    XMLReader p = getParent();
+    if (p == null) {
+      throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_PARENT_FOR_FILTER, null)); //"No parent for filter");
+    }
+    
+    ContentHandler ch = m_transformer.getInputContentHandler();
+//    if(ch instanceof SourceTreeHandler)
+//      ((SourceTreeHandler)ch).setUseMultiThreading(true);
+    p.setContentHandler(ch);
+    p.setEntityResolver(this);
+    p.setDTDHandler(this);
+    p.setErrorHandler(this);
+  }
+
+  /**
+   * Set the content event handler.
+   *
+   * @param handler The new content handler.
+   * @throws java.lang.NullPointerException If the handler
+   *            is null.
+   * @see org.xml.sax.XMLReader#setContentHandler
+   */
+  public void setContentHandler (ContentHandler handler)
+  {
+    m_transformer.setContentHandler(handler);
+    // super.setContentHandler(m_transformer.getResultTreeHandler());
+  }
+  
+  public void setErrorListener (ErrorListener handler)
+  {
+    m_transformer.setErrorListener(handler);
+  }
+
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TransformState.java b/src/main/java/org/apache/xalan/transformer/TransformState.java
new file mode 100644
index 0000000..3f04554
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TransformState.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformState.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import javax.xml.transform.Transformer;
+
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xml.serializer.TransformStateSetter;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * This interface is meant to be used by a consumer of
+ * SAX2 events produced by Xalan, and enables the consumer
+ * to get information about the state of the transform.  It
+ * is primarily intended as a tooling interface.  A content
+ * handler can get a reference to a TransformState by implementing
+ * the TransformerClient interface.  Xalan will check for
+ * that interface before it calls startDocument, and, if it
+ * is implemented, pass in a TransformState reference to the
+ * setTransformState method.
+ *
+ * <p>Note that the current stylesheet and root stylesheet can
+ * be retrieved from the ElemTemplateElement obtained from
+ * either getCurrentElement() or getCurrentTemplate().</p>
+ * 
+ * This interface contains only getter methods, any setters are in the interface
+ * TransformStateSetter which this interface extends.
+ * 
+ * @see org.apache.xml.serializer.TransformStateSetter
+ */
+public interface TransformState extends TransformStateSetter
+{
+
+  /**
+   * Retrieves the stylesheet element that produced
+   * the SAX event.
+   *
+   * <p>Please note that the ElemTemplateElement returned may
+   * be in a default template, and thus may not be
+   * defined in the stylesheet.</p>
+   *
+   * @return the stylesheet element that produced the SAX event.
+   */
+  ElemTemplateElement getCurrentElement();
+
+  /**
+   * This method retrieves the current context node
+   * in the source tree.
+   *
+   * @return the current context node in the source tree.
+   */
+  Node getCurrentNode();
+
+  /**
+   * This method retrieves the xsl:template
+   * that is in effect, which may be a matched template
+   * or a named template.
+   *
+   * <p>Please note that the ElemTemplate returned may
+   * be a default template, and thus may not have a template
+   * defined in the stylesheet.</p>
+   *
+   * @return the xsl:template that is in effect
+   */
+  ElemTemplate getCurrentTemplate();
+
+  /**
+   * This method retrieves the xsl:template
+   * that was matched.  Note that this may not be
+   * the same thing as the current template (which
+   * may be from getCurrentElement()), since a named
+   * template may be in effect.
+   *
+   * <p>Please note that the ElemTemplate returned may
+   * be a default template, and thus may not have a template
+   * defined in the stylesheet.</p>
+   *
+   * @return the xsl:template that was matched.
+   */
+  ElemTemplate getMatchedTemplate();
+
+  /**
+   * Retrieves the node in the source tree that matched
+   * the template obtained via getMatchedTemplate().
+   *
+   * @return the node in the source tree that matched
+   * the template obtained via getMatchedTemplate().
+   */
+  Node getMatchedNode();
+
+  /**
+   * Get the current context node list.
+   *
+   * @return the current context node list.
+   */
+  NodeIterator getContextNodeList();
+
+  /**
+   * Get the TrAX Transformer object in effect.
+   *
+   * @return the TrAX Transformer object in effect.
+   */
+  Transformer getTransformer();
+  
+
+    
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TransformerClient.java b/src/main/java/org/apache/xalan/transformer/TransformerClient.java
new file mode 100644
index 0000000..b35b036
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TransformerClient.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformerClient.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+/**
+ * A content handler can get a reference
+ * to a TransformState by implementing
+ * the TransformerClient interface.  Xalan will check for
+ * that interface before it calls startDocument, and, if it
+ * is implemented, pass in a TransformState reference to the
+ * setTransformState method.
+ */
+public interface TransformerClient
+{
+
+  /**
+   * Pass in a reference to a TransformState object, which
+   * can be used during SAX ContentHandler events to obtain
+   * information about he state of the transformation. This
+   * method will be called  before each startDocument event.
+   *
+   * @param ts A reference to a TransformState object
+   */
+  void setTransformState(TransformState ts);
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TransformerHandlerImpl.java b/src/main/java/org/apache/xalan/transformer/TransformerHandlerImpl.java
new file mode 100644
index 0000000..3f4c948
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TransformerHandlerImpl.java
@@ -0,0 +1,1080 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformerHandlerImpl.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.io.IOException;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.ref.IncrementalSAXSource_Filter;
+import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
+import org.apache.xpath.XPathContext;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.DeclHandler;
+import org.xml.sax.ext.LexicalHandler;
+import org.apache.xml.serializer.SerializationHandler;
+
+
+/**
+ * A TransformerHandler
+ * listens for SAX ContentHandler parse events and transforms
+ * them to a Result.
+ */
+public class TransformerHandlerImpl
+        implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
+                   LexicalHandler, TransformerHandler, DeclHandler
+{
+    /**
+     * The flag for the setting of the optimize feature;
+     */    
+    private final boolean m_optimizer;
+
+    /**
+     * The flag for the setting of the incremental feature;
+     */    
+    private final boolean m_incremental;
+
+    /**
+     * The flag for the setting of the source_location feature;
+     */  
+    private final boolean m_source_location;
+  
+  private boolean m_insideParse = false;
+
+  ////////////////////////////////////////////////////////////////////
+  // Constructors.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Construct a TransformerHandlerImpl.
+   *
+   * @param transformer Non-null reference to the Xalan transformer impl.
+   * @param doFragment True if the result should be a document fragement.
+   * @param baseSystemID  The system ID to use as the base for relative URLs.
+   */
+  public TransformerHandlerImpl(TransformerImpl transformer,
+                                boolean doFragment, String baseSystemID)
+  {
+
+    super();
+
+    m_transformer = transformer;
+    m_baseSystemID = baseSystemID;
+
+    XPathContext xctxt = transformer.getXPathContext();
+    DTM dtm = xctxt.getDTM(null, true, transformer, true, true);
+    
+    m_dtm = dtm;
+    dtm.setDocumentBaseURI(baseSystemID);
+
+    m_contentHandler = dtm.getContentHandler();
+    m_dtdHandler = dtm.getDTDHandler();
+    m_entityResolver = dtm.getEntityResolver();
+    m_errorHandler = dtm.getErrorHandler();
+    m_lexicalHandler = dtm.getLexicalHandler();
+    m_incremental = transformer.getIncremental();
+    m_optimizer = transformer.getOptimize();
+    m_source_location = transformer.getSource_location();
+  }
+  
+  /** 
+   * Do what needs to be done to shut down the CoRoutine management.
+   */
+  protected void clearCoRoutine()
+  {
+    clearCoRoutine(null);
+  }
+  
+  /** 
+   * Do what needs to be done to shut down the CoRoutine management.
+   */
+  protected void clearCoRoutine(SAXException ex)
+  {
+    if(null != ex)
+      m_transformer.setExceptionThrown(ex);
+    
+    if(m_dtm instanceof SAX2DTM)
+    {
+      if(DEBUG)
+        System.err.println("In clearCoRoutine...");
+      try
+      {
+        SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);          
+        if(null != m_contentHandler 
+           && m_contentHandler instanceof IncrementalSAXSource_Filter)
+        {
+          IncrementalSAXSource_Filter sp =
+            (IncrementalSAXSource_Filter)m_contentHandler;
+          // This should now be all that's needed.
+          sp.deliverMoreNodes(false);
+        }
+        
+        sax2dtm.clearCoRoutine(true);
+        m_contentHandler = null;
+        m_dtdHandler = null;
+        m_entityResolver = null;
+        m_errorHandler = null;
+        m_lexicalHandler = null;
+      }
+      catch(Throwable throwable)
+      {
+        throwable.printStackTrace();
+      }
+      
+      if(DEBUG)
+        System.err.println("...exiting clearCoRoutine");
+    }
+  }
+  
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of javax.xml.transform.sax.TransformerHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Enables the user of the TransformerHandler to set the
+   * to set the Result for the transformation.
+   *
+   * @param result A Result instance, should not be null.
+   *
+   * @throws IllegalArgumentException if result is invalid for some reason.
+   */
+  public void setResult(Result result) throws IllegalArgumentException
+  {
+
+    if (null == result)
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_NULL, null)); //"result should not be null");
+
+    try
+    {
+//      ContentHandler handler =
+//        m_transformer.createResultContentHandler(result);
+//      m_transformer.setContentHandler(handler);
+        SerializationHandler xoh = 
+            m_transformer.createSerializationHandler(result);
+        m_transformer.setSerializationHandler(xoh);
+    }
+    catch (javax.xml.transform.TransformerException te)
+    {
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_COULD_NOT_BE_SET, null)); //"result could not be set");
+    }
+
+    m_result = result;
+  }
+
+  /**
+   * Set the base ID (URI or system ID) from where relative
+   * URLs will be resolved.
+   * @param systemID Base URI for the source tree.
+   */
+  public void setSystemId(String systemID)
+  {
+    m_baseSystemID = systemID;
+    m_dtm.setDocumentBaseURI(systemID);
+  }
+
+  /**
+   * Get the base ID (URI or system ID) from where relative
+   * URLs will be resolved.
+   * @return The systemID that was set with {@link #setSystemId}.
+   */
+  public String getSystemId()
+  {
+    return m_baseSystemID;
+  }
+
+  /**
+   * Get the Transformer associated with this handler, which
+   * is needed in order to set parameters and output properties.
+   *
+   * @return The Transformer associated with this handler
+   */
+  public Transformer getTransformer()
+  {
+    return m_transformer;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.EntityResolver.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Filter an external entity resolution.
+   *
+   * @param publicId The entity's public identifier, or null.
+   * @param systemId The entity's system identifier.
+   * @return A new InputSource or null for the default.
+   *
+   * @throws IOException
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @throws java.io.IOException The client may throw an
+   *            I/O-related exception while obtaining the
+   *            new InputSource.
+   * @see org.xml.sax.EntityResolver#resolveEntity
+   */
+  public InputSource resolveEntity(String publicId, String systemId)
+          throws SAXException, IOException
+  {
+
+    if (m_entityResolver != null)
+    {
+      return m_entityResolver.resolveEntity(publicId, systemId);
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.DTDHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Filter a notation declaration event.
+   *
+   * @param name The notation name.
+   * @param publicId The notation's public identifier, or null.
+   * @param systemId The notation's system identifier, or null.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.DTDHandler#notationDecl
+   */
+  public void notationDecl(String name, String publicId, String systemId)
+          throws SAXException
+  {
+
+    if (m_dtdHandler != null)
+    {
+      m_dtdHandler.notationDecl(name, publicId, systemId);
+    }
+  }
+
+  /**
+   * Filter an unparsed entity declaration event.
+   *
+   * @param name The entity name.
+   * @param publicId The entity's public identifier, or null.
+   * @param systemId The entity's system identifier, or null.
+   * @param notationName The name of the associated notation.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void unparsedEntityDecl(
+          String name, String publicId, String systemId, String notationName)
+            throws SAXException
+  {
+
+    if (m_dtdHandler != null)
+    {
+      m_dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.ContentHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Filter a new document locator event.
+   *
+   * @param locator The document locator.
+   * @see org.xml.sax.ContentHandler#setDocumentLocator
+   */
+  public void setDocumentLocator(Locator locator)
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#setDocumentLocator: "
+                         + locator.getSystemId());
+
+    this.m_locator = locator;
+    
+    if(null == m_baseSystemID)
+    {
+      setSystemId(locator.getSystemId());
+    }
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.setDocumentLocator(locator);
+    }
+  }
+
+  /**
+   * Filter a start document event.
+   *
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#startDocument
+   */
+  public void startDocument() throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startDocument");
+      
+    m_insideParse = true;
+
+   // Thread listener = new Thread(m_transformer);
+
+    if (m_contentHandler != null)
+    {
+      //m_transformer.setTransformThread(listener);
+      if(m_incremental)
+      {
+        m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
+            
+        int cpriority = Thread.currentThread().getPriority();
+    
+        // runTransformThread is equivalent with the 2.0.1 code,
+        // except that the Thread may come from a pool.
+        m_transformer.runTransformThread( cpriority );
+      }
+
+      // This is now done _last_, because IncrementalSAXSource_Filter
+      // will immediately go into a "wait until events are requested"
+      // pause. I believe that will close our timing window.
+      // %REVIEW%
+      m_contentHandler.startDocument();
+   }
+        
+   //listener.setDaemon(false);
+   //listener.start();
+
+  }
+
+  /**
+   * Filter an end document event.
+   *
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#endDocument
+   */
+  public void endDocument() throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endDocument");
+
+    m_insideParse = false;
+    
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.endDocument();
+    }
+    
+    if(m_incremental)
+    {
+      m_transformer.waitTransformThread();
+    }
+    else
+    {
+      m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
+      m_transformer.run();
+    }
+   /* Thread transformThread = m_transformer.getTransformThread();
+
+    if (null != transformThread)
+    {
+      try
+      {
+
+        // This should wait until the transformThread is considered not alive.
+        transformThread.join();
+
+        if (!m_transformer.hasTransformThreadErrorCatcher())
+        {
+          Exception e = m_transformer.getExceptionThrown();
+
+          if (null != e)
+            throw new org.xml.sax.SAXException(e);
+        }
+
+        m_transformer.setTransformThread(null);
+      }
+      catch (InterruptedException ie){}
+    }*/
+  }
+
+  /**
+   * Filter a start Namespace prefix mapping event.
+   *
+   * @param prefix The Namespace prefix.
+   * @param uri The Namespace URI.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#startPrefixMapping
+   */
+  public void startPrefixMapping(String prefix, String uri)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startPrefixMapping: "
+                         + prefix + ", " + uri);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.startPrefixMapping(prefix, uri);
+    }
+  }
+
+  /**
+   * Filter an end Namespace prefix mapping event.
+   *
+   * @param prefix The Namespace prefix.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#endPrefixMapping
+   */
+  public void endPrefixMapping(String prefix) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endPrefixMapping: "
+                         + prefix);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.endPrefixMapping(prefix);
+    }
+  }
+
+  /**
+   * Filter a start element event.
+   *
+   * @param uri The element's Namespace URI, or the empty string.
+   * @param localName The element's local name, or the empty string.
+   * @param qName The element's qualified (prefixed) name, or the empty
+   *        string.
+   * @param atts The element's attributes.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#startElement
+   */
+  public void startElement(
+          String uri, String localName, String qName, Attributes atts)
+            throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startElement: " + qName);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.startElement(uri, localName, qName, atts);
+    }
+  }
+
+  /**
+   * Filter an end element event.
+   *
+   * @param uri The element's Namespace URI, or the empty string.
+   * @param localName The element's local name, or the empty string.
+   * @param qName The element's qualified (prefixed) name, or the empty
+   *        string.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#endElement
+   */
+  public void endElement(String uri, String localName, String qName)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endElement: " + qName);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.endElement(uri, localName, qName);
+    }
+  }
+
+  /**
+   * Filter a character data event.
+   *
+   * @param ch An array of characters.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#characters
+   */
+  public void characters(char ch[], int start, int length) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#characters: " + start + ", "
+                         + length);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.characters(ch, start, length);
+    }
+  }
+
+  /**
+   * Filter an ignorable whitespace event.
+   *
+   * @param ch An array of characters.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#ignorableWhitespace
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#ignorableWhitespace: "
+                         + start + ", " + length);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.ignorableWhitespace(ch, start, length);
+    }
+  }
+
+  /**
+   * Filter a processing instruction event.
+   *
+   * @param target The processing instruction target.
+   * @param data The text following the target.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   */
+  public void processingInstruction(String target, String data)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#processingInstruction: "
+                         + target + ", " + data);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.processingInstruction(target, data);
+    }
+  }
+
+  /**
+   * Filter a skipped entity event.
+   *
+   * @param name The name of the skipped entity.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ContentHandler#skippedEntity
+   */
+  public void skippedEntity(String name) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#skippedEntity: " + name);
+
+    if (m_contentHandler != null)
+    {
+      m_contentHandler.skippedEntity(name);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.ErrorHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Filter a warning event.
+   *
+   * @param e The nwarning as an exception.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ErrorHandler#warning
+   */
+  public void warning(SAXParseException e) throws SAXException
+  {
+    // This is not great, but we really would rather have the error 
+    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
+    // can't really be configured, so I think this is the best thing right now 
+    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
+    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
+    if(errorListener instanceof ErrorHandler)
+    {
+      ((ErrorHandler)errorListener).warning(e);
+    }
+    else
+    {
+      try
+      {
+        errorListener.warning(new javax.xml.transform.TransformerException(e));
+      }
+      catch(javax.xml.transform.TransformerException te)
+      {
+        throw e;
+      }
+    }
+  }
+
+  /**
+   * Filter an error event.
+   *
+   * @param e The error as an exception.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ErrorHandler#error
+   */
+  public void error(SAXParseException e) throws SAXException
+  {
+    // %REVIEW% I don't think this should be called.  -sb
+    // clearCoRoutine(e);
+
+    // This is not great, but we really would rather have the error 
+    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
+    // can't really be configured, so I think this is the best thing right now 
+    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
+    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
+    if(errorListener instanceof ErrorHandler)
+    {
+      ((ErrorHandler)errorListener).error(e);
+      if(null != m_errorHandler)
+        m_errorHandler.error(e); // may not be called.
+    }
+    else
+    {
+      try
+      {
+        errorListener.error(new javax.xml.transform.TransformerException(e));
+        if(null != m_errorHandler)
+          m_errorHandler.error(e); // may not be called.
+      }
+      catch(javax.xml.transform.TransformerException te)
+      {
+        throw e;
+      }
+    }
+  }
+
+  /**
+   * Filter a fatal error event.
+   *
+   * @param e The error as an exception.
+   * @throws SAXException The client may throw
+   *            an exception during processing.
+   * @see org.xml.sax.ErrorHandler#fatalError
+   */
+  public void fatalError(SAXParseException e) throws SAXException
+  {
+    if(null != m_errorHandler)
+    {
+      try
+      {
+        m_errorHandler.fatalError(e);
+      }
+      catch(SAXParseException se)
+      {
+        // ignore
+      }
+      // clearCoRoutine(e);
+    }
+
+    // This is not great, but we really would rather have the error 
+    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
+    // can't really be configured, so I think this is the best thing right now 
+    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
+    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
+    
+    if(errorListener instanceof ErrorHandler)
+    {
+      ((ErrorHandler)errorListener).fatalError(e);
+      if(null != m_errorHandler)
+        m_errorHandler.fatalError(e); // may not be called.
+    }
+    else
+    {
+      try
+      {
+        errorListener.fatalError(new javax.xml.transform.TransformerException(e));
+        if(null != m_errorHandler)
+          m_errorHandler.fatalError(e); // may not be called.
+      }
+      catch(javax.xml.transform.TransformerException te)
+      {
+        throw e;
+      }
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.ext.LexicalHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Report the start of DTD declarations, if any.
+   *
+   * <p>Any declarations are assumed to be in the internal subset
+   * unless otherwise indicated by a {@link #startEntity startEntity}
+   * event.</p>
+   *
+   * <p>Note that the start/endDTD events will appear within
+   * the start/endDocument events from ContentHandler and
+   * before the first startElement event.</p>
+   *
+   * @param name The document type name.
+   * @param publicId The declared public identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @param systemId The declared system identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @throws SAXException The application may raise an
+   *            exception.
+   * @see #endDTD
+   * @see #startEntity
+   */
+  public void startDTD(String name, String publicId, String systemId)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startDTD: " + name + ", "
+                         + publicId + ", " + systemId);
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.startDTD(name, publicId, systemId);
+    }
+  }
+
+  /**
+   * Report the end of DTD declarations.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startDTD
+   */
+  public void endDTD() throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endDTD");
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.endDTD();
+    }
+  }
+
+  /**
+   * Report the beginning of an entity in content.
+   *
+   * <p><strong>NOTE:</entity> entity references in attribute
+   * values -- and the start and end of the document entity --
+   * are never reported.</p>
+   *
+   * <p>The start and end of the external DTD subset are reported
+   * using the pseudo-name "[dtd]".  All other events must be
+   * properly nested within start/end entity events.</p>
+   *
+   * <p>Note that skipped entities will be reported through the
+   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+   * event, which is part of the ContentHandler interface.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @throws SAXException The application may raise an exception.
+   * @see #endEntity
+   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+   */
+  public void startEntity(String name) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startEntity: " + name);
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.startEntity(name);
+    }
+  }
+
+  /**
+   * Report the end of an entity.
+   *
+   * @param name The name of the entity that is ending.
+   * @throws SAXException The application may raise an exception.
+   * @see #startEntity
+   */
+  public void endEntity(String name) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endEntity: " + name);
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.endEntity(name);
+    }
+  }
+
+  /**
+   * Report the start of a CDATA section.
+   *
+   * <p>The contents of the CDATA section will be reported through
+   * the regular {@link org.xml.sax.ContentHandler#characters
+   * characters} event.</p>
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #endCDATA
+   */
+  public void startCDATA() throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#startCDATA");
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.startCDATA();
+    }
+  }
+
+  /**
+   * Report the end of a CDATA section.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startCDATA
+   */
+  public void endCDATA() throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#endCDATA");
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.endCDATA();
+    }
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * <p>This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).</p>
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void comment(char ch[], int start, int length) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#comment: " + start + ", "
+                         + length);
+
+    if (null != m_lexicalHandler)
+    {
+      m_lexicalHandler.comment(ch, start, length);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of org.xml.sax.ext.DeclHandler.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Report an element type declaration.
+   *
+   * <p>The content model will consist of the string "EMPTY", the
+   * string "ANY", or a parenthesised group, optionally followed
+   * by an occurrence indicator.  The model will be normalized so
+   * that all whitespace is removed,and will include the enclosing
+   * parentheses.</p>
+   *
+   * @param name The element type name.
+   * @param model The content model as a normalized string.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void elementDecl(String name, String model) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#elementDecl: " + name + ", "
+                         + model);
+
+    if (null != m_declHandler)
+    {
+      m_declHandler.elementDecl(name, model);
+    }
+  }
+
+  /**
+   * Report an attribute type declaration.
+   *
+   * <p>Only the effective (first) declaration for an attribute will
+   * be reported.  The type will be one of the strings "CDATA",
+   * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+   * "ENTITIES", or "NOTATION", or a parenthesized token group with
+   * the separator "|" and all whitespace removed.</p>
+   *
+   * @param eName The name of the associated element.
+   * @param aName The name of the attribute.
+   * @param type A string representing the attribute type.
+   * @param valueDefault A string representing the attribute default
+   *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+   *        none of these applies.
+   * @param value A string representing the attribute's default value,
+   *        or null if there is none.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void attributeDecl(
+          String eName, String aName, String type, String valueDefault, String value)
+            throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#attributeDecl: " + eName
+                         + ", " + aName + ", etc...");
+
+    if (null != m_declHandler)
+    {
+      m_declHandler.attributeDecl(eName, aName, type, valueDefault, value);
+    }
+  }
+
+  /**
+   * Report an internal entity declaration.
+   *
+   * <p>Only the effective (first) declaration for each entity
+   * will be reported.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @param value The replacement text of the entity.
+   * @throws SAXException The application may raise an exception.
+   * @see #externalEntityDecl
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void internalEntityDecl(String name, String value)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#internalEntityDecl: " + name
+                         + ", " + value);
+
+    if (null != m_declHandler)
+    {
+      m_declHandler.internalEntityDecl(name, value);
+    }
+  }
+
+  /**
+   * Report a parsed external entity declaration.
+   *
+   * <p>Only the effective (first) declaration for each entity
+   * will be reported.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @param publicId The declared public identifier of the entity, or
+   *        null if none was declared.
+   * @param systemId The declared system identifier of the entity.
+   * @throws SAXException The application may raise an exception.
+   * @see #internalEntityDecl
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void externalEntityDecl(
+          String name, String publicId, String systemId) throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("TransformerHandlerImpl#externalEntityDecl: " + name
+                         + ", " + publicId + ", " + systemId);
+
+    if (null != m_declHandler)
+    {
+      m_declHandler.externalEntityDecl(name, publicId, systemId);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Internal state.
+  ////////////////////////////////////////////////////////////////////
+
+  /** Set to true for diagnostics output.         */
+  private static boolean DEBUG = false;
+
+  /**
+   * The transformer this will use to transform a
+   * source tree into a result tree.
+   */
+  private TransformerImpl m_transformer;
+
+  /** The system ID to use as a base for relative URLs. */
+  private String m_baseSystemID;
+
+  /** The result for the transformation. */
+  private Result m_result = null;
+
+  /** The locator for this TransformerHandler. */
+  private Locator m_locator = null;
+
+  /** The entity resolver to aggregate to. */
+  private EntityResolver m_entityResolver = null;
+
+  /** The DTD handler to aggregate to. */
+  private DTDHandler m_dtdHandler = null;
+
+  /** The content handler to aggregate to. */
+  private ContentHandler m_contentHandler = null;
+
+  /** The error handler to aggregate to. */
+  private ErrorHandler m_errorHandler = null;
+
+  /** The lexical handler to aggregate to. */
+  private LexicalHandler m_lexicalHandler = null;
+
+  /** The decl handler to aggregate to. */
+  private DeclHandler m_declHandler = null;
+  
+  /** The Document Table Instance we are transforming. */
+  DTM m_dtm;
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TransformerIdentityImpl.java b/src/main/java/org/apache/xalan/transformer/TransformerIdentityImpl.java
new file mode 100644
index 0000000..c7b2534
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TransformerIdentityImpl.java
@@ -0,0 +1,1481 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformerIdentityImpl.java 575747 2007-09-14 16:28:37Z kcormier $
+ */
+package org.apache.xalan.transformer;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xml.serializer.Method;
+import org.apache.xml.utils.DOMBuilder;
+import org.apache.xml.utils.XMLReaderManager;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.DeclHandler;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class implements an identity transformer for
+ * {@link javax.xml.transform.sax.SAXTransformerFactory#newTransformerHandler()}
+ * and {@link javax.xml.transform.TransformerFactory#newTransformer()}.  It
+ * simply feeds SAX events directly to a serializer ContentHandler, if the
+ * result is a stream.  If the result is a DOM, it will send the events to
+ * {@link org.apache.xml.utils.DOMBuilder}.  If the result is another
+ * content handler, it will simply pass the events on.
+ */
+public class TransformerIdentityImpl extends Transformer
+        implements TransformerHandler, DeclHandler
+{
+
+  /**
+   * Constructor TransformerIdentityImpl creates an identity transform.
+   *
+   */
+  public TransformerIdentityImpl(boolean isSecureProcessing)
+  {
+    m_outputFormat = new OutputProperties(Method.XML);
+    m_isSecureProcessing = isSecureProcessing;
+  }
+
+  /**
+   * Constructor TransformerIdentityImpl creates an identity transform.
+   *
+   */
+  public TransformerIdentityImpl()
+  {
+    this(false);
+  }
+
+  /**
+   * Enables the user of the TransformerHandler to set the
+   * to set the Result for the transformation.
+   *
+   * @param result A Result instance, should not be null.
+   *
+   * @throws IllegalArgumentException if result is invalid for some reason.
+   */
+  public void setResult(Result result) throws IllegalArgumentException
+  {
+    if(null == result)
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_NULL, null)); //"Result should not be null");        
+    m_result = result;
+  }
+
+  /**
+   * Set the base ID (URI or system ID) from where relative
+   * URLs will be resolved.
+   * @param systemID Base URI for the source tree.
+   */
+  public void setSystemId(String systemID)
+  {
+    m_systemID = systemID;
+  }
+
+  /**
+   * Get the base ID (URI or system ID) from where relative
+   * URLs will be resolved.
+   * @return The systemID that was set with {@link #setSystemId}.
+   */
+  public String getSystemId()
+  {
+    return m_systemID;
+  }
+
+  /**
+   * Get the Transformer associated with this handler, which
+   * is needed in order to set parameters and output properties.
+   *
+   * @return non-null reference to the transformer.
+   */
+  public Transformer getTransformer()
+  {
+    return this;
+  }
+
+  /**
+   * Reset the status of the transformer.
+   */
+  public void reset()
+  {
+    m_flushedStartDoc = false;
+    m_foundFirstElement = false;
+    m_outputStream = null;
+    clearParameters();
+    m_result = null;
+    m_resultContentHandler = null;
+    m_resultDeclHandler = null;
+    m_resultDTDHandler = null;
+    m_resultLexicalHandler = null;
+    m_serializer = null;
+    m_systemID = null;
+    m_URIResolver = null;
+    m_outputFormat = new OutputProperties(Method.XML);
+  }
+
+  /**
+   * Create a result ContentHandler from a Result object, based
+   * on the current OutputProperties.
+   *
+   * @param outputTarget Where the transform result should go,
+   * should not be null.
+   *
+   * @return A valid ContentHandler that will create the
+   * result tree when it is fed SAX events.
+   *
+   * @throws TransformerException
+   */
+  private void createResultContentHandler(Result outputTarget)
+          throws TransformerException
+  {
+
+    if (outputTarget instanceof SAXResult)
+    {
+      SAXResult saxResult = (SAXResult) outputTarget;
+
+      m_resultContentHandler = saxResult.getHandler();
+      m_resultLexicalHandler = saxResult.getLexicalHandler();
+
+      if (m_resultContentHandler instanceof Serializer)
+      {
+
+        // Dubious but needed, I think.
+        m_serializer = (Serializer) m_resultContentHandler;
+      }
+    }
+    else if (outputTarget instanceof DOMResult)
+    {
+      DOMResult domResult = (DOMResult) outputTarget;
+      Node outputNode = domResult.getNode();
+      Node nextSibling = domResult.getNextSibling();
+      Document doc;
+      short type;
+
+      if (null != outputNode)
+      {
+        type = outputNode.getNodeType();
+        doc = (Node.DOCUMENT_NODE == type)
+              ? (Document) outputNode : outputNode.getOwnerDocument();
+      }
+      else
+      {
+        try
+        {
+          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+          dbf.setNamespaceAware(true);
+
+          if (m_isSecureProcessing)
+          {
+            try
+            {
+              dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            }
+            catch (ParserConfigurationException pce) {}
+          }
+
+          DocumentBuilder db = dbf.newDocumentBuilder();
+
+          doc = db.newDocument();
+        }
+        catch (ParserConfigurationException pce)
+        {
+          throw new TransformerException(pce);
+        }
+
+        outputNode = doc;
+        type = outputNode.getNodeType();
+
+        ((DOMResult) outputTarget).setNode(outputNode);
+      }
+
+      DOMBuilder domBuilder =
+        (Node.DOCUMENT_FRAGMENT_NODE == type)
+        ? new DOMBuilder(doc, (DocumentFragment) outputNode)
+        : new DOMBuilder(doc, outputNode);
+      
+      if (nextSibling != null)
+        domBuilder.setNextSibling(nextSibling);
+      
+      m_resultContentHandler = domBuilder;
+      m_resultLexicalHandler = domBuilder;
+    }
+    else if (outputTarget instanceof StreamResult)
+    {
+      StreamResult sresult = (StreamResult) outputTarget;
+
+      try
+      {
+        Serializer serializer =
+          SerializerFactory.getSerializer(m_outputFormat.getProperties());
+
+        m_serializer = serializer;
+
+        if (null != sresult.getWriter())
+          serializer.setWriter(sresult.getWriter());
+        else if (null != sresult.getOutputStream())
+          serializer.setOutputStream(sresult.getOutputStream());
+        else if (null != sresult.getSystemId())
+        {
+          String fileURL = sresult.getSystemId();
+
+          if (fileURL.startsWith("file:///")) {
+            if (fileURL.substring(8).indexOf(":") >0) {
+              fileURL = fileURL.substring(8);
+            } else  {
+              fileURL = fileURL.substring(7);
+            }
+          } else if (fileURL.startsWith("file:/")) {
+            if (fileURL.substring(6).indexOf(":") >0) {
+              fileURL = fileURL.substring(6);
+            } else {
+              fileURL = fileURL.substring(5);
+            }
+          }
+
+          m_outputStream = new java.io.FileOutputStream(fileURL);
+          serializer.setOutputStream(m_outputStream);
+        }
+        else
+          throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED, null)); //"No output specified!");
+
+        m_resultContentHandler = serializer.asContentHandler();
+      }
+      catch (IOException ioe)
+      {
+        throw new TransformerException(ioe);
+      }
+    }
+    else
+    {
+      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE, new Object[]{outputTarget.getClass().getName()})); //"Can't transform to a Result of type "
+                                    // + outputTarget.getClass().getName()
+                                    // + "!");
+    }
+
+    if (m_resultContentHandler instanceof DTDHandler)
+      m_resultDTDHandler = (DTDHandler) m_resultContentHandler;
+    
+    if (m_resultContentHandler instanceof DeclHandler)
+      m_resultDeclHandler = (DeclHandler) m_resultContentHandler;
+
+    if (m_resultContentHandler instanceof LexicalHandler)
+      m_resultLexicalHandler = (LexicalHandler) m_resultContentHandler;
+  }
+
+  /**
+   * Process the source tree to the output result.
+   * @param source  The input for the source tree.
+   *
+   * @param outputTarget The output target.
+   *
+   * @throws TransformerException If an unrecoverable error occurs
+   * during the course of the transformation.
+   */
+  public void transform(Source source, Result outputTarget)
+          throws TransformerException
+  {
+
+    createResultContentHandler(outputTarget);
+    
+    /*
+     * According to JAXP1.2, new SAXSource()/StreamSource()
+     * should create an empty input tree, with a default root node. 
+     * new DOMSource()creates an empty document using DocumentBuilder.
+     * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations,
+     * since there is no clear spec. how to create an empty tree when
+     * both SAXSource() and StreamSource() are used.
+     */
+    if ((source instanceof StreamSource && source.getSystemId()==null &&
+       ((StreamSource)source).getInputStream()==null &&
+       ((StreamSource)source).getReader()==null)||
+       (source instanceof SAXSource &&
+       ((SAXSource)source).getInputSource()==null &&
+       ((SAXSource)source).getXMLReader()==null )||
+       (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){
+      try {
+        DocumentBuilderFactory builderF = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = builderF.newDocumentBuilder();
+        String systemID = source.getSystemId();
+        source = new DOMSource(builder.newDocument());
+
+        // Copy system ID from original, empty Source to new Source
+        if (systemID != null) {
+          source.setSystemId(systemID);
+        }
+      } catch (ParserConfigurationException e){
+        throw new TransformerException(e.getMessage());
+      }           
+    }
+    
+    try
+    {
+      if (source instanceof DOMSource)
+      {
+        DOMSource dsource = (DOMSource) source;
+  
+        m_systemID = dsource.getSystemId();
+  
+        Node dNode = dsource.getNode();
+  
+        if (null != dNode)
+        {
+          try
+          {
+            if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
+              this.startDocument();
+            try
+            {
+              if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
+              {
+                String data = dNode.getNodeValue();
+                char[] chars = data.toCharArray();
+                characters(chars, 0, chars.length);
+              }
+              else
+              { 
+                org.apache.xml.serializer.TreeWalker walker;
+                walker = new org.apache.xml.serializer.TreeWalker(this, m_systemID);
+                walker.traverse(dNode);
+              }
+            }
+            finally
+            {
+              if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
+                this.endDocument();
+            }
+          }
+          catch (SAXException se)
+          {
+            throw new TransformerException(se);
+          }
+  
+          return;
+        }
+        else
+        {
+          String messageStr = XSLMessages.createMessage(
+            XSLTErrorResources.ER_ILLEGAL_DOMSOURCE_INPUT, null);
+  
+          throw new IllegalArgumentException(messageStr);
+        }
+      }
+  
+      InputSource xmlSource = SAXSource.sourceToInputSource(source);
+  
+      if (null == xmlSource)
+      {
+        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_SOURCE_TYPE, new Object[]{source.getClass().getName()})); //"Can't transform a Source of type "
+                                       //+ source.getClass().getName() + "!");
+      }
+  
+      if (null != xmlSource.getSystemId())
+        m_systemID = xmlSource.getSystemId();
+  
+      XMLReader reader = null;
+      boolean managedReader = false;
+  
+      try
+      {
+        if (source instanceof SAXSource) {
+          reader = ((SAXSource) source).getXMLReader();
+        }
+          
+        if (null == reader) {
+          try {
+            reader = XMLReaderManager.getInstance().getXMLReader();
+            managedReader = true;
+          } catch (SAXException se) {
+            throw new TransformerException(se);
+          }
+        } else {
+          try {
+            reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
+                              true);
+          } catch (org.xml.sax.SAXException se) {
+            // We don't care.
+          }
+        }
+
+        // Get the input content handler, which will handle the 
+        // parse events and create the source tree. 
+        ContentHandler inputHandler = this;
+  
+        reader.setContentHandler(inputHandler);
+  
+        if (inputHandler instanceof org.xml.sax.DTDHandler)
+          reader.setDTDHandler((org.xml.sax.DTDHandler) inputHandler);
+  
+        try
+        {
+          if (inputHandler instanceof org.xml.sax.ext.LexicalHandler)
+            reader.setProperty("http://xml.org/sax/properties/lexical-handler",
+                               inputHandler);
+  
+          if (inputHandler instanceof org.xml.sax.ext.DeclHandler)
+            reader.setProperty(
+              "http://xml.org/sax/properties/declaration-handler",
+              inputHandler);
+        }
+        catch (org.xml.sax.SAXException se){}
+  
+        try
+        {
+          if (inputHandler instanceof org.xml.sax.ext.LexicalHandler)
+            reader.setProperty("http://xml.org/sax/handlers/LexicalHandler",
+                               inputHandler);
+  
+          if (inputHandler instanceof org.xml.sax.ext.DeclHandler)
+            reader.setProperty("http://xml.org/sax/handlers/DeclHandler",
+                               inputHandler);
+        }
+        catch (org.xml.sax.SAXNotRecognizedException snre){}
+  
+        reader.parse(xmlSource);
+      }
+      catch (org.apache.xml.utils.WrappedRuntimeException wre)
+      {
+        Throwable throwable = wre.getException();
+  
+        while (throwable
+               instanceof org.apache.xml.utils.WrappedRuntimeException)
+        {
+          throwable =
+            ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
+        }
+  
+        throw new TransformerException(wre.getException());
+      }
+      catch (org.xml.sax.SAXException se)
+      {
+        throw new TransformerException(se);
+      }
+      catch (IOException ioe)
+      {
+        throw new TransformerException(ioe);
+      } finally {
+        if (managedReader) {
+          XMLReaderManager.getInstance().releaseXMLReader(reader);
+        }
+      }
+    }
+    finally
+    {
+      if(null != m_outputStream)
+      {
+        try
+        {
+          m_outputStream.close();
+        }
+        catch(IOException ioe){}
+        m_outputStream = null;
+      }
+    }
+  }
+
+  /**
+   * Add a parameter for the transformation.
+   *
+   * <p>Pass a qualified name as a two-part string, the namespace URI
+   * enclosed in curly braces ({}), followed by the local name. If the
+   * name has a null URL, the String only contain the local name. An
+   * application can safely check for a non-null URI by testing to see if the first
+   * character of the name is a '{' character.</p>
+   * <p>For example, if a URI and local name were obtained from an element
+   * defined with &lt;xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/&gt;,
+   * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that
+   * no prefix is used.</p>
+   *
+   * @param name The name of the parameter, which may begin with a namespace URI
+   * in curly braces ({}).
+   * @param value The value object.  This can be any valid Java object. It is
+   * up to the processor to provide the proper object coersion or to simply
+   * pass the object on for use in an extension.
+   */
+  public void setParameter(String name, Object value)
+  {
+    if (value == null) {
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE, new Object[]{name}));
+    }
+    
+    if (null == m_params)
+    {
+      m_params = new Hashtable();
+    }
+
+    m_params.put(name, value);
+  }
+
+  /**
+   * Get a parameter that was explicitly set with setParameter
+   * or setParameters.
+   *
+   * <p>This method does not return a default parameter value, which
+   * cannot be determined until the node context is evaluated during
+   * the transformation process.
+   *
+   *
+   * @param name Name of the parameter.
+   * @return A parameter that has been set with setParameter.
+   */
+  public Object getParameter(String name)
+  {
+
+    if (null == m_params)
+      return null;
+
+    return m_params.get(name);
+  }
+
+  /**
+   * Clear all parameters set with setParameter.
+   */
+  public void clearParameters()
+  {
+
+    if (null == m_params)
+      return;
+
+    m_params.clear();
+  }
+
+  /**
+   * Set an object that will be used to resolve URIs used in
+   * document().
+   *
+   * <p>If the resolver argument is null, the URIResolver value will
+   * be cleared, and the default behavior will be used.</p>
+   *
+   * @param resolver An object that implements the URIResolver interface,
+   * or null.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+    m_URIResolver = resolver;
+  }
+
+  /**
+   * Get an object that will be used to resolve URIs used in
+   * document(), etc.
+   *
+   * @return An object that implements the URIResolver interface,
+   * or null.
+   */
+  public URIResolver getURIResolver()
+  {
+    return m_URIResolver;
+  }
+
+  /**
+   * Set the output properties for the transformation.  These
+   * properties will override properties set in the Templates
+   * with xsl:output.
+   *
+   * <p>If argument to this function is null, any properties
+   * previously set are removed, and the value will revert to the value
+   * defined in the templates object.</p>
+   *
+   * <p>Pass a qualified property key name as a two-part string, the namespace URI
+   * enclosed in curly braces ({}), followed by the local name. If the
+   * name has a null URL, the String only contain the local name. An
+   * application can safely check for a non-null URI by testing to see if the first
+   * character of the name is a '{' character.</p>
+   * <p>For example, if a URI and local name were obtained from an element
+   * defined with &lt;xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/&gt;,
+   * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that
+   * no prefix is used.</p>
+   *
+   * @param oformat A set of output properties that will be
+   * used to override any of the same properties in affect
+   * for the transformation.
+   *
+   * @see javax.xml.transform.OutputKeys
+   * @see java.util.Properties
+   *
+   * @throws IllegalArgumentException if any of the argument keys are not
+   * recognized and are not namespace qualified.
+   */
+  public void setOutputProperties(Properties oformat)
+          throws IllegalArgumentException
+  {
+
+    if (null != oformat)
+    {
+
+      // See if an *explicit* method was set.
+      String method = (String) oformat.get(OutputKeys.METHOD);
+
+      if (null != method)
+        m_outputFormat = new OutputProperties(method);
+      else
+        m_outputFormat = new OutputProperties();
+
+      m_outputFormat.copyFrom(oformat);
+    }
+    else {
+      // if oformat is null JAXP says that any props previously set are removed
+      // and we are to revert back to those in the templates object (i.e. Stylesheet).
+      m_outputFormat = null;
+    }
+  }
+
+  /**
+   * Get a copy of the output properties for the transformation.
+   *
+   * <p>The properties returned should contain properties set by the user,
+   * and properties set by the stylesheet, and these properties
+   * are "defaulted" by default properties specified by <a href="http://www.w3.org/TR/xslt#output">section 16 of the
+   * XSL Transformations (XSLT) W3C Recommendation</a>.  The properties that
+   * were specifically set by the user or the stylesheet should be in the base
+   * Properties list, while the XSLT default properties that were not
+   * specifically set should be the default Properties list.  Thus,
+   * getOutputProperties().getProperty(String key) will obtain any
+   * property in that was set by {@link #setOutputProperty},
+   * {@link #setOutputProperties}, in the stylesheet, <em>or</em> the default
+   * properties, while
+   * getOutputProperties().get(String key) will only retrieve properties
+   * that were explicitly set by {@link #setOutputProperty},
+   * {@link #setOutputProperties}, or in the stylesheet.</p>
+   *
+   * <p>Note that mutation of the Properties object returned will not
+   * effect the properties that the transformation contains.</p>
+   *
+   * <p>If any of the argument keys are not recognized and are not
+   * namespace qualified, the property will be ignored.  In other words the
+   * behaviour is not orthogonal with setOutputProperties.</p>
+   *
+   * @return A copy of the set of output properties in effect
+   * for the next transformation.
+   *
+   * @see javax.xml.transform.OutputKeys
+   * @see java.util.Properties
+   */
+  public Properties getOutputProperties()
+  {
+    return (Properties) m_outputFormat.getProperties().clone();
+  }
+
+  /**
+   * Set an output property that will be in effect for the
+   * transformation.
+   *
+   * <p>Pass a qualified property name as a two-part string, the namespace URI
+   * enclosed in curly braces ({}), followed by the local name. If the
+   * name has a null URL, the String only contain the local name. An
+   * application can safely check for a non-null URI by testing to see if the first
+   * character of the name is a '{' character.</p>
+   * <p>For example, if a URI and local name were obtained from an element
+   * defined with &lt;xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/&gt;,
+   * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that
+   * no prefix is used.</p>
+   *
+   * <p>The Properties object that was passed to {@link #setOutputProperties} won't
+   * be effected by calling this method.</p>
+   *
+   * @param name A non-null String that specifies an output
+   * property name, which may be namespace qualified.
+   * @param value The non-null string value of the output property.
+   *
+   * @throws IllegalArgumentException If the property is not supported, and is
+   * not qualified with a namespace.
+   *
+   * @see javax.xml.transform.OutputKeys
+   */
+  public void setOutputProperty(String name, String value)
+          throws IllegalArgumentException
+  {
+
+    if (!OutputProperties.isLegalPropertyKey(name))
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: "
+                                         //+ name);
+
+    m_outputFormat.setProperty(name, value);
+  }
+
+  /**
+   * Get an output property that is in effect for the
+   * transformation.  The property specified may be a property
+   * that was set with setOutputProperty, or it may be a
+   * property specified in the stylesheet.
+   *
+   * @param name A non-null String that specifies an output
+   * property name, which may be namespace qualified.
+   *
+   * @return The string value of the output property, or null
+   * if no property was found.
+   *
+   * @throws IllegalArgumentException If the property is not supported.
+   *
+   * @see javax.xml.transform.OutputKeys
+   */
+  public String getOutputProperty(String name) throws IllegalArgumentException
+  {
+
+    String value = null;
+    OutputProperties props = m_outputFormat;
+
+    value = props.getProperty(name);
+
+    if (null == value)
+    {
+      if (!OutputProperties.isLegalPropertyKey(name))
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: "
+                                          // + name);
+    }
+
+    return value;
+  }
+
+  /**
+   * Set the error event listener in effect for the transformation.
+   *
+   * @param listener The new error listener.
+   * @throws IllegalArgumentException if listener is null.
+   */
+  public void setErrorListener(ErrorListener listener)
+          throws IllegalArgumentException
+  {
+      if (listener == null)
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_ERROR_HANDLER, null));
+      else
+        m_errorListener = listener;
+  }
+
+  /**
+   * Get the error event handler in effect for the transformation.
+   *
+   * @return The current error handler, which should never be null.
+   */
+  public ErrorListener getErrorListener()
+  {
+    return m_errorListener;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Default implementation of DTDHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive notification of a notation declaration.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass if they wish to keep track of the notations
+   * declared in a document.</p>
+   *
+   * @param name The notation name.
+   * @param publicId The notation public identifier, or null if not
+   *                 available.
+   * @param systemId The notation system identifier.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.DTDHandler#notationDecl
+   *
+   * @throws SAXException
+   */
+  public void notationDecl(String name, String publicId, String systemId)
+          throws SAXException
+  {
+    if (null != m_resultDTDHandler)
+      m_resultDTDHandler.notationDecl(name, publicId, systemId);
+  }
+
+  /**
+   * Receive notification of an unparsed entity declaration.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to keep track of the unparsed entities
+   * declared in a document.</p>
+   *
+   * @param name The entity name.
+   * @param publicId The entity public identifier, or null if not
+   *                 available.
+   * @param systemId The entity system identifier.
+   * @param notationName The name of the associated notation.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   *
+   * @throws SAXException
+   */
+  public void unparsedEntityDecl(
+          String name, String publicId, String systemId, String notationName)
+            throws SAXException
+  {
+
+    if (null != m_resultDTDHandler)
+      m_resultDTDHandler.unparsedEntityDecl(name, publicId, systemId,
+                                            notationName);
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Default implementation of ContentHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive a Locator object for document events.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass if they wish to store the locator for use
+   * with other document events.</p>
+   *
+   * @param locator A locator for all SAX document events.
+   * @see org.xml.sax.ContentHandler#setDocumentLocator
+   * @see org.xml.sax.Locator
+   */
+  public void setDocumentLocator(Locator locator)
+  {
+    try
+    {
+      if (null == m_resultContentHandler)
+        createResultContentHandler(m_result);
+    }
+    catch (TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+
+    m_resultContentHandler.setDocumentLocator(locator);
+  }
+
+  /**
+   * Receive notification of the beginning of the document.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the beginning
+   * of a document (such as allocating the root node of a tree or
+   * creating an output file).</p>
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startDocument
+   *
+   * @throws SAXException
+   */
+  public void startDocument() throws SAXException
+  {
+
+    try
+    {
+      if (null == m_resultContentHandler)
+        createResultContentHandler(m_result);
+    }
+    catch (TransformerException te)
+    {
+      throw new SAXException(te.getMessage(), te);
+    }
+
+    // Reset for multiple transforms with this transformer.
+    m_flushedStartDoc = false;
+    m_foundFirstElement = false;
+  }
+  
+  boolean m_flushedStartDoc = false;
+  
+  protected final void flushStartDoc()
+     throws SAXException
+  {
+    if(!m_flushedStartDoc)
+    {
+      if (m_resultContentHandler == null)
+      {
+        try
+        {
+          createResultContentHandler(m_result);
+        }
+        catch(TransformerException te)
+        {
+            throw new SAXException(te);
+        }
+      }
+      m_resultContentHandler.startDocument();
+      m_flushedStartDoc = true;
+    }
+  }
+
+  /**
+   * Receive notification of the end of the document.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end
+   * of a document (such as finalising a tree or closing an output
+   * file).</p>
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endDocument
+   *
+   * @throws SAXException
+   */
+  public void endDocument() throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.endDocument();
+  }
+
+  /**
+   * Receive notification of the start of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each Namespace prefix scope (such as storing the prefix mapping).</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @param uri The Namespace URI mapped to the prefix.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startPrefixMapping
+   *
+   * @throws SAXException
+   */
+  public void startPrefixMapping(String prefix, String uri)
+          throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.startPrefixMapping(prefix, uri);
+  }
+
+  /**
+   * Receive notification of the end of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end of
+   * each prefix mapping.</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endPrefixMapping
+   *
+   * @throws SAXException
+   */
+  public void endPrefixMapping(String prefix) throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.endPrefixMapping(prefix);
+  }
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each element (such as allocating a new tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @param attributes The specified or defaulted attributes.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startElement
+   *
+   * @throws SAXException
+   */
+  public void startElement(
+          String uri, String localName, String qName, Attributes attributes)
+            throws SAXException
+  {
+
+    if (!m_foundFirstElement && null != m_serializer)
+    {
+      m_foundFirstElement = true;
+
+      Serializer newSerializer;
+
+      try
+      {
+        newSerializer = SerializerSwitcher.switchSerializerIfHTML(uri,
+                localName, m_outputFormat.getProperties(), m_serializer);
+      }
+      catch (TransformerException te)
+      {
+        throw new SAXException(te);
+      }
+
+      if (newSerializer != m_serializer)
+      {
+        try
+        {
+          m_resultContentHandler = newSerializer.asContentHandler();
+        }
+        catch (IOException ioe)  // why?
+        {
+          throw new SAXException(ioe);
+        }
+
+        if (m_resultContentHandler instanceof DTDHandler)
+          m_resultDTDHandler = (DTDHandler) m_resultContentHandler;
+
+        if (m_resultContentHandler instanceof LexicalHandler)
+          m_resultLexicalHandler = (LexicalHandler) m_resultContentHandler;
+
+        m_serializer = newSerializer;
+      }
+    }
+    flushStartDoc();
+    m_resultContentHandler.startElement(uri, localName, qName, attributes);
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end of
+   * each element (such as finalising a tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endElement
+   *
+   * @throws SAXException
+   */
+  public void endElement(String uri, String localName, String qName)
+          throws SAXException
+  {
+    m_resultContentHandler.endElement(uri, localName, qName);
+  }
+
+  /**
+   * Receive notification of character data inside an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method to take specific actions for each chunk of character data
+   * (such as adding the data to a node or buffer, or printing it to
+   * a file).</p>
+   *
+   * @param ch The characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#characters
+   *
+   * @throws SAXException
+   */
+  public void characters(char ch[], int start, int length) throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.characters(ch, start, length);
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method to take specific actions for each chunk of ignorable
+   * whitespace (such as adding data to a node or buffer, or printing
+   * it to a file).</p>
+   *
+   * @param ch The whitespace characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#ignorableWhitespace
+   *
+   * @throws SAXException
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws SAXException
+  {
+    m_resultContentHandler.ignorableWhitespace(ch, start, length);
+  }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   *
+   * @throws SAXException
+   */
+  public void processingInstruction(String target, String data)
+          throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.processingInstruction(target, data);
+  }
+
+  /**
+   * Receive notification of a skipped entity.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param name The name of the skipped entity.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   *
+   * @throws SAXException
+   */
+  public void skippedEntity(String name) throws SAXException
+  {
+    flushStartDoc();
+    m_resultContentHandler.skippedEntity(name);
+  }
+
+  /**
+   * Report the start of DTD declarations, if any.
+   *
+   * <p>Any declarations are assumed to be in the internal subset
+   * unless otherwise indicated by a {@link #startEntity startEntity}
+   * event.</p>
+   *
+   * <p>Note that the start/endDTD events will appear within
+   * the start/endDocument events from ContentHandler and
+   * before the first startElement event.</p>
+   *
+   * @param name The document type name.
+   * @param publicId The declared public identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @param systemId The declared system identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @throws SAXException The application may raise an
+   *            exception.
+   * @see #endDTD
+   * @see #startEntity
+   */
+  public void startDTD(String name, String publicId, String systemId)
+          throws SAXException
+  {
+    flushStartDoc();
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.startDTD(name, publicId, systemId);
+  }
+
+  /**
+   * Report the end of DTD declarations.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startDTD
+   */
+  public void endDTD() throws SAXException
+  {
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.endDTD();
+  }
+
+  /**
+   * Report the beginning of an entity in content.
+   *
+   * <p><strong>NOTE:</entity> entity references in attribute
+   * values -- and the start and end of the document entity --
+   * are never reported.</p>
+   *
+   * <p>The start and end of the external DTD subset are reported
+   * using the pseudo-name "[dtd]".  All other events must be
+   * properly nested within start/end entity events.</p>
+   *
+   * <p>Note that skipped entities will be reported through the
+   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+   * event, which is part of the ContentHandler interface.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @throws SAXException The application may raise an exception.
+   * @see #endEntity
+   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+   */
+  public void startEntity(String name) throws SAXException
+  {
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.startEntity(name);
+  }
+
+  /**
+   * Report the end of an entity.
+   *
+   * @param name The name of the entity that is ending.
+   * @throws SAXException The application may raise an exception.
+   * @see #startEntity
+   */
+  public void endEntity(String name) throws SAXException
+  {
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.endEntity(name);
+  }
+
+  /**
+   * Report the start of a CDATA section.
+   *
+   * <p>The contents of the CDATA section will be reported through
+   * the regular {@link org.xml.sax.ContentHandler#characters
+   * characters} event.</p>
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #endCDATA
+   */
+  public void startCDATA() throws SAXException
+  {
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.startCDATA();
+  }
+
+  /**
+   * Report the end of a CDATA section.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startCDATA
+   */
+  public void endCDATA() throws SAXException
+  {
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.endCDATA();
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * <p>This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).</p>
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void comment(char ch[], int start, int length) throws SAXException
+  {
+    flushStartDoc();
+    if (null != m_resultLexicalHandler)
+      m_resultLexicalHandler.comment(ch, start, length);
+  }
+  
+  // Implement DeclHandler
+  
+  /**
+     * Report an element type declaration.
+     *
+     * <p>The content model will consist of the string "EMPTY", the
+     * string "ANY", or a parenthesised group, optionally followed
+     * by an occurrence indicator.  The model will be normalized so
+     * that all whitespace is removed,and will include the enclosing
+     * parentheses.</p>
+     *
+     * @param name The element type name.
+     * @param model The content model as a normalized string.
+     * @exception SAXException The application may raise an exception.
+     */
+    public void elementDecl (String name, String model)
+        throws SAXException
+    {
+                        if (null != m_resultDeclHandler)
+                                m_resultDeclHandler.elementDecl(name, model);
+    }
+
+
+    /**
+     * Report an attribute type declaration.
+     *
+     * <p>Only the effective (first) declaration for an attribute will
+     * be reported.  The type will be one of the strings "CDATA",
+     * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+     * "ENTITIES", or "NOTATION", or a parenthesized token group with 
+     * the separator "|" and all whitespace removed.</p>
+     *
+     * @param eName The name of the associated element.
+     * @param aName The name of the attribute.
+     * @param type A string representing the attribute type.
+     * @param valueDefault A string representing the attribute default
+     *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+     *        none of these applies.
+     * @param value A string representing the attribute's default value,
+     *        or null if there is none.
+     * @exception SAXException The application may raise an exception.
+     */
+    public void attributeDecl (String eName,
+                                        String aName,
+                                        String type,
+                                        String valueDefault,
+                                        String value)
+        throws SAXException
+    {
+      if (null != m_resultDeclHandler)
+                                m_resultDeclHandler.attributeDecl(eName, aName, type, valueDefault, value);
+    }
+
+
+    /**
+     * Report an internal entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param value The replacement text of the entity.
+     * @exception SAXException The application may raise an exception.
+     * @see #externalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void internalEntityDecl (String name, String value)
+        throws SAXException
+    {
+      if (null != m_resultDeclHandler)
+                                m_resultDeclHandler.internalEntityDecl(name, value); 
+    }
+
+
+    /**
+     * Report a parsed external entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param publicId The declared public identifier of the entity, or
+     *        null if none was declared.
+     * @param systemId The declared system identifier of the entity.
+     * @exception SAXException The application may raise an exception.
+     * @see #internalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void externalEntityDecl (String name, String publicId,
+                                             String systemId)
+        throws SAXException
+    {
+      if (null != m_resultDeclHandler)
+                                m_resultDeclHandler.externalEntityDecl(name, publicId, systemId);
+    }
+  
+  /**
+   * This is null unless we own the stream.
+   */
+  private java.io.FileOutputStream m_outputStream = null;
+
+  /** The content handler where result events will be sent. */
+  private ContentHandler m_resultContentHandler;
+
+  /** The lexical handler where result events will be sent. */
+  private LexicalHandler m_resultLexicalHandler;
+
+  /** The DTD handler where result events will be sent. */
+  private DTDHandler m_resultDTDHandler;
+  
+  /** The Decl handler where result events will be sent. */
+  private DeclHandler m_resultDeclHandler;
+
+  /** The Serializer, which may or may not be null. */
+  private Serializer m_serializer;
+
+  /** The Result object. */
+  private Result m_result;
+
+  /**
+   * The system ID, which is unused, but must be returned to fullfill the
+   *  TransformerHandler interface.
+   */
+  private String m_systemID;
+
+  /**
+   * The parameters, which is unused, but must be returned to fullfill the
+   *  Transformer interface.
+   */
+  private Hashtable m_params;
+
+  /** The error listener for TrAX errors and warnings. */
+  private ErrorListener m_errorListener =
+    new org.apache.xml.utils.DefaultErrorHandler(false);
+
+  /**
+   * The URIResolver, which is unused, but must be returned to fullfill the
+   *  TransformerHandler interface.
+   */
+  URIResolver m_URIResolver;
+
+  /** The output properties. */
+  private OutputProperties m_outputFormat;
+
+  /** Flag to set if we've found the first element, so we can tell if we have 
+   *  to check to see if we should create an HTML serializer.      */
+  boolean m_foundFirstElement;
+  
+  /**
+   * State of the secure processing feature.
+   */
+  private boolean m_isSecureProcessing = false;
+}
diff --git a/src/main/java/org/apache/xalan/transformer/TransformerImpl.java b/src/main/java/org/apache/xalan/transformer/TransformerImpl.java
new file mode 100644
index 0000000..cf550b9
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TransformerImpl.java
@@ -0,0 +1,3271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformerImpl.java 475979 2006-11-16 23:32:48Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xalan.extensions.ExtensionsTable;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.serializer.Method;
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xalan.templates.AVT;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemAttributeSet;
+import org.apache.xalan.templates.ElemForEach;
+import org.apache.xalan.templates.ElemSort;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemTextLiteral;
+import org.apache.xalan.templates.ElemVariable;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.StylesheetComposed;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.XUnresolvedVariable;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.serializer.ToSAXHandler;
+import org.apache.xml.serializer.ToTextStream;
+import org.apache.xml.serializer.ToXMLSAXHandler;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.BoolStack;
+import org.apache.xml.utils.DOMBuilder;
+import org.apache.xml.utils.NodeVector;
+import org.apache.xml.utils.ObjectPool;
+import org.apache.xml.utils.ObjectStack;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xml.utils.ThreadControllerWrapper;
+import org.apache.xpath.Arg;
+import org.apache.xpath.ExtensionsProvider;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.objects.XObject;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class implements the
+ * {@link javax.xml.transform.Transformer} interface, and is the core
+ * representation of the transformation execution.</p>
+ * @xsl.usage advanced
+ */
+public class TransformerImpl extends Transformer
+        implements Runnable, DTMWSFilter, ExtensionsProvider, org.apache.xml.serializer.SerializerTrace
+{
+
+  // Synch object to gaurd against setting values from the TrAX interface 
+  // or reentry while the transform is going on.
+
+  /** NEEDSDOC Field m_reentryGuard          */
+  private Boolean m_reentryGuard = new Boolean(true);
+
+  /**
+   * This is null unless we own the stream.
+   */
+  private java.io.FileOutputStream m_outputStream = null;
+
+  /** The thread that the transformer is running on. */
+  private Thread m_transformThread;
+
+  /** The base URL of the source tree. */
+  private String m_urlOfSource = null;
+
+  /** The Result object at the start of the transform, if any. */
+  private Result m_outputTarget = null;
+
+  /**
+   * The output format object set by the user.  May be null.
+   */
+  private OutputProperties m_outputFormat;
+
+
+  /**
+   * The content handler for the source input tree.
+   */
+  ContentHandler m_inputContentHandler;
+
+  /**
+   * The content handler for the result tree.
+   */
+  private ContentHandler m_outputContentHandler = null;
+
+  //  /*
+  //   * Use member variable to store param variables as they're
+  //   * being created, use member variable so we don't
+  //   * have to create a new vector every time.
+  //   */
+  //  private Vector m_newVars = new Vector();
+
+  /**
+   * A pool of ResultTreeHandlers, for serialization of a subtree to text.
+   *  Please note that each of these also holds onto a Text Serializer.  
+   */
+  private ObjectPool m_textResultHandlerObjectPool =
+    new ObjectPool(ToTextStream.class);
+
+  /**
+   * Related to m_textResultHandlerObjectPool, this is a pool of
+   * StringWriters, which are passed to the Text Serializers.
+   * (I'm not sure if this is really needed any more.  -sb)      
+   */
+  private ObjectPool m_stringWriterObjectPool =
+    new ObjectPool(StringWriter.class);
+
+  /**
+   * A static text format object, which can be used over and
+   * over to create the text serializers.    
+   */
+  private OutputProperties m_textformat = new OutputProperties(Method.TEXT);
+
+  // Commenteded out in response to problem reported by 
+  // Nicola Brown <Nicola.Brown@jacobsrimell.com>
+  //  /**
+  //   * Flag to let us know if an exception should be reported inside the 
+  //   * postExceptionFromThread method.  This is needed if the transform is 
+  //   * being generated from SAX events, and thus there is no central place 
+  //   * to report the exception from.  (An exception is usually picked up in 
+  //   * the main thread from the transform thread in {@link #transform(Source source)} 
+  //   * from {@link #getExceptionThrown()}. )
+  //   */
+  //  private boolean m_reportInPostExceptionFromThread = false;
+
+  /**
+   * A node vector used as a stack to track the current
+   * ElemTemplateElement.  Needed for the
+   * org.apache.xalan.transformer.TransformState interface,
+   * so a tool can discover the calling template. Note the use of an array 
+   * for this limits the recursion depth to 4K.
+   */
+  ObjectStack m_currentTemplateElements 
+      = new ObjectStack(XPathContext.RECURSIONLIMIT);
+  
+  /** The top of the currentTemplateElements stack. */
+  //int m_currentTemplateElementsTop = 0;
+
+  /**
+   * A node vector used as a stack to track the current
+   * ElemTemplate that was matched.
+   * Needed for the
+   * org.apache.xalan.transformer.TransformState interface,
+   * so a tool can discover the matched template
+   */
+  Stack m_currentMatchTemplates = new Stack();
+
+  /**
+   * A node vector used as a stack to track the current
+   * node that was matched.
+   * Needed for the
+   * org.apache.xalan.transformer.TransformState interface,
+   * so a tool can discover the matched
+   * node. 
+   */
+  NodeVector m_currentMatchedNodes = new NodeVector();
+
+  /**
+   * The root of a linked set of stylesheets.
+   */
+  private StylesheetRoot m_stylesheetRoot = null;
+
+  /**
+   * If this is set to true, do not warn about pattern
+   * match conflicts.
+   */
+  private boolean m_quietConflictWarnings = true;
+
+  /**
+   * The liason to the XML parser, so the XSL processor
+   * can handle included files, and the like, and do the
+   * initial parse of the XSL document.
+   */
+  private XPathContext m_xcontext;
+
+  /**
+   * Output handler to bottleneck SAX events.
+   */
+  private SerializationHandler m_serializationHandler;  
+
+  /** The key manager, which manages xsl:keys. */
+  private KeyManager m_keyManager = new KeyManager();
+
+  /**
+   * Stack for the purposes of flagging infinite recursion with
+   * attribute sets.
+   */
+  Stack m_attrSetStack = null;
+
+  /**
+   * The table of counters for xsl:number support.
+   */
+  CountersTable m_countersTable = null;
+
+  /**
+   * Is > 0 when we're processing a for-each.
+   */
+  BoolStack m_currentTemplateRuleIsNull = new BoolStack();
+
+  /**
+   * Keeps track of the result delivered by any EXSLT <code>func:result</code>
+   * instruction that has been executed for the currently active EXSLT
+   * <code>func:function</code>
+   */
+  ObjectStack m_currentFuncResult = new ObjectStack();
+  
+  /**
+   * The message manager, which manages error messages, warning
+   * messages, and other types of message events.   
+   */
+  private MsgMgr m_msgMgr;
+
+  /**
+   * The flag for the setting of the optimize feature;
+   * This flag should have the same value as the FEATURE_OPTIMIZE feature
+   * which is set by the TransformerFactory.setAttribut() method before a
+   * Transformer is created
+   */    
+  private boolean m_optimizer = true;
+
+  /**
+   * The flag for the setting of the incremental feature;
+   * This flag should have the same value as the FEATURE_INCREMENTAL feature
+   * which is set by the TransformerFactory.setAttribut() method before a
+   * Transformer is created
+   */    
+  private boolean m_incremental = false;
+
+  /**
+   * The flag for the setting of the source_location feature;
+   * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature
+   * which is set by the TransformerFactory.setAttribut() method before a
+   * Transformer is created
+   */  
+  private boolean m_source_location = false;
+    
+  /**
+   * The SAX error handler, where errors and warnings are sent.
+   */
+  private ErrorListener m_errorHandler =
+    new org.apache.xml.utils.DefaultErrorHandler(false);
+
+  /**
+   * If the transform thread throws an exception, the exception needs to
+   * be stashed away so that the main thread can pass it on to the
+   * client. 
+   */
+  private Exception m_exceptionThrown = null;
+
+  /**
+   * This is needed for support of setSourceTreeDocForThread(Node doc),
+   * which must be called in order for the transform thread's run
+   * method to obtain the root of the source tree to be transformed.     
+   */
+  private int m_doc;
+
+  /** Flag to to tell if the tranformer needs to be reset. */
+  private boolean m_hasBeenReset = false;
+
+  /** NEEDSDOC Field m_shouldReset          */
+  private boolean m_shouldReset = true;
+
+  /**
+   * A stack of current template modes.
+   */
+  private Stack m_modes = new Stack();
+
+  //==========================================================
+  // SECTION: Constructor
+  //==========================================================
+
+  /**
+   * Construct a TransformerImpl.
+   *
+   * @param stylesheet The root of the stylesheet tree.
+   */
+  public TransformerImpl(StylesheetRoot stylesheet)
+   // throws javax.xml.transform.TransformerException    
+  {
+    m_optimizer = stylesheet.getOptimizer();
+    m_incremental = stylesheet.getIncremental();
+    m_source_location = stylesheet.getSource_location();  	
+    setStylesheet(stylesheet);
+    XPathContext xPath = new XPathContext(this);
+    xPath.setIncremental(m_incremental);
+    xPath.getDTMManager().setIncremental(m_incremental);
+    xPath.setSource_location(m_source_location);
+    xPath.getDTMManager().setSource_location(m_source_location);
+    
+    if (stylesheet.isSecureProcessing())
+      xPath.setSecureProcessing(true);
+    
+    setXPathContext(xPath);
+    getXPathContext().setNamespaceContext(stylesheet);
+  }
+  
+  // ================ ExtensionsTable ===================
+
+  /**
+   * The table of ExtensionHandlers.
+   */
+  private ExtensionsTable m_extensionsTable = null;
+
+  /**
+   * Get the extensions table object. 
+   *
+   * @return The extensions table.
+   */
+  public ExtensionsTable getExtensionsTable()
+  {
+    return m_extensionsTable;
+  }
+
+  /**
+   * If the stylesheet contains extensions, set the extensions table object.
+   *
+   *
+   * @param sroot The stylesheet.
+   * @throws javax.xml.transform.TransformerException
+   */
+  void setExtensionsTable(StylesheetRoot sroot)
+       throws javax.xml.transform.TransformerException
+  {
+    try
+    {
+      if (sroot.getExtensions() != null)
+        m_extensionsTable = new ExtensionsTable(sroot);
+    }
+    catch (javax.xml.transform.TransformerException te)
+    {te.printStackTrace();}
+  }
+  
+  //== Implementation of the XPath ExtensionsProvider interface.
+  
+  public boolean functionAvailable(String ns, String funcName)
+          throws javax.xml.transform.TransformerException
+  {
+    return getExtensionsTable().functionAvailable(ns, funcName);
+  }
+  
+  public boolean elementAvailable(String ns, String elemName)
+          throws javax.xml.transform.TransformerException
+  {
+    return getExtensionsTable().elementAvailable(ns, elemName);   
+  }
+   
+  public Object extFunction(String ns, String funcName, 
+                            Vector argVec, Object methodKey)
+            throws javax.xml.transform.TransformerException
+  {//System.out.println("TransImpl.extFunction() " + ns + " " + funcName +" " + getExtensionsTable());
+    return getExtensionsTable().extFunction(ns, funcName, 
+                                        argVec, methodKey,
+                                        getXPathContext().getExpressionContext());   
+  }
+
+  public Object extFunction(FuncExtFunction extFunction, Vector argVec)
+            throws javax.xml.transform.TransformerException
+  {
+    return getExtensionsTable().extFunction(extFunction, argVec,
+                                            getXPathContext().getExpressionContext());   
+  }
+  
+  //=========================
+
+  /**
+   * Reset the state.  This needs to be called after a process() call
+   * is invoked, if the processor is to be used again.
+   */
+  public void reset()
+  {
+
+    if (!m_hasBeenReset && m_shouldReset)
+    {
+      m_hasBeenReset = true;
+
+      if (this.m_outputStream != null)
+      {
+        try
+        {
+          m_outputStream.close();
+        }
+        catch (java.io.IOException ioe){}
+      }
+
+      m_outputStream = null;
+
+      // I need to look more carefully at which of these really
+      // needs to be reset.
+      m_countersTable = null;
+
+      m_xcontext.reset();
+      
+      m_xcontext.getVarStack().reset();
+      resetUserParameters();
+      
+
+      m_currentTemplateElements.removeAllElements();     
+      m_currentMatchTemplates.removeAllElements();
+      m_currentMatchedNodes.removeAllElements();
+      
+      m_serializationHandler = null;      
+      m_outputTarget = null;
+      m_keyManager = new KeyManager();
+      m_attrSetStack = null;
+      m_countersTable = null;
+      m_currentTemplateRuleIsNull = new BoolStack();
+      // m_xmlSource = null; // android-removed
+      m_doc = DTM.NULL;
+      // m_isTransformDone = false; // android-removed
+      m_transformThread = null;
+
+      // m_inputContentHandler = null;
+      // For now, reset the document cache each time.
+      m_xcontext.getSourceTreeManager().reset();
+    }
+
+    //    m_reportInPostExceptionFromThread = false;
+  }
+
+  // ========= Transformer Interface Implementation ==========
+
+  /**
+   * Get the thread that the transform process is on.
+   *
+   * @return The thread that the transform process is on, or null.
+   * @xsl.usage internal
+   */
+  public Thread getTransformThread()
+  {
+    return m_transformThread;
+  }
+
+  /**
+   * Get the thread that the transform process is on.
+   *
+   * @param t The transform thread, may be null.
+   * @xsl.usage internal
+   */
+  public void setTransformThread(Thread t)
+  {
+    m_transformThread = t;
+  }
+
+  /** NEEDSDOC Field m_hasTransformThreadErrorCatcher          */
+  private boolean m_hasTransformThreadErrorCatcher = false;
+
+  /**
+   * Return true if the transform was initiated from the transform method,
+   * otherwise it was probably done from a pure parse events.
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public boolean hasTransformThreadErrorCatcher()
+  {
+    return m_hasTransformThreadErrorCatcher;
+  }
+        
+        /**
+   * Process the source tree to SAX parse events.
+   * @param source  The input for the source tree.
+   *
+   * @throws TransformerException
+   */
+  public void transform(Source source) throws TransformerException
+  {
+                transform(source, true); 
+        }
+
+  /**
+   * Process the source tree to SAX parse events.
+   * @param source  The input for the source tree.
+   * @param shouldRelease  Flag indicating whether to release DTMManager.
+   *
+   * @throws TransformerException
+   */
+  public void transform(Source source, boolean shouldRelease) throws TransformerException
+  {
+
+    try
+    {
+        
+      // Patch for bugzilla #13863.  If we don't reset the namespaceContext
+      // then we will get a NullPointerException if transformer is reused 
+      // (for stylesheets that use xsl:key).  Not sure if this should go 
+      // here or in reset(). -is  
+      if(getXPathContext().getNamespaceContext() == null){
+         getXPathContext().setNamespaceContext(getStylesheet());
+      }
+      String base = source.getSystemId();
+      
+      // If no systemID of the source, use the base of the stylesheet.
+      if(null == base)
+      {
+        base = m_stylesheetRoot.getBaseIdentifier();
+      }
+
+      // As a last resort, use the current user dir.
+      if(null == base)
+      {
+        String currentDir = "";
+        try {
+          currentDir = System.getProperty("user.dir");
+        }
+        catch (SecurityException se) {}// user.dir not accessible from applet
+              
+        if (currentDir.startsWith(java.io.File.separator))
+          base = "file://" + currentDir;
+        else
+          base = "file:///" + currentDir;
+        
+        base = base + java.io.File.separatorChar
+               + source.getClass().getName();
+      }
+      setBaseURLOfSource(base);
+      DTMManager mgr = m_xcontext.getDTMManager();
+      /*
+       * According to JAXP1.2, new SAXSource()/StreamSource()
+       * should create an empty input tree, with a default root node. 
+       * new DOMSource()creates an empty document using DocumentBuilder.
+       * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations,
+       * since there is no clear spec. how to create an empty tree when
+       * both SAXSource() and StreamSource() are used.
+       */
+      if ((source instanceof StreamSource && source.getSystemId()==null &&
+         ((StreamSource)source).getInputStream()==null &&
+         ((StreamSource)source).getReader()==null)||
+         (source instanceof SAXSource &&
+         ((SAXSource)source).getInputSource()==null &&
+         ((SAXSource)source).getXMLReader()==null )||
+         (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){
+        try {
+          DocumentBuilderFactory builderF = 
+                   DocumentBuilderFactory.newInstance();
+          DocumentBuilder builder = builderF.newDocumentBuilder();
+          String systemID = source.getSystemId();
+          source = new DOMSource(builder.newDocument());
+
+          // Copy system ID from original, empty Source to new Source
+          if (systemID != null) {
+            source.setSystemId(systemID);
+          }
+        } catch (ParserConfigurationException e) {
+          fatalError(e);
+        }           
+      }
+      DTM dtm = mgr.getDTM(source, false, this, true, true);
+      dtm.setDocumentBaseURI(base);
+      
+      boolean hardDelete = true;  // %REVIEW% I have to think about this. -sb
+
+      try
+      {
+      	// NOTE: This will work because this is _NOT_ a shared DTM, and thus has
+      	// only a single Document node. If it could ever be an RTF or other
+      	// shared DTM, look at dtm.getDocumentRoot(nodeHandle).
+        this.transformNode(dtm.getDocument());
+      }
+      finally
+      {
+        if (shouldRelease)
+          mgr.release(dtm, hardDelete);
+      }
+
+      // Kick off the parse.  When the ContentHandler gets 
+      // the startDocument event, it will call transformNode( node ).
+      // reader.parse( xmlSource );
+      // This has to be done to catch exceptions thrown from 
+      // the transform thread spawned by the STree handler.
+      Exception e = getExceptionThrown();
+
+      if (null != e)
+      {
+        if (e instanceof javax.xml.transform.TransformerException)
+        {
+          throw (javax.xml.transform.TransformerException) e;
+        }
+        else if (e instanceof org.apache.xml.utils.WrappedRuntimeException)
+        {
+          fatalError(
+              ((org.apache.xml.utils.WrappedRuntimeException) e).getException());
+        }
+        else
+        {
+          throw new javax.xml.transform.TransformerException(e);
+        }
+      }
+      else if (null != m_serializationHandler)
+      {
+        m_serializationHandler.endDocument();
+      }
+    }
+    catch (org.apache.xml.utils.WrappedRuntimeException wre)
+    {
+      Throwable throwable = wre.getException();
+
+      while (throwable
+             instanceof org.apache.xml.utils.WrappedRuntimeException)
+      {
+        throwable =
+          ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
+      }
+
+      fatalError(throwable);
+    }
+
+    // Patch attributed to David Eisenberg <david@catcode.com>
+    catch (org.xml.sax.SAXParseException spe)
+    {
+      fatalError(spe);
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      m_errorHandler.fatalError(new TransformerException(se));
+    }
+    finally
+    {
+      m_hasTransformThreadErrorCatcher = false;
+
+      // This looks to be redundent to the one done in TransformNode.
+      reset();
+    }
+  }
+  
+  private void fatalError(Throwable throwable) throws TransformerException
+  {
+    if (throwable instanceof org.xml.sax.SAXParseException)
+      m_errorHandler.fatalError(new TransformerException(throwable.getMessage(),new SAXSourceLocator((org.xml.sax.SAXParseException)throwable)));
+    else
+      m_errorHandler.fatalError(new TransformerException(throwable));
+    
+  }
+
+  /**
+   * Get the base URL of the source.
+   *
+   *
+   * NEEDSDOC @param base
+   * @return The base URL of the source tree, or null.
+   */
+  public void setBaseURLOfSource(String base)
+  {
+    m_urlOfSource = base;
+  }
+
+  /**
+   * Get an output property that is in effect for the
+   * transformation.  The property specified may be a property
+   * that was set with setOutputProperty, or it may be a
+   * property specified in the stylesheet.
+   *
+   * NEEDSDOC @param qnameString
+   *
+   * @return The string value of the output property, or null
+   * if no property was found.
+   *
+   * @throws IllegalArgumentException If the property is not supported.
+   *
+   * @see javax.xml.transform.OutputKeys
+   */
+  public String getOutputProperty(String qnameString)
+          throws IllegalArgumentException
+  {
+
+    String value = null;
+    OutputProperties props = getOutputFormat();
+
+    value = props.getProperty(qnameString);
+
+    if (null == value)
+    {
+      if (!OutputProperties.isLegalPropertyKey(qnameString))
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: "
+                                           //+ qnameString);
+    }
+
+    return value;
+  }
+
+  /**
+   * Get the value of a property, without using the default properties.  This
+   * can be used to test if a property has been explicitly set by the stylesheet
+   * or user.
+   *
+   * NEEDSDOC @param qnameString
+   *
+   * @return The value of the property, or null if not found.
+   *
+   * @throws IllegalArgumentException If the property is not supported,
+   * and is not namespaced.
+   */
+  public String getOutputPropertyNoDefault(String qnameString)
+          throws IllegalArgumentException
+  {
+
+    String value = null;
+    OutputProperties props = getOutputFormat();
+
+    value = (String) props.getProperties().get(qnameString);
+
+    if (null == value)
+    {
+      if (!OutputProperties.isLegalPropertyKey(qnameString))
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: "
+                                          // + qnameString);
+    }
+
+    return value;
+  }
+
+  /**
+   * This method is used to set or override the value
+   * of the effective xsl:output attribute values
+   * specified in the stylesheet.
+   * <p>
+   * The recognized standard output properties are:
+   * <ul>
+   * <li>cdata-section-elements
+   * <li>doctype-system
+   * <li>doctype-public
+   * <li>indent
+   * <li>media-type
+   * <li>method
+   * <li>omit-xml-declaration
+   * <li>standalone
+   * <li>version
+   * </ul>
+   * <p>
+   * For example:
+   * <pre>
+   *   tran.setOutputProperty("standalone", "yes");
+   * </pre>
+   * <p>
+   * In the case of the cdata-section-elements property,
+   * the value should be a whitespace separated list of
+   * element names.  The element name is the local name
+   * of the element, if it is in no namespace, or, the URI
+   * in braces followed immediately by the local name
+   * if the element is in that namespace. For example: 
+   * <pre>
+   * tran.setOutputProperty(
+   *   "cdata-section-elements", 
+   *   "elem1 {http://example.uri}elem2 elem3");
+   * </pre>
+   * <p>
+   * The recognized Xalan extension elements are: 
+   * <ul>
+   * <li>content-handler
+   * <li>entities
+   * <li>indent-amount
+   * <li>line-separator
+   * <li>omit-meta-tag
+   * <li>use-url-escaping
+   * </ul>
+   * <p>
+   * These must be in the extension namespace of
+   * "http://xml.apache.org/xalan".  This is accomplished
+   * by putting the namespace URI in braces before the 
+   * property name, for example:
+   * <pre>
+   *   tran.setOutputProperty(
+   *     "{http://xml.apache.org/xalan}line-separator" ,
+   *     "\n");
+   * </pre> 
+   *
+   * @param name The property name.
+   * @param value The requested value for the property.
+   * @throws IllegalArgumentException if the property name is not legal.
+   */
+  public void setOutputProperty(String name, String value)
+          throws IllegalArgumentException
+  {
+
+    synchronized (m_reentryGuard)
+    {
+
+      // Get the output format that was set by the user, otherwise get the 
+      // output format from the stylesheet.
+      if (null == m_outputFormat)
+      {
+        m_outputFormat =
+          (OutputProperties) getStylesheet().getOutputComposed().clone();
+      }
+
+      if (!OutputProperties.isLegalPropertyKey(name))
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: "
+                                           //+ name);
+
+      m_outputFormat.setProperty(name, value);
+    }
+  }
+
+  /**
+   * Set the output properties for the transformation.  These
+   * properties will override properties set in the templates
+   * with xsl:output.
+   *
+   * <p>If argument to this function is null, any properties
+   * previously set will be removed.</p>
+   *
+   * @param oformat A set of output properties that will be
+   * used to override any of the same properties in effect
+   * for the transformation.
+   *
+   * @see javax.xml.transform.OutputKeys
+   * @see java.util.Properties
+   *
+   * @throws IllegalArgumentException if any of the argument keys are not
+   * recognized and are not namespace qualified.   
+   */
+  public void setOutputProperties(Properties oformat)
+  		throws IllegalArgumentException
+  {
+
+    synchronized (m_reentryGuard)
+    {
+      if (null != oformat)
+      {
+
+        // See if an *explicit* method was set.
+        String method = (String) oformat.get(OutputKeys.METHOD);
+
+        if (null != method)
+          m_outputFormat = new OutputProperties(method);
+        else if(m_outputFormat==null)
+          m_outputFormat = new OutputProperties();
+
+        m_outputFormat.copyFrom(oformat);
+        // copyFrom does not set properties that have been already set, so 
+        // this must be called after, which is a bit in the reverse from 
+        // what one might think.
+        m_outputFormat.copyFrom(m_stylesheetRoot.getOutputProperties());
+      }
+      else {
+        // if oformat is null JAXP says that any props previously set are removed
+        // and we are to revert back to those in the templates object (i.e. Stylesheet).
+        m_outputFormat = null;
+      }
+    }
+  }
+
+  /**
+   * Get a copy of the output properties for the transformation.  These
+   * properties will override properties set in the templates
+   * with xsl:output.
+   *
+   * <p>Note that mutation of the Properties object returned will not
+   * effect the properties that the transformation contains.</p>
+   *
+   * @return  A copy of the set of output properties in effect
+   * for the next transformation.
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public Properties getOutputProperties()
+  {
+    return (Properties) getOutputFormat().getProperties().clone();
+  }
+
+    /**
+     * Create a result ContentHandler from a Result object, based
+     * on the current OutputProperties.
+     *
+     * @param outputTarget Where the transform result should go,
+     * should not be null.
+     *
+     * @return A valid ContentHandler that will create the
+     * result tree when it is fed SAX events.
+     *
+     * @throws TransformerException
+     */
+    public SerializationHandler createSerializationHandler(Result outputTarget)
+            throws TransformerException
+    {
+       SerializationHandler xoh =
+        createSerializationHandler(outputTarget, getOutputFormat());
+       return xoh;
+    }
+
+    /**
+     * Create a ContentHandler from a Result object and an OutputProperties.
+     *
+     * @param outputTarget Where the transform result should go,
+     * should not be null.
+     * @param format The OutputProperties object that will contain
+     * instructions on how to serialize the output.
+     *
+     * @return A valid ContentHandler that will create the
+     * result tree when it is fed SAX events.
+     *
+     * @throws TransformerException
+     */
+    public SerializationHandler createSerializationHandler(
+            Result outputTarget, OutputProperties format)
+              throws TransformerException
+    {
+
+      SerializationHandler xoh;
+
+      // If the Result object contains a Node, then create
+      // a ContentHandler that will add nodes to the input node.
+      org.w3c.dom.Node outputNode = null;
+
+      if (outputTarget instanceof DOMResult)
+      {
+        outputNode = ((DOMResult) outputTarget).getNode();
+        org.w3c.dom.Node nextSibling = ((DOMResult)outputTarget).getNextSibling();
+
+        org.w3c.dom.Document doc;
+        short type;
+
+        if (null != outputNode)
+        {
+          type = outputNode.getNodeType();
+          doc = (org.w3c.dom.Node.DOCUMENT_NODE == type)
+                ? (org.w3c.dom.Document) outputNode
+                : outputNode.getOwnerDocument();
+        }
+        else
+        {
+          boolean isSecureProcessing = m_stylesheetRoot.isSecureProcessing();
+          doc = org.apache.xml.utils.DOMHelper.createDocument(isSecureProcessing);
+          outputNode = doc;
+          type = outputNode.getNodeType();
+
+          ((DOMResult) outputTarget).setNode(outputNode);
+        }
+
+        DOMBuilder handler =
+          (org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE == type)
+          ? new DOMBuilder(doc, (org.w3c.dom.DocumentFragment) outputNode)
+          : new DOMBuilder(doc, outputNode);
+        
+        if (nextSibling != null)
+          handler.setNextSibling(nextSibling);
+        
+          String encoding = format.getProperty(OutputKeys.ENCODING);          
+          xoh = new ToXMLSAXHandler(handler, (LexicalHandler)handler, encoding);
+      }
+      else if (outputTarget instanceof SAXResult)
+      {
+        ContentHandler handler = ((SAXResult) outputTarget).getHandler();
+        
+        if (null == handler)
+           throw new IllegalArgumentException(
+             "handler can not be null for a SAXResult"); 
+             
+        LexicalHandler lexHandler;
+        if (handler instanceof LexicalHandler)     
+            lexHandler = (LexicalHandler)  handler;
+        else
+            lexHandler = null;
+            
+        String encoding = format.getProperty(OutputKeys.ENCODING); 
+        String method = format.getProperty(OutputKeys.METHOD);
+
+        ToXMLSAXHandler toXMLSAXHandler = new ToXMLSAXHandler(handler, lexHandler, encoding);
+        toXMLSAXHandler.setShouldOutputNSAttr(false);
+        xoh = toXMLSAXHandler;   
+
+
+        String publicID = format.getProperty(OutputKeys.DOCTYPE_PUBLIC); 
+        String systemID = format.getProperty(OutputKeys.DOCTYPE_SYSTEM); 
+        if (systemID != null)
+            xoh.setDoctypeSystem(systemID);
+        if (publicID != null)
+            xoh.setDoctypePublic(publicID);
+        
+        if (handler instanceof TransformerClient) {
+            XalanTransformState state = new XalanTransformState();
+            ((TransformerClient)handler).setTransformState(state);
+            ((ToSAXHandler)xoh).setTransformState(state);
+        }
+
+ 
+      }
+
+      // Otherwise, create a ContentHandler that will serialize the
+      // result tree to either a stream or a writer.
+      else if (outputTarget instanceof StreamResult)
+      {
+        StreamResult sresult = (StreamResult) outputTarget;
+
+        try
+        {
+          SerializationHandler serializer =
+            (SerializationHandler) SerializerFactory.getSerializer(format.getProperties());
+
+          if (null != sresult.getWriter())
+            serializer.setWriter(sresult.getWriter());
+          else if (null != sresult.getOutputStream())
+            serializer.setOutputStream(sresult.getOutputStream());
+          else if (null != sresult.getSystemId())
+          {
+            String fileURL = sresult.getSystemId();
+
+            if (fileURL.startsWith("file:///"))
+            {
+              if (fileURL.substring(8).indexOf(":") >0)
+                fileURL = fileURL.substring(8);
+              else
+                fileURL = fileURL.substring(7);
+            }
+            else if (fileURL.startsWith("file:/"))
+            {
+                if (fileURL.substring(6).indexOf(":") >0)
+                    fileURL = fileURL.substring(6);
+                  else
+                    fileURL = fileURL.substring(5);            	
+            }
+
+            m_outputStream = new java.io.FileOutputStream(fileURL);
+
+            serializer.setOutputStream(m_outputStream);
+            
+            xoh = serializer;
+          }
+          else
+            throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED, null)); //"No output specified!");
+
+          // handler = serializer.asContentHandler();
+
+        //  this.setSerializer(serializer);
+
+          xoh = serializer;  
+        }
+//        catch (UnsupportedEncodingException uee)
+//        {
+//          throw new TransformerException(uee);
+//        }
+        catch (IOException ioe)
+        {
+          throw new TransformerException(ioe);
+        }
+      }
+      else
+      {
+        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE, new Object[]{outputTarget.getClass().getName()})); //"Can't transform to a Result of type "
+                                       //+ outputTarget.getClass().getName()
+                                       //+ "!");
+      }
+      
+      // before we forget, lets make the created handler hold a reference
+      // to the current TransformImpl object
+      xoh.setTransformer(this);
+
+      SourceLocator srcLocator = getStylesheet();
+      xoh.setSourceLocator(srcLocator);
+      
+      
+      return xoh;
+
+   
+    }
+        
+        /**
+   * Process the source tree to the output result.
+   * @param xmlSource  The input for the source tree.
+   * @param outputTarget The output source target.
+   *
+   * @throws TransformerException
+   */
+  public void transform(Source xmlSource, Result outputTarget)
+          throws TransformerException
+  {
+                transform(xmlSource, outputTarget, true);
+        }
+
+  /**
+   * Process the source tree to the output result.
+   * @param xmlSource  The input for the source tree.
+   * @param outputTarget The output source target.
+   * @param shouldRelease  Flag indicating whether to release DTMManager. 
+   *
+   * @throws TransformerException
+   */
+  public void transform(Source xmlSource, Result outputTarget, boolean shouldRelease)
+          throws TransformerException
+  {
+
+    synchronized (m_reentryGuard)
+    {
+      SerializationHandler xoh = createSerializationHandler(outputTarget);
+      this.setSerializationHandler(xoh);        
+
+      m_outputTarget = outputTarget;
+
+      transform(xmlSource, shouldRelease);
+    }
+  }
+
+  /**
+   * Process the source node to the output result, if the
+   * processor supports the "http://xml.org/trax/features/dom/input"
+   * feature.
+   * %REVIEW% Do we need a Node version of this?
+   * @param node  The input source node, which can be any valid DTM node.
+   * @param outputTarget The output source target.
+   *
+   * @throws TransformerException
+   */
+  public void transformNode(int node, Result outputTarget)
+          throws TransformerException
+  {
+    
+
+    SerializationHandler xoh = createSerializationHandler(outputTarget);
+    this.setSerializationHandler(xoh);
+
+    m_outputTarget = outputTarget;
+
+    transformNode(node);
+  }
+
+  /**
+   * Process the source node to the output result, if the
+   * processor supports the "http://xml.org/trax/features/dom/input"
+   * feature.
+   * %REVIEW% Do we need a Node version of this?
+   * @param node  The input source node, which can be any valid DTM node.
+   *
+   * @throws TransformerException
+   */
+  public void transformNode(int node) throws TransformerException
+  {
+    //dml
+    setExtensionsTable(getStylesheet());
+    // Make sure we're not writing to the same output content handler.
+    synchronized (m_serializationHandler)
+    {
+      m_hasBeenReset = false;
+      
+      XPathContext xctxt = getXPathContext();
+      DTM dtm = xctxt.getDTM(node);
+
+      try
+      {
+        pushGlobalVars(node);
+
+        // ==========
+        // Give the top-level templates a chance to pass information into 
+        // the context (this is mainly for setting up tables for extensions).
+        StylesheetRoot stylesheet = this.getStylesheet();
+        int n = stylesheet.getGlobalImportCount();
+
+        for (int i = 0; i < n; i++)
+        {
+          StylesheetComposed imported = stylesheet.getGlobalImport(i);
+          int includedCount = imported.getIncludeCountComposed();
+
+          for (int j = -1; j < includedCount; j++)
+          {
+            Stylesheet included = imported.getIncludeComposed(j);
+
+            included.runtimeInit(this);
+
+            for (ElemTemplateElement child = included.getFirstChildElem();
+                    child != null; child = child.getNextSiblingElem())
+            {
+              child.runtimeInit(this);
+            }
+          }
+        }
+        // ===========        
+        // System.out.println("Calling applyTemplateToNode - "+Thread.currentThread().getName());
+        DTMIterator dtmIter = new org.apache.xpath.axes.SelfIteratorNoPredicate();
+        dtmIter.setRoot(node, xctxt);
+        xctxt.pushContextNodeList(dtmIter);
+        try
+        {
+          this.applyTemplateToNode(null, null, node);
+        }
+        finally
+        {
+          xctxt.popContextNodeList();
+        }
+        // m_stylesheetRoot.getStartRule().execute(this);
+
+        // System.out.println("Done with applyTemplateToNode - "+Thread.currentThread().getName());
+        if (null != m_serializationHandler)
+        {
+          m_serializationHandler.endDocument();
+        }
+      }
+      catch (Exception se)
+      {
+
+        // System.out.println(Thread.currentThread().getName()+" threw an exception! "
+        //                   +se.getMessage());
+        // If an exception was thrown, we need to make sure that any waiting 
+        // handlers can terminate, which I guess is best done by sending 
+        // an endDocument.
+        
+        // SAXSourceLocator
+        while(se instanceof org.apache.xml.utils.WrappedRuntimeException)
+        {
+          Exception e = ((org.apache.xml.utils.WrappedRuntimeException)se).getException();
+          if(null != e)
+            se = e;
+        }
+        
+        if (null != m_serializationHandler)
+        {
+          try
+          {
+            if(se instanceof org.xml.sax.SAXParseException)
+              m_serializationHandler.fatalError((org.xml.sax.SAXParseException)se);
+            else if(se instanceof TransformerException)
+            {
+              TransformerException te = ((TransformerException)se);
+              SAXSourceLocator sl = new SAXSourceLocator( te.getLocator() );
+              m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(te.getMessage(), sl, te)); 
+            }
+            else
+            {
+              m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(se.getMessage(), new SAXSourceLocator(), se)); 
+            }             
+          }
+          catch (Exception e){}
+        }        
+        
+        if(se instanceof TransformerException)
+        {
+          m_errorHandler.fatalError((TransformerException)se);
+        }
+        else if(se instanceof org.xml.sax.SAXParseException)
+        {
+          m_errorHandler.fatalError(new TransformerException(se.getMessage(), 
+                      new SAXSourceLocator((org.xml.sax.SAXParseException)se), 
+                      se));
+        }
+        else
+        {
+          m_errorHandler.fatalError(new TransformerException(se));
+        }
+        
+      }
+      finally
+      {
+        this.reset();
+      }
+    }
+  }
+
+  /**
+   * Get a SAX2 ContentHandler for the input.
+   *
+   * @return A valid ContentHandler, which should never be null, as
+   * long as getFeature("http://xml.org/trax/features/sax/input")
+   * returns true.
+   */
+  public ContentHandler getInputContentHandler()
+  {
+    return getInputContentHandler(false);
+  }
+
+  /**
+   * Get a SAX2 ContentHandler for the input.
+   *
+   * @param doDocFrag true if a DocumentFragment should be created as
+   * the root, rather than a Document.
+   *
+   * @return A valid ContentHandler, which should never be null, as
+   * long as getFeature("http://xml.org/trax/features/sax/input")
+   * returns true.
+   */
+  public ContentHandler getInputContentHandler(boolean doDocFrag)
+  {
+
+    if (null == m_inputContentHandler)
+    {
+
+      //      if(null == m_urlOfSource && null != m_stylesheetRoot)
+      //        m_urlOfSource = m_stylesheetRoot.getBaseIdentifier();
+      m_inputContentHandler = new TransformerHandlerImpl(this, doDocFrag,
+              m_urlOfSource);
+    }
+
+    return m_inputContentHandler;
+  }
+
+  /**
+   * Set the output properties for the transformation.  These
+   * properties will override properties set in the templates
+   * with xsl:output.
+   *
+   * @param oformat A valid OutputProperties object (which will
+   * not be mutated), or null.
+   */
+  public void setOutputFormat(OutputProperties oformat)
+  {
+    m_outputFormat = oformat;
+  }
+
+  /**
+   * Get the output properties used for the transformation.
+   *
+   * @return the output format that was set by the user,
+   * otherwise the output format from the stylesheet.
+   */
+  public OutputProperties getOutputFormat()
+  {
+
+    // Get the output format that was set by the user, otherwise get the 
+    // output format from the stylesheet.
+    OutputProperties format = (null == m_outputFormat)
+                              ? getStylesheet().getOutputComposed()
+                              : m_outputFormat;
+
+    return format;
+  }
+
+  /**
+   * Set a parameter for the templates.
+   * 
+   * @param name The name of the parameter.
+   * @param namespace The namespace of the parameter.
+   * @param value The value object.  This can be any valid Java object
+   * -- it's up to the processor to provide the proper
+   * coersion to the object, or simply pass it on for use
+   * in extensions.
+   */
+  public void setParameter(String name, String namespace, Object value)
+  {
+
+    VariableStack varstack = getXPathContext().getVarStack();
+    QName qname = new QName(namespace, name);
+    XObject xobject = XObject.create(value, getXPathContext());
+    
+    StylesheetRoot sroot = m_stylesheetRoot;
+    Vector vars = sroot.getVariablesAndParamsComposed();
+    int i = vars.size();
+    while (--i >= 0)
+    {
+      ElemVariable variable = (ElemVariable)vars.elementAt(i);
+      if(variable.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE && 
+         variable.getName().equals(qname))
+      {
+          varstack.setGlobalVariable(i, xobject);
+      }
+    }
+  }
+
+  /** NEEDSDOC Field m_userParams          */
+  Vector m_userParams;
+
+  /**
+   * Set a parameter for the transformation.
+   *
+   * @param name The name of the parameter,
+   *             which may have a namespace URI.
+   * @param value The value object.  This can be any valid Java object
+   * -- it's up to the processor to provide the proper
+   * coersion to the object, or simply pass it on for use
+   * in extensions.
+   */
+  public void setParameter(String name, Object value)
+  {
+    
+    if (value == null) {
+      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE, new Object[]{name}));
+    }    
+
+    StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
+
+    try
+    {
+
+      // The first string might be the namespace, or it might be 
+      // the local name, if the namespace is null.
+      String s1 = tokenizer.nextToken();
+      String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+
+      if (null == m_userParams)
+        m_userParams = new Vector();
+
+      if (null == s2)
+      {
+        replaceOrPushUserParam(new QName(s1), XObject.create(value, getXPathContext()));
+        setParameter(s1, null, value);
+      }
+      else
+      {
+        replaceOrPushUserParam(new QName(s1, s2), XObject.create(value, getXPathContext()));
+        setParameter(s2, s1, value);
+      }
+    }
+    catch (java.util.NoSuchElementException nsee)
+    {
+
+      // Should throw some sort of an error.
+    }
+  }
+
+  /**
+   * NEEDSDOC Method replaceOrPushUserParam 
+   *
+   *
+   * NEEDSDOC @param qname
+   * NEEDSDOC @param xval
+   */
+  private void replaceOrPushUserParam(QName qname, XObject xval)
+  {
+
+    int n = m_userParams.size();
+
+    for (int i = n - 1; i >= 0; i--)
+    {
+      Arg arg = (Arg) m_userParams.elementAt(i);
+
+      if (arg.getQName().equals(qname))
+      {
+        m_userParams.setElementAt(new Arg(qname, xval, true), i);
+
+        return;
+      }
+    }
+
+    m_userParams.addElement(new Arg(qname, xval, true));
+  }
+
+  /**
+   * Get a parameter that was explicitly set with setParameter
+   * or setParameters.
+   *
+   *
+   * NEEDSDOC @param name
+   * @return A parameter that has been set with setParameter
+   * or setParameters,
+   * *not* all the xsl:params on the stylesheet (which require
+   * a transformation Source to be evaluated).
+   */
+  public Object getParameter(String name)
+  {
+
+    try
+    {
+
+      // VariableStack varstack = getXPathContext().getVarStack();
+      // The first string might be the namespace, or it might be 
+      // the local name, if the namespace is null.
+      QName qname = QName.getQNameFromString(name);
+
+      if (null == m_userParams)
+        return null;
+
+      int n = m_userParams.size();
+
+      for (int i = n - 1; i >= 0; i--)
+      {
+        Arg arg = (Arg) m_userParams.elementAt(i);
+
+        if (arg.getQName().equals(qname))
+        {
+          return arg.getVal().object();
+        }
+      }
+
+      return null;
+    }
+    catch (java.util.NoSuchElementException nsee)
+    {
+
+      // Should throw some sort of an error.
+      return null;
+    }
+  }
+  
+  /**
+   * Reset parameters that the user specified for the transformation.
+   * Called during transformer.reset() after we have cleared the 
+   * variable stack. We need to make sure that user params are
+   * reset so that the transformer object can be reused. 
+   */
+  private void resetUserParameters()
+  {
+
+    try
+    {
+      
+      if (null == m_userParams)
+        return;
+
+      int n = m_userParams.size();
+      for (int i = n - 1; i >= 0; i--)
+      {
+        Arg arg = (Arg) m_userParams.elementAt(i);
+        QName name = arg.getQName();
+        // The first string might be the namespace, or it might be 
+        // the local name, if the namespace is null.
+        String s1 = name.getNamespace();
+        String s2 = name.getLocalPart();
+
+        setParameter(s2, s1, arg.getVal().object());
+        
+      }
+      
+    }
+    catch (java.util.NoSuchElementException nsee)
+    {
+      // Should throw some sort of an error.
+      
+    }
+  }
+
+  /**
+   * Set a bag of parameters for the transformation. Note that
+   * these will not be additive, they will replace the existing
+   * set of parameters.
+   *
+   * NEEDSDOC @param params
+   */
+  public void setParameters(Properties params)
+  {
+
+    clearParameters();
+
+    Enumeration names = params.propertyNames();
+
+    while (names.hasMoreElements())
+    {
+      String name = params.getProperty((String) names.nextElement());
+      StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
+
+      try
+      {
+
+        // The first string might be the namespace, or it might be 
+        // the local name, if the namespace is null.
+        String s1 = tokenizer.nextToken();
+        String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+
+        if (null == s2)
+          setParameter(s1, null, params.getProperty(name));
+        else
+          setParameter(s2, s1, params.getProperty(name));
+      }
+      catch (java.util.NoSuchElementException nsee)
+      {
+
+        // Should throw some sort of an error.
+      }
+    }
+  }
+
+  /**
+   * Reset the parameters to a null list.
+   */
+  public void clearParameters()
+  {
+
+    synchronized (m_reentryGuard)
+    {
+      VariableStack varstack = new VariableStack();
+
+      m_xcontext.setVarStack(varstack);
+
+      m_userParams = null;
+    }
+  }
+
+
+  /**
+   * Internal -- push the global variables from the Stylesheet onto
+   * the context's runtime variable stack.
+   * <p>If we encounter a variable
+   * that is already defined in the variable stack, we ignore it.  This
+   * is because the second variable definition will be at a lower import
+   * precedence.  Presumably, global"variables at the same import precedence
+   * with the same name will have been caught during the recompose process.
+   * <p>However, if we encounter a parameter that is already defined in the
+   * variable stack, we need to see if this is a parameter whose value was
+   * supplied by a setParameter call.  If so, we need to "receive" the one
+   * already in the stack, ignoring this one.  If it is just an earlier
+   * xsl:param or xsl:variable definition, we ignore it using the same
+   * reasoning as explained above for the variable.
+   *
+   * @param contextNode The root of the source tree, can't be null.
+   *
+   * @throws TransformerException
+   */
+  protected void pushGlobalVars(int contextNode) throws TransformerException
+  {
+
+    XPathContext xctxt = m_xcontext;
+    VariableStack vs = xctxt.getVarStack();
+    StylesheetRoot sr = getStylesheet();
+    Vector vars = sr.getVariablesAndParamsComposed();
+    
+    int i = vars.size();
+    vs.link(i);
+
+    while (--i >= 0)
+    {
+      ElemVariable v = (ElemVariable) vars.elementAt(i);
+
+      // XObject xobj = v.getValue(this, contextNode);
+      XObject xobj = new XUnresolvedVariable(v, contextNode, this,
+                                     vs.getStackFrame(), 0, true);
+      
+      if(null == vs.elementAt(i))                               
+        vs.setGlobalVariable(i, xobj);
+    }
+
+  }
+
+  /**
+   * Set an object that will be used to resolve URIs used in
+   * document(), etc.
+   * @param resolver An object that implements the URIResolver interface,
+   * or null.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+
+    synchronized (m_reentryGuard)
+    {
+      m_xcontext.getSourceTreeManager().setURIResolver(resolver);
+    }
+  }
+
+  /**
+   * Get an object that will be used to resolve URIs used in
+   * document(), etc.
+   *
+   * @return An object that implements the URIResolver interface,
+   * or null.
+   */
+  public URIResolver getURIResolver()
+  {
+    return m_xcontext.getSourceTreeManager().getURIResolver();
+  }
+
+  // ======== End Transformer Implementation ========  
+
+  /**
+   * Set the content event handler.
+   *
+   * NEEDSDOC @param handler
+   * @throws java.lang.NullPointerException If the handler
+   *            is null.
+   * @see org.xml.sax.XMLReader#setContentHandler
+   */
+  public void setContentHandler(ContentHandler handler)
+  {
+
+    if (handler == null)
+    {
+      throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_CONTENT_HANDLER, null)); //"Null content handler");
+    }
+    else
+    {
+      m_outputContentHandler = handler;
+
+      if (null == m_serializationHandler)
+      {
+        ToXMLSAXHandler h = new ToXMLSAXHandler();
+        h.setContentHandler(handler);
+        h.setTransformer(this);
+        
+        m_serializationHandler = h;
+      }
+      else
+        m_serializationHandler.setContentHandler(handler);
+    }
+  }
+
+  /**
+   * Get the content event handler.
+   *
+   * @return The current content handler, or null if none was set.
+   * @see org.xml.sax.XMLReader#getContentHandler
+   */
+  public ContentHandler getContentHandler()
+  {
+    return m_outputContentHandler;
+  }
+
+  /**
+   * Given a stylesheet element, create a result tree fragment from it's
+   * contents. The fragment will be built within the shared RTF DTM system
+   * used as a variable stack.
+   * @param templateParent The template element that holds the fragment.
+   * @return the NodeHandle for the root node of the resulting RTF.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public int transformToRTF(ElemTemplateElement templateParent)
+          throws TransformerException
+  {
+    // Retrieve a DTM to contain the RTF. At this writing, this may be a
+    // multi-document DTM (SAX2RTFDTM).
+    DTM dtmFrag = m_xcontext.getRTFDTM();
+    return transformToRTF(templateParent,dtmFrag);
+  }
+  
+  /**
+   * Given a stylesheet element, create a result tree fragment from it's
+   * contents. The fragment will also use the shared DTM system, but will
+   * obtain its space from the global variable pool rather than the dynamic
+   * variable stack. This allows late binding of XUnresolvedVariables without
+   * the risk that their content will be discarded when the variable stack
+   * is popped.
+   * 
+   * @param templateParent The template element that holds the fragment.
+   * @return the NodeHandle for the root node of the resulting RTF.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public int transformToGlobalRTF(ElemTemplateElement templateParent)
+          throws TransformerException
+  {
+    // Retrieve a DTM to contain the RTF. At this writing, this may be a
+    // multi-document DTM (SAX2RTFDTM).
+    DTM dtmFrag = m_xcontext.getGlobalRTFDTM();
+    return transformToRTF(templateParent,dtmFrag);
+  }
+  
+  /**
+   * Given a stylesheet element, create a result tree fragment from it's
+   * contents.
+   * @param templateParent The template element that holds the fragment.
+   * @param dtmFrag The DTM to write the RTF into
+   * @return the NodeHandle for the root node of the resulting RTF.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  private int transformToRTF(ElemTemplateElement templateParent,DTM dtmFrag)
+          throws TransformerException
+  {
+
+    XPathContext xctxt = m_xcontext;
+    
+    ContentHandler rtfHandler = dtmFrag.getContentHandler();
+
+    // Obtain the ResultTreeFrag's root node.
+    // NOTE: In SAX2RTFDTM, this value isn't available until after
+    // the startDocument has been issued, so assignment has been moved
+    // down a bit in the code.
+    int resultFragment; // not yet reliably = dtmFrag.getDocument();
+
+    // Save the current result tree handler.
+    SerializationHandler savedRTreeHandler = this.m_serializationHandler;
+ 
+
+    // And make a new handler for the RTF.
+    ToSAXHandler h = new ToXMLSAXHandler();
+    h.setContentHandler(rtfHandler);
+    h.setTransformer(this);
+    
+    // Replace the old handler (which was already saved)
+    m_serializationHandler = h;
+ 
+    // use local variable for the current handler
+    SerializationHandler rth = m_serializationHandler;
+
+    try
+    {
+      rth.startDocument();
+      
+      // startDocument is "bottlenecked" in RTH. We need it acted upon immediately,
+      // to set the DTM's state as in-progress, so that if the xsl:variable's body causes
+      // further RTF activity we can keep that from bashing this DTM.
+      rth.flushPending(); 
+ 
+      try
+      {
+
+        // Do the transformation of the child elements.
+        executeChildTemplates(templateParent, true);
+
+        // Make sure everything is flushed!
+        rth.flushPending();
+        
+        // Get the document ID. May not exist until the RTH has not only
+        // received, but flushed, the startDocument, and may be invalid
+        // again after the document has been closed (still debating that)
+        // ... so waiting until just before the end seems simplest/safest. 
+	resultFragment = dtmFrag.getDocument();      
+      }
+      finally
+      {
+        rth.endDocument();
+      }
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    finally
+    {
+
+      // Restore the previous result tree handler.
+      this.m_serializationHandler = savedRTreeHandler;
+    }
+
+    return resultFragment;
+  }
+
+  /**
+   * Take the contents of a template element, process it, and
+   * convert it to a string.
+   *
+   * @param elem The parent element whose children will be output
+   * as a string.
+   *
+   * @return The stringized result of executing the elements children.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public String transformToString(ElemTemplateElement elem)
+          throws TransformerException
+  {
+    ElemTemplateElement firstChild = elem.getFirstChildElem();
+    if(null == firstChild)
+      return "";
+    if(elem.hasTextLitOnly() && m_optimizer)
+    {
+      return ((ElemTextLiteral)firstChild).getNodeValue();
+    }
+
+    // Save the current result tree handler.
+    SerializationHandler savedRTreeHandler = this.m_serializationHandler;
+
+    // Create a Serializer object that will handle the SAX events 
+    // and build the ResultTreeFrag nodes.
+    StringWriter sw = (StringWriter) m_stringWriterObjectPool.getInstance();
+
+    m_serializationHandler =
+        (ToTextStream) m_textResultHandlerObjectPool.getInstance();
+
+      if (null == m_serializationHandler)
+      {
+        // if we didn't get one from the pool, go make a new one
+
+        
+        Serializer serializer = org.apache.xml.serializer.SerializerFactory.getSerializer(
+            m_textformat.getProperties());
+        m_serializationHandler = (SerializationHandler) serializer;
+      } 
+
+        m_serializationHandler.setTransformer(this);
+        m_serializationHandler.setWriter(sw);
+ 
+ 
+    String result;
+
+    try
+    {
+        /* Don't call startDocument, the SerializationHandler  will
+         * generate its own internal startDocument call anyways
+         */
+      // this.m_serializationHandler.startDocument();
+
+      // Do the transformation of the child elements.
+      executeChildTemplates(elem, true);
+        this.m_serializationHandler.endDocument();
+
+      result = sw.toString();
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    finally
+    {
+      sw.getBuffer().setLength(0);
+
+      try
+      {
+        sw.close();
+      }
+      catch (Exception ioe){}
+
+      m_stringWriterObjectPool.freeInstance(sw);
+      m_serializationHandler.reset();
+      m_textResultHandlerObjectPool.freeInstance(m_serializationHandler);
+
+      // Restore the previous result tree handler.
+      m_serializationHandler = savedRTreeHandler;
+    }
+
+    return result;
+  }
+
+  /**
+   * Given an element and mode, find the corresponding
+   * template and process the contents.
+   *
+   * @param xslInstruction The calling element.
+   * @param template The template to use if xsl:for-each, current template for apply-imports, or null.
+   * @param child The source context node.
+   * @throws TransformerException
+   * @return true if applied a template, false if not.
+   * @xsl.usage advanced
+   */
+  public boolean applyTemplateToNode(ElemTemplateElement xslInstruction,  // xsl:apply-templates or xsl:for-each
+                                     ElemTemplate template, int child)
+                                             throws TransformerException
+  {
+
+    DTM dtm = m_xcontext.getDTM(child);
+    short nodeType = dtm.getNodeType(child);
+    boolean isDefaultTextRule = false;
+    boolean isApplyImports = false;
+    
+    isApplyImports = ((xslInstruction == null)
+                                ? false
+                                : xslInstruction.getXSLToken()
+                                  == Constants.ELEMNAME_APPLY_IMPORTS);        
+
+    if (null == template || isApplyImports)
+    {
+      int maxImportLevel, endImportLevel=0;
+
+      if (isApplyImports)
+      {
+        maxImportLevel =
+          template.getStylesheetComposed().getImportCountComposed() - 1;
+        endImportLevel =
+          template.getStylesheetComposed().getEndImportCountComposed();
+      }
+      else
+      {
+        maxImportLevel = -1;
+      }
+
+      // If we're trying an xsl:apply-imports at the top level (ie there are no
+      // imported stylesheets), we need to indicate that there is no matching template.
+      // The above logic will calculate a maxImportLevel of -1 which indicates
+      // that we should find any template.  This is because a value of -1 for
+      // maxImportLevel has a special meaning.  But we don't want that.
+      // We want to match -no- templates. See bugzilla bug 1170.
+      if (isApplyImports && (maxImportLevel == -1))
+      {
+        template = null;
+      }
+      else
+      {
+
+        // Find the XSL template that is the best match for the 
+        // element.        
+        XPathContext xctxt = m_xcontext;
+
+        try
+        {
+          xctxt.pushNamespaceContext(xslInstruction);
+
+          QName mode = this.getMode();
+          
+          if (isApplyImports)
+            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
+                  maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm);
+          else
+            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
+                  m_quietConflictWarnings, dtm);
+          
+        }
+        finally
+        {
+          xctxt.popNamespaceContext();
+        }
+      }
+
+      // If that didn't locate a node, fall back to a default template rule.
+      // See http://www.w3.org/TR/xslt#built-in-rule.
+      if (null == template)
+      {
+        switch (nodeType)
+        {
+        case DTM.DOCUMENT_FRAGMENT_NODE :
+        case DTM.ELEMENT_NODE :
+          template = m_stylesheetRoot.getDefaultRule();
+          break;
+        case DTM.CDATA_SECTION_NODE :
+        case DTM.TEXT_NODE :
+        case DTM.ATTRIBUTE_NODE :
+          template = m_stylesheetRoot.getDefaultTextRule();
+          isDefaultTextRule = true;
+          break;
+        case DTM.DOCUMENT_NODE :
+          template = m_stylesheetRoot.getDefaultRootRule();
+          break;
+        default :
+
+          // No default rules for processing instructions and the like.
+          return false;
+        }
+      }
+    }
+
+    // If we are processing the default text rule, then just clone 
+    // the value directly to the result tree.
+    try
+    {
+      pushElemTemplateElement(template);
+      m_xcontext.pushCurrentNode(child);
+      pushPairCurrentMatched(template, child);
+      
+      // Fix copy copy29 test.
+      if (!isApplyImports) {
+          DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
+          m_xcontext.pushContextNodeList(cnl);
+      }
+
+      if (isDefaultTextRule)
+      {
+        switch (nodeType)
+        {
+        case DTM.CDATA_SECTION_NODE :
+        case DTM.TEXT_NODE :
+          ClonerToResultTree.cloneToResultTree(child, nodeType, 
+                                        dtm, getResultTreeHandler(), false);
+          break;
+        case DTM.ATTRIBUTE_NODE :
+          dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false);
+          break;
+        }
+      }
+      else
+      {
+
+        // And execute the child templates.
+        // 9/11/00: If template has been compiled, hand off to it
+        // since much (most? all?) of the processing has been inlined.
+        // (It would be nice if there was a single entry point that
+        // worked for both... but the interpretive system works by
+        // having the Tranformer execute the children, while the
+        // compiled obviously has to run its own code. It's
+        // also unclear that "execute" is really the right name for
+        // that entry point.)
+        m_xcontext.setSAXLocator(template);
+        // m_xcontext.getVarStack().link();
+        m_xcontext.getVarStack().link(template.m_frameSize);
+        executeChildTemplates(template, true);
+      }
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    finally
+    {
+      if (!isDefaultTextRule)
+        m_xcontext.getVarStack().unlink();
+      m_xcontext.popCurrentNode();
+      if (!isApplyImports) {
+          m_xcontext.popContextNodeList();
+      }
+      popCurrentMatched();
+      
+      popElemTemplateElement();
+    }
+
+    return true;
+  }
+  
+  
+  /**
+   * Execute each of the children of a template element.  This method
+   * is only for extension use.
+   *
+   * @param elem The ElemTemplateElement that contains the children
+   * that should execute.
+   * NEEDSDOC @param context
+   * @param mode The current mode.
+   * @param handler The ContentHandler to where the result events
+   * should be fed.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public void executeChildTemplates(
+          ElemTemplateElement elem, org.w3c.dom.Node context, QName mode, ContentHandler handler)
+            throws TransformerException
+  {
+
+    XPathContext xctxt = m_xcontext;
+
+    try
+    {
+      if(null != mode)
+        pushMode(mode);
+      xctxt.pushCurrentNode(xctxt.getDTMHandleFromNode(context));
+      executeChildTemplates(elem, handler);
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      
+      // I'm not sure where or why this was here.  It is clearly in 
+      // error though, without a corresponding pushMode().
+      if (null != mode)
+        popMode();
+    }
+  }
+
+  /**
+   * Execute each of the children of a template element.
+   *
+   * @param elem The ElemTemplateElement that contains the children
+   * that should execute.
+   * @param shouldAddAttrs true if xsl:attributes should be executed.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public void executeChildTemplates(
+          ElemTemplateElement elem, boolean shouldAddAttrs)
+            throws TransformerException
+  {
+
+    // Does this element have any children?
+    ElemTemplateElement t = elem.getFirstChildElem();
+
+    if (null == t)
+      return;      
+    
+    if(elem.hasTextLitOnly() && m_optimizer)
+    {      
+      char[] chars = ((ElemTextLiteral)t).getChars();
+      try
+      {
+        // Have to push stuff on for tooling...
+        this.pushElemTemplateElement(t);
+        m_serializationHandler.characters(chars, 0, chars.length);
+      }
+      catch(SAXException se)
+      {
+        throw new TransformerException(se);
+      }
+      finally
+      {
+        this.popElemTemplateElement();
+      }
+      return;
+    }
+
+//    // Check for infinite loops if we have to.
+//    boolean check = (m_stackGuard.m_recursionLimit > -1);
+//
+//    if (check)
+//      getStackGuard().push(elem, xctxt.getCurrentNode());
+
+    XPathContext xctxt = m_xcontext;
+    xctxt.pushSAXLocatorNull();
+    int currentTemplateElementsTop = m_currentTemplateElements.size();
+    m_currentTemplateElements.push(null);
+
+    try
+    {
+      // Loop through the children of the template, calling execute on 
+      // each of them.
+      for (; t != null; t = t.getNextSiblingElem())
+      {
+        if (!shouldAddAttrs
+                && t.getXSLToken() == Constants.ELEMNAME_ATTRIBUTE)
+          continue;
+
+        xctxt.setSAXLocator(t);
+        m_currentTemplateElements.setElementAt(t,currentTemplateElementsTop);
+        t.execute(this);
+      }
+    }
+    catch(RuntimeException re)
+    {
+    	TransformerException te = new TransformerException(re);
+    	te.setLocator(t);
+    	throw te;
+    }
+    finally
+    {
+      m_currentTemplateElements.pop();
+      xctxt.popSAXLocator();
+    }
+
+    // Check for infinite loops if we have to
+//    if (check)
+//      getStackGuard().pop();
+  }
+    /**
+      * Execute each of the children of a template element.
+      *
+      * @param elem The ElemTemplateElement that contains the children
+      * that should execute.
+      * @param handler The ContentHandler to where the result events
+      * should be fed.
+      *
+      * @throws TransformerException
+      * @xsl.usage advanced
+      */
+     public void executeChildTemplates(
+             ElemTemplateElement elem, ContentHandler handler)
+               throws TransformerException
+     {
+
+       SerializationHandler xoh = this.getSerializationHandler();
+
+       // These may well not be the same!  In this case when calling
+       // the Redirect extension, it has already set the ContentHandler
+       // in the Transformer.
+       SerializationHandler savedHandler = xoh;
+
+       try
+       {
+         xoh.flushPending();
+
+         // %REVIEW% Make sure current node is being pushed.
+         LexicalHandler lex = null;
+         if (handler instanceof LexicalHandler) {
+            lex = (LexicalHandler) handler;
+         }
+         m_serializationHandler = new ToXMLSAXHandler(handler, lex, savedHandler.getEncoding());
+         m_serializationHandler.setTransformer(this);
+         executeChildTemplates(elem, true);
+       }
+       catch (TransformerException e)
+       {
+         throw e;
+       }
+       catch (SAXException se) {
+       	 throw new TransformerException(se);
+       }
+       finally
+       {
+         m_serializationHandler = savedHandler;
+    }
+  }
+
+  /**
+   * Get the keys for the xsl:sort elements.
+   * Note: Should this go into ElemForEach?
+   *
+   * @param foreach Valid ElemForEach element, not null.
+   * @param sourceNodeContext The current node context in the source tree,
+   * needed to evaluate the Attribute Value Templates.
+   *
+   * @return A Vector of NodeSortKeys, or null.
+   *
+   * @throws TransformerException
+   * @xsl.usage advanced
+   */
+  public Vector processSortKeys(ElemForEach foreach, int sourceNodeContext)
+          throws TransformerException
+  {
+
+    Vector keys = null;
+    XPathContext xctxt = m_xcontext;
+    int nElems = foreach.getSortElemCount();
+
+    if (nElems > 0)
+      keys = new Vector();
+
+    // March backwards, collecting the sort keys.
+    for (int i = 0; i < nElems; i++)
+    {
+      ElemSort sort = foreach.getSortElem(i);
+      
+      String langString =
+        (null != sort.getLang())
+        ? sort.getLang().evaluate(xctxt, sourceNodeContext, foreach) : null;
+      String dataTypeString = sort.getDataType().evaluate(xctxt,
+                                sourceNodeContext, foreach);
+
+      if (dataTypeString.indexOf(":") >= 0)
+        System.out.println(
+          "TODO: Need to write the hooks for QNAME sort data type");
+      else if (!(dataTypeString.equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_TEXT))
+               &&!(dataTypeString.equalsIgnoreCase(
+                 Constants.ATTRVAL_DATATYPE_NUMBER)))
+        foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
+                      new Object[]{ Constants.ATTRNAME_DATATYPE,
+                                    dataTypeString });
+
+      boolean treatAsNumbers =
+        ((null != dataTypeString) && dataTypeString.equals(
+        Constants.ATTRVAL_DATATYPE_NUMBER)) ? true : false;
+      String orderString = sort.getOrder().evaluate(xctxt, sourceNodeContext,
+                             foreach);
+
+      if (!(orderString.equalsIgnoreCase(Constants.ATTRVAL_ORDER_ASCENDING))
+              &&!(orderString.equalsIgnoreCase(
+                Constants.ATTRVAL_ORDER_DESCENDING)))
+        foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
+                      new Object[]{ Constants.ATTRNAME_ORDER,
+                                    orderString });
+
+      boolean descending =
+        ((null != orderString) && orderString.equals(
+        Constants.ATTRVAL_ORDER_DESCENDING)) ? true : false;
+      AVT caseOrder = sort.getCaseOrder();
+      boolean caseOrderUpper;
+
+      if (null != caseOrder)
+      {
+        String caseOrderString = caseOrder.evaluate(xctxt, sourceNodeContext,
+                                                    foreach);
+
+        if (!(caseOrderString.equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_UPPER))
+                &&!(caseOrderString.equalsIgnoreCase(
+                  Constants.ATTRVAL_CASEORDER_LOWER)))
+          foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
+                        new Object[]{ Constants.ATTRNAME_CASEORDER,
+                                      caseOrderString });
+
+        caseOrderUpper =
+          ((null != caseOrderString) && caseOrderString.equals(
+          Constants.ATTRVAL_CASEORDER_UPPER)) ? true : false;
+      }
+      else
+      {
+        caseOrderUpper = false;
+      }
+
+      keys.addElement(new NodeSortKey(this, sort.getSelect(), treatAsNumbers,
+                                      descending, langString, caseOrderUpper,
+                                      foreach));
+     }
+
+    return keys;
+  }
+
+  //==========================================================
+  // SECTION: TransformState implementation
+  //==========================================================
+  
+  /**
+   * Get the count of how many elements are 
+   * active.
+   * @return The number of active elements on 
+   * the currentTemplateElements stack.
+   */
+  public int getCurrentTemplateElementsCount()
+  {
+  	return m_currentTemplateElements.size();
+  }
+  
+  
+  /**
+   * Get the count of how many elements are 
+   * active.
+   * @return The number of active elements on 
+   * the currentTemplateElements stack.
+   */
+  public ObjectStack getCurrentTemplateElements()
+  {
+  	return m_currentTemplateElements;
+  }
+
+  /**
+   * Push the current template element.
+   *
+   * @param elem The current ElemTemplateElement (may be null, and then
+   * set via setCurrentElement).
+   */
+  public void pushElemTemplateElement(ElemTemplateElement elem)
+  {
+    m_currentTemplateElements.push(elem);
+  }
+
+  /**
+   * Pop the current template element.
+   */
+  public void popElemTemplateElement()
+  {
+    m_currentTemplateElements.pop();
+  }
+
+  /**
+   * Set the top of the current template elements
+   * stack.
+   *
+   * @param e The current ElemTemplateElement about to
+   * be executed.
+   */
+  public void setCurrentElement(ElemTemplateElement e)
+  {
+    m_currentTemplateElements.setTop(e);
+  }
+
+  /**
+   * Retrieves the current ElemTemplateElement that is
+   * being executed.
+   *
+   * @return The current ElemTemplateElement that is executing,
+   * should not normally be null.
+   */
+  public ElemTemplateElement getCurrentElement()
+  {
+    return (m_currentTemplateElements.size() > 0) ? 
+        (ElemTemplateElement) m_currentTemplateElements.peek() : null;
+  }
+
+  /**
+   * This method retrieves the current context node
+   * in the source tree.
+   *
+   * @return The current context node (should never be null?).
+   */
+  public int getCurrentNode()
+  {
+    return m_xcontext.getCurrentNode();
+  }
+  
+  /**
+   * This method retrieves the xsl:template
+   * that is in effect, which may be a matched template
+   * or a named template.
+   *
+   * <p>Please note that the ElemTemplate returned may
+   * be a default template, and thus may not have a template
+   * defined in the stylesheet.</p>
+   *
+   * @return The current xsl:template, should not be null.
+   */
+  public ElemTemplate getCurrentTemplate()
+  {
+
+    ElemTemplateElement elem = getCurrentElement();
+
+    while ((null != elem)
+           && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE))
+    {
+      elem = elem.getParentElem();
+    }
+
+    return (ElemTemplate) elem;
+  }
+
+  /**
+   * Push both the current xsl:template or xsl:for-each onto the
+   * stack, along with the child node that was matched.
+   * (Note: should this only be used for xsl:templates?? -sb)
+   *
+   * @param template xsl:template or xsl:for-each.
+   * @param child The child that was matched.
+   */
+  public void pushPairCurrentMatched(ElemTemplateElement template, int child)
+  {
+    m_currentMatchTemplates.push(template);
+    m_currentMatchedNodes.push(child);
+  }
+
+  /**
+   * Pop the elements that were pushed via pushPairCurrentMatched.
+   */
+  public void popCurrentMatched()
+  {
+    m_currentMatchTemplates.pop();
+    m_currentMatchedNodes.pop();
+  }
+
+  /**
+   * This method retrieves the xsl:template
+   * that was matched.  Note that this may not be
+   * the same thing as the current template (which
+   * may be from getCurrentElement()), since a named
+   * template may be in effect.
+   *
+   * @return The pushed template that was pushed via pushPairCurrentMatched.
+   */
+  public ElemTemplate getMatchedTemplate()
+  {
+    return (ElemTemplate) m_currentMatchTemplates.peek();
+  }
+
+  /**
+   * Retrieves the node in the source tree that matched
+   * the template obtained via getMatchedTemplate().
+   *
+   * @return The matched node that corresponds to the
+   * match attribute of the current xsl:template.
+   */
+  public int getMatchedNode()
+  {
+    return m_currentMatchedNodes.peepTail();
+  }
+
+  /**
+   * Get the current context node list.
+   *
+   * @return A reset clone of the context node list.
+   */
+  public DTMIterator getContextNodeList()
+  {
+
+    try
+    {
+      DTMIterator cnl = m_xcontext.getContextNodeList();
+
+      return (cnl == null) ? null : (DTMIterator) cnl.cloneWithReset();
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+
+      // should never happen.
+      return null;
+    }
+  }
+
+  /**
+   * Get the TrAX Transformer object in effect.
+   *
+   * @return This object.
+   */
+  public Transformer getTransformer()
+  {
+    return this;
+  }
+
+  //==========================================================
+  // SECTION: Accessor Functions
+  //==========================================================
+
+  /**
+   * Set the stylesheet for this processor.  If this is set, then the
+   * process calls that take only the input .xml will use
+   * this instead of looking for a stylesheet PI.  Also,
+   * setting the stylesheet is needed if you are going
+   * to use the processor as a SAX ContentHandler.
+   *
+   * @param stylesheetRoot A non-null StylesheetRoot object,
+   * or null if you wish to clear the stylesheet reference.
+   */
+  public void setStylesheet(StylesheetRoot stylesheetRoot)
+  {
+    m_stylesheetRoot = stylesheetRoot;
+  }
+
+  /**
+   * Get the current stylesheet for this processor.
+   *
+   * @return The stylesheet that is associated with this
+   * transformer.
+   */
+  public final StylesheetRoot getStylesheet()
+  {
+    return m_stylesheetRoot;
+  }
+
+  /**
+   * Get quietConflictWarnings property. If the quietConflictWarnings
+   * property is set to true, warnings about pattern conflicts won't be
+   * printed to the diagnostics stream.
+   *
+   * @return True if this transformer should not report
+   * template match conflicts.
+   */
+  public boolean getQuietConflictWarnings()
+  {
+    return m_quietConflictWarnings;
+  }
+
+  /**
+   * Set the execution context for XPath.
+   *
+   * @param xcontext A non-null reference to the XPathContext
+   * associated with this transformer.
+   * @xsl.usage internal
+   */
+  public void setXPathContext(XPathContext xcontext)
+  {
+    m_xcontext = xcontext;
+  }
+
+  /**
+   * Get the XPath context associated with this transformer.
+   *
+   * @return The XPathContext reference, never null.
+   */
+  public final XPathContext getXPathContext()
+  {
+    return m_xcontext;
+  }
+
+  /**
+   * Get the SerializationHandler object.
+   *
+   * @return The current SerializationHandler, which may not
+   * be the main result tree manager.
+   */
+  public SerializationHandler getResultTreeHandler()
+  {
+    return m_serializationHandler;
+  }
+
+  /**
+   * Get the SerializationHandler object.
+   *
+   * @return The current SerializationHandler, which may not
+   * be the main result tree manager.
+   */
+  public SerializationHandler getSerializationHandler()
+  {
+    return m_serializationHandler;
+  }
+  
+  /**
+   * Get the KeyManager object.
+   *
+   * @return A reference to the KeyManager object, which should
+   * never be null.
+   */
+  public KeyManager getKeyManager()
+  {
+    return m_keyManager;
+  }
+
+  /**
+   * Check to see if this is a recursive attribute definition.
+   *
+   * @param attrSet A non-null ElemAttributeSet reference.
+   *
+   * @return true if the attribute set is recursive.
+   */
+  public boolean isRecursiveAttrSet(ElemAttributeSet attrSet)
+  {
+
+    if (null == m_attrSetStack)
+    {
+      m_attrSetStack = new Stack();
+    }
+
+    if (!m_attrSetStack.empty())
+    {
+      int loc = m_attrSetStack.search(attrSet);
+
+      if (loc > -1)
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Push an executing attribute set, so we can check for
+   * recursive attribute definitions.
+   *
+   * @param attrSet A non-null ElemAttributeSet reference.
+   */
+  public void pushElemAttributeSet(ElemAttributeSet attrSet)
+  {
+    m_attrSetStack.push(attrSet);
+  }
+
+  /**
+   * Pop the current executing attribute set.
+   */
+  public void popElemAttributeSet()
+  {
+    m_attrSetStack.pop();
+  }
+
+  /**
+   * Get the table of counters, for optimized xsl:number support.
+   *
+   * @return The CountersTable, never null.
+   */
+  public CountersTable getCountersTable()
+  {
+
+    if (null == m_countersTable)
+      m_countersTable = new CountersTable();
+
+    return m_countersTable;
+  }
+
+  /**
+   * Tell if the current template rule is null, i.e. if we are
+   * directly within an apply-templates.  Used for xsl:apply-imports.
+   *
+   * @return True if the current template rule is null.
+   */
+  public boolean currentTemplateRuleIsNull()
+  {
+    return ((!m_currentTemplateRuleIsNull.isEmpty())
+            && (m_currentTemplateRuleIsNull.peek() == true));
+  }
+
+  /**
+   * Push true if the current template rule is null, false
+   * otherwise.
+   *
+   * @param b True if the we are executing an xsl:for-each
+   * (or xsl:call-template?).
+   */
+  public void pushCurrentTemplateRuleIsNull(boolean b)
+  {
+    m_currentTemplateRuleIsNull.push(b);
+  }
+
+  /**
+   * Push true if the current template rule is null, false
+   * otherwise.
+   */
+  public void popCurrentTemplateRuleIsNull()
+  {
+    m_currentTemplateRuleIsNull.pop();
+  }
+
+  /**
+   * Push a funcion result for the currently active EXSLT
+   * <code>func:function</code>.
+   * 
+   * @param val the result of executing an EXSLT
+   * <code>func:result</code> instruction for the current
+   * <code>func:function</code>.
+   */
+  public void pushCurrentFuncResult(Object val) {
+    m_currentFuncResult.push(val);
+  }
+
+  /**
+   * Pops the result of the currently active EXSLT <code>func:function</code>.
+   * 
+   * @return the value of the <code>func:function</code>
+   */
+  public Object popCurrentFuncResult() {
+    return m_currentFuncResult.pop();
+  }
+
+  /**
+   * Determines whether an EXSLT <code>func:result</code> instruction has been
+   * executed for the currently active EXSLT <code>func:function</code>.
+   * 
+   * @return <code>true</code> if and only if a <code>func:result</code>
+   * instruction has been executed
+   */
+  public boolean currentFuncResultSeen() {
+    return !m_currentFuncResult.empty()
+               && m_currentFuncResult.peek() != null;
+  }
+
+  /**
+   * Return the message manager.
+   *
+   * @return The message manager, never null.
+   */
+  public MsgMgr getMsgMgr()
+  {
+
+    if (null == m_msgMgr)
+      m_msgMgr = new MsgMgr(this);
+
+    return m_msgMgr;
+  }
+
+  /**
+   * Set the error event listener.
+   *
+   * @param listener The new error listener.
+   * @throws IllegalArgumentException if
+   */
+  public void setErrorListener(ErrorListener listener)
+          throws IllegalArgumentException
+  {
+
+    synchronized (m_reentryGuard)
+    {
+      if (listener == null)
+        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler");
+
+      m_errorHandler = listener;
+    }
+  }
+
+  /**
+   * Get the current error event handler.
+   *
+   * @return The current error handler, which should never be null.
+   */
+  public ErrorListener getErrorListener()
+  {
+    return m_errorHandler;
+  }
+
+  /**
+   * Look up the value of a feature.
+   *
+   * <p>The feature name is any fully-qualified URI.  It is
+   * possible for an TransformerFactory to recognize a feature name but
+   * to be unable to return its value; this is especially true
+   * in the case of an adapter for a SAX1 Parser, which has
+   * no way of knowing whether the underlying parser is
+   * validating, for example.</p>
+   *
+   * <h3>Open issues:</h3>
+   * <dl>
+   *    <dt><h4>Should getFeature be changed to hasFeature?</h4></dt>
+   *    <dd>Keith Visco writes: Should getFeature be changed to hasFeature?
+   *        It returns a boolean which indicated whether the "state"
+   *        of feature is "true or false". I assume this means whether
+   *        or not a feature is supported? I know SAX is using "getFeature",
+   *        but to me "hasFeature" is cleaner.</dd>
+   * </dl>
+   *
+   * @param name The feature name, which is a fully-qualified
+   *        URI.
+   * @return The current state of the feature (true or false).
+   * @throws org.xml.sax.SAXNotRecognizedException When the
+   *            TransformerFactory does not recognize the feature name.
+   * @throws org.xml.sax.SAXNotSupportedException When the
+   *            TransformerFactory recognizes the feature name but
+   *            cannot determine its value at this time.
+   *
+   * @throws SAXNotRecognizedException
+   * @throws SAXNotSupportedException
+   */
+  public boolean getFeature(String name)
+          throws SAXNotRecognizedException, SAXNotSupportedException
+  {
+
+    if ("http://xml.org/trax/features/sax/input".equals(name))
+      return true;
+    else if ("http://xml.org/trax/features/dom/input".equals(name))
+      return true;
+
+    throw new SAXNotRecognizedException(name);
+  }
+
+  // %TODO% Doc
+
+  /**
+   * NEEDSDOC Method getMode 
+   *
+   *
+   * NEEDSDOC (getMode) @return
+   */
+  public QName getMode()
+  {
+    return m_modes.isEmpty() ? null : (QName) m_modes.peek();
+  }
+
+  // %TODO% Doc
+
+  /**
+   * NEEDSDOC Method pushMode 
+   *
+   *
+   * NEEDSDOC @param mode
+   */
+  public void pushMode(QName mode)
+  {
+    m_modes.push(mode);
+  }
+
+  // %TODO% Doc
+
+  /**
+   * NEEDSDOC Method popMode 
+   *
+   */
+  public void popMode()
+  {
+    m_modes.pop();
+  }
+
+  /**
+   * Called by SourceTreeHandler to start the transformation
+   *  in a separate thread
+   *
+   * NEEDSDOC @param priority
+   */
+  public void runTransformThread(int priority)
+  {
+
+    // used in SourceTreeHandler
+    Thread t = ThreadControllerWrapper.runThread(this, priority);
+    this.setTransformThread(t);
+  }
+
+  /**
+   * Called by this.transform() if isParserEventsOnMain()==false.
+   *  Similar with runTransformThread(), but no priority is set
+   *  and setTransformThread is not set.
+   */
+  public void runTransformThread()
+  {
+    ThreadControllerWrapper.runThread(this, -1);
+  }
+  
+  /**
+   * Called by CoRoutineSAXParser. Launches the CoroutineSAXParser
+   * in a thread, and prepares it to invoke the parser from that thread
+   * upon request. 
+   *  
+   */
+  public static void runTransformThread(Runnable runnable)
+  {
+    ThreadControllerWrapper.runThread(runnable, -1);
+  }
+
+  /**
+   * Used by SourceTreeHandler to wait until the transform
+   *   completes
+   *
+   * @throws SAXException
+   */
+  public void waitTransformThread() throws SAXException
+  {
+
+    // This is called to make sure the task is done.
+    // It is possible that the thread has been reused -
+    // but for a different transformation. ( what if we 
+    // recycle the transformer ? Not a problem since this is
+    // still in use. )
+    Thread transformThread = this.getTransformThread();
+
+    if (null != transformThread)
+    {
+      try
+      {
+        ThreadControllerWrapper.waitThread(transformThread, this);
+
+        if (!this.hasTransformThreadErrorCatcher())
+        {
+          Exception e = this.getExceptionThrown();
+
+          if (null != e)
+          {
+            e.printStackTrace();
+            throw new org.xml.sax.SAXException(e);
+          }
+        }
+
+        this.setTransformThread(null);
+      }
+      catch (InterruptedException ie){}
+    }
+  }
+
+  /**
+   * Get the exception thrown by the secondary thread (normally
+   * the transform thread).
+   *
+   * @return The thrown exception, or null if no exception was
+   * thrown.
+   */
+  public Exception getExceptionThrown()
+  {
+    return m_exceptionThrown;
+  }
+
+  /**
+   * Set the exception thrown by the secondary thread (normally
+   * the transform thread).
+   *
+   * @param e The thrown exception, or null if no exception was
+   * thrown.
+   */
+  public void setExceptionThrown(Exception e)
+  {
+    m_exceptionThrown = e;
+  }
+
+  /**
+   * This is just a way to set the document for run().
+   *
+   * @param doc A non-null reference to the root of the
+   * tree to be transformed.
+   */
+  public void setSourceTreeDocForThread(int doc)
+  {
+    m_doc = doc;
+  }
+
+  /**
+   * From a secondary thread, post the exception, so that
+   * it can be picked up from the main thread.
+   *
+   * @param e The exception that was thrown.
+   */
+  void postExceptionFromThread(Exception e)
+  {
+
+    // Commented out in response to problem reported by Nicola Brown <Nicola.Brown@jacobsrimell.com>
+    //    if(m_reportInPostExceptionFromThread)
+    //    {
+    //      // Consider re-throwing the exception if this flag is set.
+    //      e.printStackTrace();
+    //    }
+    // %REVIEW Need DTM equivelent?    
+    //    if (m_inputContentHandler instanceof SourceTreeHandler)
+    //    {
+    //      SourceTreeHandler sth = (SourceTreeHandler) m_inputContentHandler;
+    //
+    //      sth.setExceptionThrown(e);
+    //    }
+ //   ContentHandler ch = getContentHandler();
+
+    //    if(ch instanceof SourceTreeHandler)
+    //    {
+    //      SourceTreeHandler sth = (SourceTreeHandler) ch;
+    //      ((TransformerImpl)(sth.getTransformer())).postExceptionFromThread(e);
+    //    }
+    // m_isTransformDone = true; // android-removed
+    m_exceptionThrown = e;
+    ;  // should have already been reported via the error handler?
+
+    synchronized (this)
+    {
+
+      // See message from me on 3/27/2001 to Patrick Moore.
+      //      String msg = e.getMessage();
+      // System.out.println(e.getMessage());
+      // Is this really needed?  -sb
+      notifyAll();
+
+      //      if (null == msg)
+      //      {
+      //
+      //        // m_throwNewError = false;
+      //        e.printStackTrace();
+      //      }
+      // throw new org.apache.xml.utils.WrappedRuntimeException(e);
+    }
+  }
+
+  /**
+   * Run the transform thread.
+   */
+  public void run()
+  {
+
+    m_hasBeenReset = false;
+
+    try
+    {
+
+      // int n = ((SourceTreeHandler)getInputContentHandler()).getDTMRoot();
+      // transformNode(n);
+      try
+      {
+        // m_isTransformDone = false; // android-removed
+        
+        // Should no longer be needed...
+//          if(m_inputContentHandler instanceof TransformerHandlerImpl)
+//          {
+//            TransformerHandlerImpl thi = (TransformerHandlerImpl)m_inputContentHandler;
+//            thi.waitForInitialEvents();
+//          }
+
+        transformNode(m_doc);
+        
+      }
+      catch (Exception e)
+      {
+        // e.printStackTrace();
+
+        // Strange that the other catch won't catch this...
+        if (null != m_transformThread)
+          postExceptionFromThread(e);   // Assume we're on the main thread
+        else 
+          throw new RuntimeException(e.getMessage());
+      }
+      finally
+      {
+        // m_isTransformDone = true; // android-removed
+
+        if (m_inputContentHandler instanceof TransformerHandlerImpl)
+        {
+          ((TransformerHandlerImpl) m_inputContentHandler).clearCoRoutine();
+        }
+
+        //        synchronized (this)
+        //        {
+        //          notifyAll();
+        //        }
+      }
+    }
+    catch (Exception e)
+    {
+
+      // e.printStackTrace();
+      if (null != m_transformThread)
+        postExceptionFromThread(e);
+      else 
+        throw new RuntimeException(e.getMessage());         // Assume we're on the main thread.
+    }
+  }
+
+  // Fragment re-execution interfaces for a tool.
+
+  /**
+   * Test whether whitespace-only text nodes are visible in the logical
+   * view of <code>DTM</code>. Normally, this function
+   * will be called by the implementation of <code>DTM</code>;
+   * it is not normally called directly from
+   * user code.
+   *
+   * @param elementHandle int Handle of the element.
+   * @return one of NOTSTRIP, STRIP, or INHERIT.
+   */
+  public short getShouldStripSpace(int elementHandle, DTM dtm)
+  {
+
+    try
+    {
+      org.apache.xalan.templates.WhiteSpaceInfo info =
+        m_stylesheetRoot.getWhiteSpaceInfo(m_xcontext, elementHandle, dtm);
+
+      if (null == info)
+      {
+        return DTMWSFilter.INHERIT;
+      }
+      else
+      {
+
+        // System.out.println("getShouldStripSpace: "+info.getShouldStripSpace());
+        return info.getShouldStripSpace()
+               ? DTMWSFilter.STRIP : DTMWSFilter.NOTSTRIP;
+      }
+    }
+    catch (TransformerException se)
+    {
+      return DTMWSFilter.INHERIT;
+    }
+  }
+  /**
+   * Initializer method.
+   *
+   * @param transformer non-null transformer instance
+   * @param realHandler Content Handler instance
+   */
+   public void init(ToXMLSAXHandler h,Transformer transformer, ContentHandler realHandler)
+   {
+      h.setTransformer(transformer);
+      h.setContentHandler(realHandler);
+   }
+      
+   public void setSerializationHandler(SerializationHandler xoh)
+   {
+      m_serializationHandler = xoh;
+   }
+   
+   
+     
+	/**
+	 * Fire off characters, cdate events.
+	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, char[], int, int)
+	 */
+	public void fireGenerateEvent(
+		int eventType,
+		char[] ch,
+		int start,
+		int length) {
+	}
+
+	/**
+	 * Fire off startElement, endElement events.
+	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, Attributes)
+	 */
+	public void fireGenerateEvent(
+		int eventType,
+		String name,
+		Attributes atts) {
+	}
+
+	/**
+	 * Fire off processingInstruction events.
+	 */
+	public void fireGenerateEvent(int eventType, String name, String data) {
+	}
+
+	/**
+	 * Fire off comment and entity ref events.
+	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String)
+	 */
+	public void fireGenerateEvent(int eventType, String data) {
+	}
+
+	/**
+	 * Fire off startDocument, endDocument events.
+	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int)
+	 */
+	public void fireGenerateEvent(int eventType) {
+	}
+
+    /**
+     * @see org.apache.xml.serializer.SerializerTrace#hasTraceListeners()
+     */
+    public boolean hasTraceListeners() {
+        return false;
+    }
+
+    /**
+     * @return Incremental flag
+     */
+    public boolean getIncremental() {
+        return m_incremental;
+    }
+
+    /**
+     * @return Optimization flag
+     */
+    public boolean getOptimize() {
+        return m_optimizer;
+    }
+
+    /**
+     * @return Source location flag
+     */
+    public boolean getSource_location() {
+        return m_source_location;
+    }
+
+}  // end TransformerImpl class
+
diff --git a/src/main/java/org/apache/xalan/transformer/TreeWalker2Result.java b/src/main/java/org/apache/xalan/transformer/TreeWalker2Result.java
new file mode 100644
index 0000000..3e78cbc
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/TreeWalker2Result.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TreeWalker2Result.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+package org.apache.xalan.transformer;
+
+import org.apache.xalan.serialize.SerializerUtils;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.ref.DTMTreeWalker;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Handle a walk of a tree, but screen out attributes for
+ * the result tree.
+ * @xsl.usage internal
+ */
+public class TreeWalker2Result extends DTMTreeWalker
+{
+
+  /** The transformer instance          */
+  TransformerImpl m_transformer;
+
+  /** The result tree handler          */
+  SerializationHandler m_handler;
+
+  /** Node where to start the tree walk           */
+  int m_startNode;
+
+  /**
+   * Constructor.
+   *
+   * @param transformer Non-null transformer instance
+   * @param handler The Result tree handler to use
+   */
+  public TreeWalker2Result(TransformerImpl transformer,
+                           SerializationHandler handler)
+  {
+
+    super(handler, null);
+
+    m_transformer = transformer;
+    m_handler = handler;
+  }
+
+  /**
+   * Perform a pre-order traversal non-recursive style.
+   *
+   * @param pos Start node for traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverse(int pos) throws org.xml.sax.SAXException
+  {
+    m_dtm = m_transformer.getXPathContext().getDTM(pos);
+    m_startNode = pos;
+
+    super.traverse(pos);
+  }
+        
+        /**
+   * End processing of given node 
+   *
+   *
+   * @param node Node we just finished processing
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void endNode(int node) throws org.xml.sax.SAXException
+  {
+    super.endNode(node);
+    if(DTM.ELEMENT_NODE == m_dtm.getNodeType(node))
+    {
+      m_transformer.getXPathContext().popCurrentNode();
+    }
+  }
+
+  /**
+   * Start traversal of the tree at the given node
+   *
+   *
+   * @param node Starting node for traversal
+   *
+   * @throws TransformerException
+   */
+  protected void startNode(int node) throws org.xml.sax.SAXException
+  {
+
+    XPathContext xcntxt = m_transformer.getXPathContext();
+    try
+    {
+      
+      if (DTM.ELEMENT_NODE == m_dtm.getNodeType(node))
+      {
+        xcntxt.pushCurrentNode(node);                   
+                                        
+        if(m_startNode != node)
+        {
+          super.startNode(node);
+        }
+        else
+        {
+          String elemName = m_dtm.getNodeName(node);
+          String localName = m_dtm.getLocalName(node);
+          String namespace = m_dtm.getNamespaceURI(node);
+                                        
+          //xcntxt.pushCurrentNode(node);       
+          // SAX-like call to allow adding attributes afterwards
+          m_handler.startElement(namespace, localName, elemName);
+          boolean hasNSDecls = false;
+          DTM dtm = m_dtm;
+          for (int ns = dtm.getFirstNamespaceNode(node, true); 
+               DTM.NULL != ns; ns = dtm.getNextNamespaceNode(node, ns, true))
+          {
+            SerializerUtils.ensureNamespaceDeclDeclared(m_handler,dtm, ns);
+          }
+                                                
+                                                
+          for (int attr = dtm.getFirstAttribute(node); 
+               DTM.NULL != attr; attr = dtm.getNextAttribute(attr))
+          {
+            SerializerUtils.addAttribute(m_handler, attr);
+          }
+        }
+                                
+      }
+      else
+      {
+        xcntxt.pushCurrentNode(node);
+        super.startNode(node);
+        xcntxt.popCurrentNode();
+      }
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.xml.sax.SAXException(te);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xalan/transformer/XalanProperties.java b/src/main/java/org/apache/xalan/transformer/XalanProperties.java
new file mode 100644
index 0000000..28df780
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/XalanProperties.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XalanProperties.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+
+package org.apache.xalan.transformer;
+
+/**
+ * <code>XalanProperties</code> defines the features understood by
+ * Xalan.
+ *
+ * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
+ * @since May 23, 2001
+ */
+public class XalanProperties
+{
+  public final static String SOURCE_LOCATION
+    = "http://xml.apache.org/xalan/properties/source-location";
+}
diff --git a/src/main/java/org/apache/xalan/transformer/XalanTransformState.java b/src/main/java/org/apache/xalan/transformer/XalanTransformState.java
new file mode 100644
index 0000000..cae10a2
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/XalanTransformState.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XalanTransformState.java 468645 2006-10-28 06:57:24Z minchau $
+ */
+
+package org.apache.xalan.transformer;
+
+import javax.xml.transform.Transformer;
+
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * Before the serializer merge, the TransformState interface was
+ * implemented by ResultTreeHandler.
+ */
+public class XalanTransformState
+    implements TransformState {
+        
+    Node m_node = null;
+    ElemTemplateElement m_currentElement = null;
+    ElemTemplate m_currentTemplate = null;
+    ElemTemplate m_matchedTemplate = null;
+    int m_currentNodeHandle = DTM.NULL;
+    Node m_currentNode = null;
+    int m_matchedNode = DTM.NULL;
+    DTMIterator m_contextNodeList = null;
+    boolean m_elemPending = false;    
+    TransformerImpl m_transformer = null;
+
+    /**
+     * @see org.apache.xml.serializer.TransformStateSetter#setCurrentNode(Node)
+     */
+    public void setCurrentNode(Node n) {
+        m_node = n;
+    }
+
+    /**
+     * @see org.apache.xml.serializer.TransformStateSetter#resetState(Transformer)
+     */
+    public void resetState(Transformer transformer) {
+        if ((transformer != null) && (transformer instanceof TransformerImpl)) {
+           m_transformer = (TransformerImpl)transformer;
+           m_currentElement = m_transformer.getCurrentElement();
+           m_currentTemplate = m_transformer.getCurrentTemplate();
+           m_matchedTemplate = m_transformer.getMatchedTemplate();
+           int currentNodeHandle = m_transformer.getCurrentNode();
+           DTM dtm = m_transformer.getXPathContext().getDTM(currentNodeHandle);
+           m_currentNode = dtm.getNode(currentNodeHandle);
+           m_matchedNode = m_transformer.getMatchedNode();
+           m_contextNodeList = m_transformer.getContextNodeList();    
+        }       
+    }
+
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getCurrentElement()
+     */
+    public ElemTemplateElement getCurrentElement() {
+      if (m_elemPending)
+         return m_currentElement;
+      else
+         return m_transformer.getCurrentElement();
+    }
+
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getCurrentNode()
+     */
+    public Node getCurrentNode() {
+      if (m_currentNode != null) {
+         return m_currentNode;
+      } else {
+         DTM dtm = m_transformer.getXPathContext().getDTM(m_transformer.getCurrentNode());
+         return dtm.getNode(m_transformer.getCurrentNode());
+      }
+    }
+    
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getCurrentTemplate()
+     */
+    public ElemTemplate getCurrentTemplate() {
+       if (m_elemPending)
+         return m_currentTemplate;
+       else
+         return m_transformer.getCurrentTemplate();
+    }
+
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getMatchedTemplate()
+     */
+    public ElemTemplate getMatchedTemplate() {
+      if (m_elemPending)
+         return m_matchedTemplate;
+      else
+         return m_transformer.getMatchedTemplate();
+    }
+
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getMatchedNode()
+     */
+    public Node getMatchedNode() {
+ 
+       if (m_elemPending) {
+         DTM dtm = m_transformer.getXPathContext().getDTM(m_matchedNode);
+         return dtm.getNode(m_matchedNode);
+       } else {
+         DTM dtm = m_transformer.getXPathContext().getDTM(m_transformer.getMatchedNode());
+         return dtm.getNode(m_transformer.getMatchedNode());
+       }
+    }
+
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getContextNodeList()
+     */
+    public NodeIterator getContextNodeList() {
+      if (m_elemPending) {
+          return new org.apache.xml.dtm.ref.DTMNodeIterator(m_contextNodeList);
+      } else {
+          return new org.apache.xml.dtm.ref.DTMNodeIterator(m_transformer.getContextNodeList());
+      }
+    }
+    /**
+     * @see org.apache.xalan.transformer.TransformState#getTransformer()
+     */
+    public Transformer getTransformer() {
+        return m_transformer;
+    }
+
+}
diff --git a/src/main/java/org/apache/xalan/transformer/package.html b/src/main/java/org/apache/xalan/transformer/package.html
new file mode 100644
index 0000000..763b1c1
--- /dev/null
+++ b/src/main/java/org/apache/xalan/transformer/package.html
@@ -0,0 +1,39 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468645 2006-10-28 06:57:24Z minchau $ -->
+<html>
+  <title>Xalan Transformer Package.</title>
+  <body>
+    <p>In charge of run-time transformations and the production of result trees.</p>
+    
+    <p>{@link org.apache.xalan.transformer.TransformerImpl} implements the 
+    {@link javax.xml.transform.Transformer} interface, and is the core representation 
+    of the transformation execution.</p>
+    <p>For each node in the XML source, TransformerImpl uses the StylesheetRoot and underlying XSLT schema to determine which
+    template to apply: one of the templates in the StylesheetRoot, a default template rule as specified in the XSLT spec, or
+    none.</p>
+    <p>The Transformer works with {@link org.apache.xml.serializer.SerializationHandler} to 
+    forward the SAX-like events produced by the
+    transformation to the appropriate output ContentHandler.</p>
+    <p>To the degree possible, the parsing of the XML source and application of the Templates object to that source are performed
+    concurrently in separate threads. When necessary, the Transformer waits for the parse events that must be in place before a
+    given template may be applied.</p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xalan/xslt/EnvironmentCheck.java b/src/main/java/org/apache/xalan/xslt/EnvironmentCheck.java
new file mode 100644
index 0000000..7ba3899
--- /dev/null
+++ b/src/main/java/org/apache/xalan/xslt/EnvironmentCheck.java
@@ -0,0 +1,1296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: EnvironmentCheck.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class to report simple information about the environment.
+ * Simplistic reporting about certain classes found in your JVM may 
+ * help answer some FAQs for simple problems.
+ *
+ * <p>Usage-command line:  
+ * <code>
+ * java org.apache.xalan.xslt.EnvironmentCheck [-out outFile]
+ * </code></p>
+ * 
+ * <p>Usage-from program:  
+ * <code>
+ * boolean environmentOK = 
+ * (new EnvironmentCheck()).checkEnvironment(yourPrintWriter);
+ * </code></p>
+ *
+ * <p>Usage-from stylesheet:  
+ * <code><pre>
+ *    &lt;?xml version="1.0"?&gt;
+ *    &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ *        xmlns:xalan="http://xml.apache.org/xalan"
+ *        exclude-result-prefixes="xalan"&gt;
+ *    &lt;xsl:output indent="yes"/&gt;
+ *    &lt;xsl:template match="/"&gt;
+ *      &lt;xsl:copy-of select="xalan:checkEnvironment()"/&gt;
+ *    &lt;/xsl:template&gt;
+ *    &lt;/xsl:stylesheet&gt;
+ * </pre></code></p>
+ *  
+ * <p>Xalan users reporting problems are encouraged to use this class 
+ * to see if there are potential problems with their actual 
+ * Java environment <b>before</b> reporting a bug.  Note that you 
+ * should both check from the JVM/JRE's command line as well as 
+ * temporarily calling checkEnvironment() directly from your code, 
+ * since the classpath may differ (especially for servlets, etc).</p>
+ *
+ * <p>Also see http://xml.apache.org/xalan-j/faq.html</p>
+ *
+ * <p>Note: This class is pretty simplistic: 
+ * results are not necessarily definitive nor will it find all 
+ * problems related to environment setup.  Also, you should avoid 
+ * calling this in deployed production code, both because it is 
+ * quite slow and because it forces classes to get loaded.</p>
+ *
+ * <p>Note: This class explicitly has very limited compile-time 
+ * dependencies to enable easy compilation and usage even when 
+ * Xalan, DOM/SAX/JAXP, etc. are not present.</p>
+ * 
+ * <p>Note: for an improved version of this utility, please see 
+ * the xml-commons' project Which utility which does the same kind 
+ * of thing but in a much simpler manner.</p>
+ *
+ * @author Shane_Curcuru@us.ibm.com
+ * @version $Id: EnvironmentCheck.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+public class EnvironmentCheck
+{
+
+  /**
+   * Command line runnability: checks for [-out outFilename] arg.
+   * <p>Command line entrypoint; Sets output and calls 
+   * {@link #checkEnvironment(PrintWriter)}.</p>
+   * @param args command line args
+   */
+  public static void main(String[] args)
+  {
+    // Default to System.out, autoflushing
+    PrintWriter sendOutputTo = new PrintWriter(System.out, true);
+
+    // Read our simplistic input args, if supplied
+    for (int i = 0; i < args.length; i++)
+    {
+      if ("-out".equalsIgnoreCase(args[i]))
+      {
+        i++;
+
+        if (i < args.length)
+        {
+          try
+          {
+            sendOutputTo = new PrintWriter(new FileWriter(args[i], true));
+          }
+          catch (Exception e)
+          {
+            System.err.println("# WARNING: -out " + args[i] + " threw "
+                               + e.toString());
+          }
+        }
+        else
+        {
+          System.err.println(
+            "# WARNING: -out argument should have a filename, output sent to console");
+        }
+      }
+    }
+
+    EnvironmentCheck app = new EnvironmentCheck();
+    app.checkEnvironment(sendOutputTo);
+  }
+
+  /**
+   * Programmatic entrypoint: Report on basic Java environment 
+   * and CLASSPATH settings that affect Xalan.
+   *
+   * <p>Note that this class is not advanced enough to tell you 
+   * everything about the environment that affects Xalan, and 
+   * sometimes reports errors that will not actually affect 
+   * Xalan's behavior.  Currently, it very simplistically 
+   * checks the JVM's environment for some basic properties and 
+   * logs them out; it will report a problem if it finds a setting 
+   * or .jar file that is <i>likely</i> to cause problems.</p>
+   *
+   * <p>Advanced users can peruse the code herein to help them 
+   * investigate potential environment problems found; other users 
+   * may simply send the output from this tool along with any bugs 
+   * they submit to help us in the debugging process.</p>
+   *
+   * @param pw PrintWriter to send output to; can be sent to a 
+   * file that will look similar to a Properties file; defaults 
+   * to System.out if null
+   * @return true if your environment appears to have no major 
+   * problems; false if potential environment problems found
+   * @see #getEnvironmentHash()
+   */
+  public boolean checkEnvironment(PrintWriter pw)
+  {
+
+    // Use user-specified output writer if non-null
+    if (null != pw)
+      outWriter = pw;
+
+    // Setup a hash to store various environment information in
+    Hashtable hash = getEnvironmentHash();
+
+    // Check for ERROR keys in the hashtable, and print report
+    boolean environmentHasErrors = writeEnvironmentReport(hash);
+
+    if (environmentHasErrors)
+    {
+      // Note: many logMsg calls have # at the start to 
+      //  fake a property-file like output
+      logMsg("# WARNING: Potential problems found in your environment!");
+      logMsg("#    Check any 'ERROR' items above against the Xalan FAQs");
+      logMsg("#    to correct potential problems with your classes/jars");
+      logMsg("#    http://xml.apache.org/xalan-j/faq.html");
+      if (null != outWriter)
+        outWriter.flush();
+      return false;
+    }
+    else
+    {
+      logMsg("# YAHOO! Your environment seems to be OK.");
+      if (null != outWriter)
+        outWriter.flush();
+      return true;
+    }
+  }
+
+  /**
+   * Fill a hash with basic environment settings that affect Xalan.
+   *
+   * <p>Worker method called from various places.</p>
+   * <p>Various system and CLASSPATH, etc. properties are put into 
+   * the hash as keys with a brief description of the current state 
+   * of that item as the value.  Any serious problems will be put in 
+   * with a key that is prefixed with {@link #ERROR 'ERROR.'} so it
+   * stands out in any resulting report; also a key with just that 
+   * constant will be set as well for any error.</p>
+   * <p>Note that some legitimate cases are flaged as potential 
+   * errors - namely when a developer recompiles xalan.jar on their 
+   * own - and even a non-error state doesn't guaruntee that 
+   * everything in the environment is correct.  But this will help 
+   * point out the most common classpath and system property
+   * problems that we've seen.</p>   
+   *
+   * @return Hashtable full of useful environment info about Xalan 
+   * and related system properties, etc.
+   */
+  public Hashtable getEnvironmentHash()
+  {
+    // Setup a hash to store various environment information in
+    Hashtable hash = new Hashtable();
+
+    // Call various worker methods to fill in the hash
+    //  These are explicitly separate for maintenance and so 
+    //  advanced users could call them standalone
+    checkJAXPVersion(hash);
+    checkProcessorVersion(hash);
+    checkParserVersion(hash);
+    checkAntVersion(hash);
+    checkDOMVersion(hash);
+    checkSAXVersion(hash);
+    checkSystemProperties(hash);
+
+    return hash;
+  }
+
+  /**
+   * Dump a basic Xalan environment report to outWriter.  
+   *
+   * <p>This dumps a simple header and then each of the entries in 
+   * the Hashtable to our PrintWriter; it does special processing 
+   * for entries that are .jars found in the classpath.</p>
+   *
+   * @param h Hashtable of items to report on; presumably
+   * filled in by our various check*() methods
+   * @return true if your environment appears to have no major 
+   * problems; false if potential environment problems found
+   * @see #appendEnvironmentReport(Node, Document, Hashtable)
+   * for an equivalent that appends to a Node instead
+   */
+  protected boolean writeEnvironmentReport(Hashtable h)
+  {
+
+    if (null == h)
+    {
+      logMsg("# ERROR: writeEnvironmentReport called with null Hashtable");
+      return false;
+    }
+
+    boolean errors = false;
+
+    logMsg(
+      "#---- BEGIN writeEnvironmentReport($Revision: 468646 $): Useful stuff found: ----");
+
+    // Fake the Properties-like output
+    for (Enumeration keys = h.keys(); 
+         keys.hasMoreElements();
+        /* no increment portion */
+        )
+    {
+      Object key = keys.nextElement();
+      String keyStr = (String) key;
+      try
+      {
+        // Special processing for classes found..
+        if (keyStr.startsWith(FOUNDCLASSES))
+        {
+          Vector v = (Vector) h.get(keyStr);
+          errors |= logFoundJars(v, keyStr);
+        }
+        // ..normal processing for all other entries
+        else
+        {
+          // Note: we could just check for the ERROR key by itself, 
+          //    since we now set that, but since we have to go 
+          //    through the whole hash anyway, do it this way,
+          //    which is safer for maintenance
+          if (keyStr.startsWith(ERROR))
+          {
+            errors = true;
+          }
+          logMsg(keyStr + "=" + h.get(keyStr));
+        }
+      }
+      catch (Exception e)
+      {
+        logMsg("Reading-" + key + "= threw: " + e.toString());
+      }
+    }
+
+    logMsg(
+      "#----- END writeEnvironmentReport: Useful properties found: -----");
+
+    return errors;
+  }
+
+  /** Prefixed to hash keys that signify serious problems.  */
+  public static final String ERROR = "ERROR.";
+
+  /** Added to descriptions that signify potential problems.  */
+  public static final String WARNING = "WARNING.";
+
+  /** Value for any error found.  */
+  public static final String ERROR_FOUND = "At least one error was found!";
+
+  /** Prefixed to hash keys that signify version numbers.  */
+  public static final String VERSION = "version.";
+
+  /** Prefixed to hash keys that signify .jars found in classpath.  */
+  public static final String FOUNDCLASSES = "foundclasses.";
+
+  /** Marker that a class or .jar was found.  */
+  public static final String CLASS_PRESENT = "present-unknown-version";
+
+  /** Marker that a class or .jar was not found.  */
+  public static final String CLASS_NOTPRESENT = "not-present";
+
+  /** Listing of common .jar files that include Xalan-related classes.  */
+  public String[] jarNames =
+  {
+    "xalan.jar", "xalansamples.jar", "xalanj1compat.jar", "xalanservlet.jar",
+    "serializer.jar",   // Serializer (shared between Xalan & Xerces)
+    "xerces.jar",       // Xerces-J 1.x
+    "xercesImpl.jar",   // Xerces-J 2.x
+    "testxsl.jar", 
+    "crimson.jar", 
+    "lotusxsl.jar", 
+    "jaxp.jar", "parser.jar", "dom.jar", "sax.jar", "xml.jar", 
+    "xml-apis.jar",
+    "xsltc.jar"
+  };
+
+  /**
+   * Print out report of .jars found in a classpath. 
+   *
+   * Takes the information encoded from a checkPathForJars() 
+   * call and dumps it out to our PrintWriter.
+   *
+   * @param v Vector of Hashtables of .jar file info
+   * @param desc description to print out in header
+   *
+   * @return false if OK, true if any .jars were reported 
+   * as having errors
+   * @see #checkPathForJars(String, String[])
+   */
+  protected boolean logFoundJars(Vector v, String desc)
+  {
+
+    if ((null == v) || (v.size() < 1))
+      return false;
+
+    boolean errors = false;
+
+    logMsg("#---- BEGIN Listing XML-related jars in: " + desc + " ----");
+
+    for (int i = 0; i < v.size(); i++)
+    {
+      Hashtable subhash = (Hashtable) v.elementAt(i);
+
+      for (Enumeration keys = subhash.keys(); 
+           keys.hasMoreElements();
+           /* no increment portion */
+          )
+      {
+        Object key = keys.nextElement();
+        String keyStr = (String) key;
+        try
+        {
+          if (keyStr.startsWith(ERROR))
+          {
+            errors = true;
+          }
+          logMsg(keyStr + "=" + subhash.get(keyStr));
+
+        }
+        catch (Exception e)
+        {
+          errors = true;
+          logMsg("Reading-" + key + "= threw: " + e.toString());
+        }
+      }
+    }
+
+    logMsg("#----- END Listing XML-related jars in: " + desc + " -----");
+
+    return errors;
+  }
+
+  /**
+   * Stylesheet extension entrypoint: Dump a basic Xalan 
+   * environment report from getEnvironmentHash() to a Node.  
+   * 
+   * <p>Copy of writeEnvironmentReport that creates a Node suitable 
+   * for other processing instead of a properties-like text output.
+   * </p>
+   * @param container Node to append our report to
+   * @param factory Document providing createElement, etc. services
+   * @param h Hash presumably from {@link #getEnvironmentHash()}
+   * @see #writeEnvironmentReport(Hashtable)
+   * for an equivalent that writes to a PrintWriter instead
+   */
+  public void appendEnvironmentReport(Node container, Document factory, Hashtable h)
+  {
+    if ((null == container) || (null == factory))
+    {
+      return;
+    }
+  
+    try
+    {
+      Element envCheckNode = factory.createElement("EnvironmentCheck");
+      envCheckNode.setAttribute("version", "$Revision: 468646 $");
+      container.appendChild(envCheckNode);
+
+      if (null == h)
+      {
+        Element statusNode = factory.createElement("status");
+        statusNode.setAttribute("result", "ERROR");
+        statusNode.appendChild(factory.createTextNode("appendEnvironmentReport called with null Hashtable!"));
+        envCheckNode.appendChild(statusNode);
+        return;
+      }
+
+      boolean errors = false;
+
+      Element hashNode = factory.createElement("environment");
+      envCheckNode.appendChild(hashNode);
+      
+      for (Enumeration keys = h.keys(); 
+           keys.hasMoreElements();
+          /* no increment portion */
+          )
+      {
+        Object key = keys.nextElement();
+        String keyStr = (String) key;
+        try
+        {
+          // Special processing for classes found..
+          if (keyStr.startsWith(FOUNDCLASSES))
+          {
+            Vector v = (Vector) h.get(keyStr);
+            // errors |= logFoundJars(v, keyStr);
+            errors |= appendFoundJars(hashNode, factory, v, keyStr);
+          }
+          // ..normal processing for all other entries
+          else 
+          {
+            // Note: we could just check for the ERROR key by itself, 
+            //    since we now set that, but since we have to go 
+            //    through the whole hash anyway, do it this way,
+            //    which is safer for maintenance
+            if (keyStr.startsWith(ERROR))
+            {
+              errors = true;
+            }
+            Element node = factory.createElement("item");
+            node.setAttribute("key", keyStr);
+            node.appendChild(factory.createTextNode((String)h.get(keyStr)));
+            hashNode.appendChild(node);
+          }
+        }
+        catch (Exception e)
+        {
+          errors = true;
+          Element node = factory.createElement("item");
+          node.setAttribute("key", keyStr);
+          node.appendChild(factory.createTextNode(ERROR + " Reading " + key + " threw: " + e.toString()));
+          hashNode.appendChild(node);
+        }
+      } // end of for...
+
+      Element statusNode = factory.createElement("status");
+      statusNode.setAttribute("result", (errors ? "ERROR" : "OK" ));
+      envCheckNode.appendChild(statusNode);
+    }
+    catch (Exception e2)
+    {
+      System.err.println("appendEnvironmentReport threw: " + e2.toString());
+      e2.printStackTrace();
+    }
+  }    
+
+  /**
+   * Print out report of .jars found in a classpath. 
+   *
+   * Takes the information encoded from a checkPathForJars() 
+   * call and dumps it out to our PrintWriter.
+   *
+   * @param container Node to append our report to
+   * @param factory Document providing createElement, etc. services
+   * @param v Vector of Hashtables of .jar file info
+   * @param desc description to print out in header
+   *
+   * @return false if OK, true if any .jars were reported 
+   * as having errors
+   * @see #checkPathForJars(String, String[])
+   */
+  protected boolean appendFoundJars(Node container, Document factory, 
+        Vector v, String desc)
+  {
+
+    if ((null == v) || (v.size() < 1))
+      return false;
+
+    boolean errors = false;
+
+    for (int i = 0; i < v.size(); i++)
+    {
+      Hashtable subhash = (Hashtable) v.elementAt(i);
+
+      for (Enumeration keys = subhash.keys(); 
+           keys.hasMoreElements();
+           /* no increment portion */
+          )
+      {
+        Object key = keys.nextElement();
+        try
+        {
+          String keyStr = (String) key;
+          if (keyStr.startsWith(ERROR))
+          {
+            errors = true;
+          }
+          Element node = factory.createElement("foundJar");
+          node.setAttribute("name", keyStr.substring(0, keyStr.indexOf("-")));
+          node.setAttribute("desc", keyStr.substring(keyStr.indexOf("-") + 1));
+          node.appendChild(factory.createTextNode((String)subhash.get(keyStr)));
+          container.appendChild(node);
+        }
+        catch (Exception e)
+        {
+          errors = true;
+          Element node = factory.createElement("foundJar");
+          node.appendChild(factory.createTextNode(ERROR + " Reading " + key + " threw: " + e.toString()));
+          container.appendChild(node);
+        }
+      }
+    }
+    return errors;
+  }
+
+  /**
+   * Fillin hash with info about SystemProperties.  
+   *
+   * Logs java.class.path and other likely paths; then attempts 
+   * to search those paths for .jar files with Xalan-related classes.
+   *
+   * //@todo NOTE: We don't actually search java.ext.dirs for 
+   * //  *.jar files therein! This should be updated
+   *
+   * @param h Hashtable to put information in
+   * @see #jarNames
+   * @see #checkPathForJars(String, String[])
+   */
+  protected void checkSystemProperties(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    // Grab java version for later use
+    try
+    {
+      String javaVersion = System.getProperty("java.version");
+
+      h.put("java.version", javaVersion);
+    }
+    catch (SecurityException se)
+    {
+
+      // For applet context, etc.
+      h.put(
+        "java.version",
+        "WARNING: SecurityException thrown accessing system version properties");
+    }
+
+    // Printout jar files on classpath(s) that may affect operation
+    //  Do this in order
+    try
+    {
+
+      // This is present in all JVM's
+      String cp = System.getProperty("java.class.path");
+
+      h.put("java.class.path", cp);
+
+      Vector classpathJars = checkPathForJars(cp, jarNames);
+
+      if (null != classpathJars)
+        h.put(FOUNDCLASSES + "java.class.path", classpathJars);
+
+      // Also check for JDK 1.2+ type classpaths
+      String othercp = System.getProperty("sun.boot.class.path");
+
+      if (null != othercp)
+      {
+        h.put("sun.boot.class.path", othercp);
+
+        classpathJars = checkPathForJars(othercp, jarNames);
+
+        if (null != classpathJars)
+          h.put(FOUNDCLASSES + "sun.boot.class.path", classpathJars);
+      }
+
+      //@todo NOTE: We don't actually search java.ext.dirs for 
+      //  *.jar files therein! This should be updated
+      othercp = System.getProperty("java.ext.dirs");
+
+      if (null != othercp)
+      {
+        h.put("java.ext.dirs", othercp);
+
+        classpathJars = checkPathForJars(othercp, jarNames);
+
+        if (null != classpathJars)
+          h.put(FOUNDCLASSES + "java.ext.dirs", classpathJars);
+      }
+
+      //@todo also check other System properties' paths?
+      //  v2 = checkPathForJars(System.getProperty("sun.boot.library.path"), jarNames);   // ?? may not be needed
+      //  v3 = checkPathForJars(System.getProperty("java.library.path"), jarNames);   // ?? may not be needed
+    }
+    catch (SecurityException se2)
+    {
+      // For applet context, etc.
+      h.put(
+        "java.class.path",
+        "WARNING: SecurityException thrown accessing system classpath properties");
+    }
+  }
+
+  /**
+   * Cheap-o listing of specified .jars found in the classpath. 
+   *
+   * cp should be separated by the usual File.pathSeparator.  We 
+   * then do a simplistic search of the path for any requested 
+   * .jar filenames, and return a listing of their names and 
+   * where (apparently) they came from.
+   *
+   * @param cp classpath to search
+   * @param jars array of .jar base filenames to look for
+   *
+   * @return Vector of Hashtables filled with info about found .jars
+   * @see #jarNames
+   * @see #logFoundJars(Vector, String)
+   * @see #appendFoundJars(Node, Document, Vector, String )
+   * @see #getApparentVersion(String, long)
+   */
+  protected Vector checkPathForJars(String cp, String[] jars)
+  {
+
+    if ((null == cp) || (null == jars) || (0 == cp.length())
+            || (0 == jars.length))
+      return null;
+
+    Vector v = new Vector();
+    StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);
+
+    while (st.hasMoreTokens())
+    {
+
+      // Look at each classpath entry for each of our requested jarNames
+      String filename = st.nextToken();
+
+      for (int i = 0; i < jars.length; i++)
+      {
+        if (filename.indexOf(jars[i]) > -1)
+        {
+          File f = new File(filename);
+
+          if (f.exists())
+          {
+
+            // If any requested jarName exists, report on 
+            //  the details of that .jar file
+            try
+            {
+              Hashtable h = new Hashtable(2);
+              // Note "-" char is looked for in appendFoundJars
+              h.put(jars[i] + "-path", f.getAbsolutePath());
+             
+              // We won't bother reporting on the xalan.jar apparent version
+              // since this requires knowing the jar size of the xalan.jar
+              // before we build it. 
+              // For other jars, eg. xml-apis.jar and xercesImpl.jar, we 
+              // report the apparent version of the file we've found
+              if (!("xalan.jar".equalsIgnoreCase(jars[i]))) {              
+                h.put(jars[i] + "-apparent.version",
+                    getApparentVersion(jars[i], f.length()));
+              }
+              v.addElement(h);
+            }
+            catch (Exception e)
+            {
+
+              /* no-op, don't add it  */
+            }
+          }
+          else
+          {
+            Hashtable h = new Hashtable(2);
+            // Note "-" char is looked for in appendFoundJars
+            h.put(jars[i] + "-path", WARNING + " Classpath entry: " 
+                  + filename + " does not exist");
+            h.put(jars[i] + "-apparent.version", CLASS_NOTPRESENT);
+            v.addElement(h);
+          }
+        }
+      }
+    }
+
+    return v;
+  }
+
+  /**
+   * Cheap-o method to determine the product version of a .jar.   
+   *
+   * Currently does a lookup into a local table of some recent 
+   * shipped Xalan builds to determine where the .jar probably 
+   * came from.  Note that if you recompile Xalan or Xerces 
+   * yourself this will likely report a potential error, since 
+   * we can't certify builds other than the ones we ship.
+   * Only reports against selected posted Xalan-J builds.
+   *
+   * //@todo actually look up version info in manifests
+   *
+   * @param jarName base filename of the .jarfile
+   * @param jarSize size of the .jarfile
+   *
+   * @return String describing where the .jar file probably 
+   * came from
+   */
+  protected String getApparentVersion(String jarName, long jarSize)
+  {
+    // If we found a matching size and it's for our 
+    //  jar, then return it's description
+    // Lookup in static jarVersions Hashtable
+    String foundSize = (String) jarVersions.get(new Long(jarSize));
+
+    if ((null != foundSize) && (foundSize.startsWith(jarName)))
+    {
+      return foundSize;
+    }
+    else
+    {
+      if ("xerces.jar".equalsIgnoreCase(jarName)
+              || "xercesImpl.jar".equalsIgnoreCase(jarName))
+//              || "xalan.jar".equalsIgnoreCase(jarName))
+      {
+
+        // For xalan.jar and xerces.jar/xercesImpl.jar, which we ship together:
+        // The jar is not from a shipped copy of xalan-j, so 
+        //  it's up to the user to ensure that it's compatible
+        return jarName + " " + WARNING + CLASS_PRESENT;
+      }
+      else
+      {
+
+        // Otherwise, it's just a jar we don't have the version info calculated for
+        return jarName + " " + CLASS_PRESENT;
+      }
+    }
+  }
+
+  /**
+   * Report version information about JAXP interfaces.
+   *
+   * Currently distinguishes between JAXP 1.0.1 and JAXP 1.1, 
+   * and not found; only tests the interfaces, and does not 
+   * check for reference implementation versions.
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkJAXPVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    final Class noArgs[] = new Class[0];
+    Class clazz = null;
+
+    try
+    {
+      final String JAXP1_CLASS = "javax.xml.parsers.DocumentBuilder";
+      final String JAXP11_METHOD = "getDOMImplementation";
+
+      clazz = ObjectFactory.findProviderClass(
+        JAXP1_CLASS, ObjectFactory.findClassLoader(), true);
+
+      Method method = clazz.getMethod(JAXP11_METHOD, noArgs);
+
+      // If we succeeded, we at least have JAXP 1.1 available
+      h.put(VERSION + "JAXP", "1.1 or higher");
+    }
+    catch (Exception e)
+    {
+      if (null != clazz)
+      {
+
+        // We must have found the class itself, just not the 
+        //  method, so we (probably) have JAXP 1.0.1
+        h.put(ERROR + VERSION + "JAXP", "1.0.1");
+        h.put(ERROR, ERROR_FOUND);
+      }
+      else
+      {
+        // We couldn't even find the class, and don't have 
+        //  any JAXP support at all, or only have the 
+        //  transform half of it
+        h.put(ERROR + VERSION + "JAXP", CLASS_NOTPRESENT);
+        h.put(ERROR, ERROR_FOUND);
+      }
+    }
+  }
+
+  /**
+   * Report product version information from Xalan-J.
+   *
+   * Looks for version info in xalan.jar from Xalan-J products.
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkProcessorVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    try
+    {
+      final String XALAN1_VERSION_CLASS =
+        "org.apache.xalan.xslt.XSLProcessorVersion";
+
+      Class clazz = ObjectFactory.findProviderClass(
+        XALAN1_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      // Found Xalan-J 1.x, grab it's version fields
+      StringBuffer buf = new StringBuffer();
+      Field f = clazz.getField("PRODUCT");
+
+      buf.append(f.get(null));
+      buf.append(';');
+
+      f = clazz.getField("LANGUAGE");
+
+      buf.append(f.get(null));
+      buf.append(';');
+
+      f = clazz.getField("S_VERSION");
+
+      buf.append(f.get(null));
+      buf.append(';');
+      h.put(VERSION + "xalan1", buf.toString());
+    }
+    catch (Exception e1)
+    {
+      h.put(VERSION + "xalan1", CLASS_NOTPRESENT);
+    }
+
+    try
+    {
+      // NOTE: This is the old Xalan 2.0, 2.1, 2.2 version class, 
+      //    is being replaced by class below
+      final String XALAN2_VERSION_CLASS =
+        "org.apache.xalan.processor.XSLProcessorVersion";
+
+      Class clazz = ObjectFactory.findProviderClass(
+        XALAN2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      // Found Xalan-J 2.x, grab it's version fields
+      StringBuffer buf = new StringBuffer();
+      Field f = clazz.getField("S_VERSION");
+      buf.append(f.get(null));
+
+      h.put(VERSION + "xalan2x", buf.toString());
+    }
+    catch (Exception e2)
+    {
+      h.put(VERSION + "xalan2x", CLASS_NOTPRESENT);
+    }
+    try
+    {
+      // NOTE: This is the new Xalan 2.2+ version class
+      final String XALAN2_2_VERSION_CLASS =
+        "org.apache.xalan.Version";
+      final String XALAN2_2_VERSION_METHOD = "getVersion";
+      final Class noArgs[] = new Class[0];
+
+      Class clazz = ObjectFactory.findProviderClass(
+        XALAN2_2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      Method method = clazz.getMethod(XALAN2_2_VERSION_METHOD, noArgs);
+      Object returnValue = method.invoke(null, new Object[0]);
+
+      h.put(VERSION + "xalan2_2", (String)returnValue);
+    }
+    catch (Exception e2)
+    {
+      h.put(VERSION + "xalan2_2", CLASS_NOTPRESENT);
+    }
+  }
+
+  /**
+   * Report product version information from common parsers.
+   *
+   * Looks for version info in xerces.jar/xercesImpl.jar/crimson.jar.
+   *
+   * //@todo actually look up version info in crimson manifest
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkParserVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    try
+    {
+      final String XERCES1_VERSION_CLASS = "org.apache.xerces.framework.Version";
+
+      Class clazz = ObjectFactory.findProviderClass(
+        XERCES1_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      // Found Xerces-J 1.x, grab it's version fields
+      Field f = clazz.getField("fVersion");
+      String parserVersion = (String) f.get(null);
+
+      h.put(VERSION + "xerces1", parserVersion);
+    }
+    catch (Exception e)
+    {
+      h.put(VERSION + "xerces1", CLASS_NOTPRESENT);
+    }
+
+    // Look for xerces1 and xerces2 parsers separately
+    try
+    {
+      final String XERCES2_VERSION_CLASS = "org.apache.xerces.impl.Version";
+
+      Class clazz = ObjectFactory.findProviderClass(
+        XERCES2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      // Found Xerces-J 2.x, grab it's version fields
+      Field f = clazz.getField("fVersion");
+      String parserVersion = (String) f.get(null);
+
+      h.put(VERSION + "xerces2", parserVersion);
+    }
+    catch (Exception e)
+    {
+      h.put(VERSION + "xerces2", CLASS_NOTPRESENT);
+    }
+
+    try
+    {
+      final String CRIMSON_CLASS = "org.apache.crimson.parser.Parser2";
+
+      Class clazz = ObjectFactory.findProviderClass(
+        CRIMSON_CLASS, ObjectFactory.findClassLoader(), true);
+
+      //@todo determine specific crimson version
+      h.put(VERSION + "crimson", CLASS_PRESENT);
+    }
+    catch (Exception e)
+    {
+      h.put(VERSION + "crimson", CLASS_NOTPRESENT);
+    }
+  }
+
+  /**
+   * Report product version information from Ant.
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkAntVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    try
+    {
+      final String ANT_VERSION_CLASS = "org.apache.tools.ant.Main";
+      final String ANT_VERSION_METHOD = "getAntVersion"; // noArgs
+      final Class noArgs[] = new Class[0];
+
+      Class clazz = ObjectFactory.findProviderClass(
+        ANT_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
+
+      Method method = clazz.getMethod(ANT_VERSION_METHOD, noArgs);
+      Object returnValue = method.invoke(null, new Object[0]);
+
+      h.put(VERSION + "ant", (String)returnValue);
+    }
+    catch (Exception e)
+    {
+      h.put(VERSION + "ant", CLASS_NOTPRESENT);
+    }
+  }
+
+  /**
+   * Report version info from DOM interfaces. 
+   *
+   * Currently distinguishes between pre-DOM level 2, the DOM 
+   * level 2 working draft, the DOM level 2 final draft, 
+   * and not found.
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkDOMVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    final String DOM_LEVEL2_CLASS = "org.w3c.dom.Document";
+    final String DOM_LEVEL2_METHOD = "createElementNS";  // String, String
+    final String DOM_LEVEL2WD_CLASS = "org.w3c.dom.Node";
+    final String DOM_LEVEL2WD_METHOD = "supported";  // String, String
+    final String DOM_LEVEL2FD_CLASS = "org.w3c.dom.Node";
+    final String DOM_LEVEL2FD_METHOD = "isSupported";  // String, String
+    final Class twoStringArgs[] = { java.lang.String.class,
+                                    java.lang.String.class };
+
+    try
+    {
+      Class clazz = ObjectFactory.findProviderClass(
+        DOM_LEVEL2_CLASS, ObjectFactory.findClassLoader(), true);
+
+      Method method = clazz.getMethod(DOM_LEVEL2_METHOD, twoStringArgs);
+
+      // If we succeeded, we have loaded interfaces from a 
+      //  level 2 DOM somewhere
+      h.put(VERSION + "DOM", "2.0");
+
+      try
+      {
+        // Check for the working draft version, which is 
+        //  commonly found, but won't work anymore
+        clazz = ObjectFactory.findProviderClass(
+          DOM_LEVEL2WD_CLASS, ObjectFactory.findClassLoader(), true);
+
+        method = clazz.getMethod(DOM_LEVEL2WD_METHOD, twoStringArgs);
+
+        h.put(ERROR + VERSION + "DOM.draftlevel", "2.0wd");
+        h.put(ERROR, ERROR_FOUND);
+      }
+      catch (Exception e2)
+      {
+        try
+        {
+          // Check for the final draft version as well
+          clazz = ObjectFactory.findProviderClass(
+            DOM_LEVEL2FD_CLASS, ObjectFactory.findClassLoader(), true);
+
+          method = clazz.getMethod(DOM_LEVEL2FD_METHOD, twoStringArgs);
+
+          h.put(VERSION + "DOM.draftlevel", "2.0fd");
+        }
+        catch (Exception e3)
+        {
+          h.put(ERROR + VERSION + "DOM.draftlevel", "2.0unknown");
+          h.put(ERROR, ERROR_FOUND);
+        }
+      }
+    }
+    catch (Exception e)
+    {
+      h.put(ERROR + VERSION + "DOM",
+            "ERROR attempting to load DOM level 2 class: " + e.toString());
+      h.put(ERROR, ERROR_FOUND);
+    }
+
+    //@todo load an actual DOM implmementation and query it as well
+    //@todo load an actual DOM implmementation and check if 
+    //  isNamespaceAware() == true, which is needed to parse 
+    //  xsl stylesheet files into a DOM
+  }
+
+  /**
+   * Report version info from SAX interfaces. 
+   *
+   * Currently distinguishes between SAX 2, SAX 2.0beta2, 
+   * SAX1, and not found.
+   *
+   * @param h Hashtable to put information in
+   */
+  protected void checkSAXVersion(Hashtable h)
+  {
+
+    if (null == h)
+      h = new Hashtable();
+
+    final String SAX_VERSION1_CLASS = "org.xml.sax.Parser";
+    final String SAX_VERSION1_METHOD = "parse";  // String
+    final String SAX_VERSION2_CLASS = "org.xml.sax.XMLReader";
+    final String SAX_VERSION2_METHOD = "parse";  // String
+    final String SAX_VERSION2BETA_CLASSNF = "org.xml.sax.helpers.AttributesImpl";
+    final String SAX_VERSION2BETA_METHODNF = "setAttributes";  // Attributes
+    final Class oneStringArg[] = { java.lang.String.class };
+    // Note this introduces a minor compile dependency on SAX...
+    final Class attributesArg[] = { org.xml.sax.Attributes.class };
+
+    try
+    {
+      // This method was only added in the final SAX 2.0 release; 
+      //  see changes.html "Changes from SAX 2.0beta2 to SAX 2.0prerelease"
+      Class clazz = ObjectFactory.findProviderClass(
+        SAX_VERSION2BETA_CLASSNF, ObjectFactory.findClassLoader(), true);
+
+      Method method = clazz.getMethod(SAX_VERSION2BETA_METHODNF, attributesArg);
+
+      // If we succeeded, we have loaded interfaces from a 
+      //  real, final SAX version 2.0 somewhere
+      h.put(VERSION + "SAX", "2.0");
+    }
+    catch (Exception e)
+    {
+      // If we didn't find the SAX 2.0 class, look for a 2.0beta2
+      h.put(ERROR + VERSION + "SAX",
+            "ERROR attempting to load SAX version 2 class: " + e.toString());
+      h.put(ERROR, ERROR_FOUND);
+            
+      try
+      {
+        Class clazz = ObjectFactory.findProviderClass(
+          SAX_VERSION2_CLASS, ObjectFactory.findClassLoader(), true);
+
+        Method method = clazz.getMethod(SAX_VERSION2_METHOD, oneStringArg);
+
+        // If we succeeded, we have loaded interfaces from a 
+        //  SAX version 2.0beta2 or earlier; these might work but 
+        //  you should really have the final SAX 2.0 
+        h.put(VERSION + "SAX-backlevel", "2.0beta2-or-earlier");
+      }
+      catch (Exception e2)
+      {
+        // If we didn't find the SAX 2.0beta2 class, look for a 1.0 one
+        h.put(ERROR + VERSION + "SAX",
+              "ERROR attempting to load SAX version 2 class: " + e.toString());
+        h.put(ERROR, ERROR_FOUND);
+          
+        try
+        {
+          Class clazz = ObjectFactory.findProviderClass(
+            SAX_VERSION1_CLASS, ObjectFactory.findClassLoader(), true);
+
+          Method method = clazz.getMethod(SAX_VERSION1_METHOD, oneStringArg);
+
+          // If we succeeded, we have loaded interfaces from a 
+          //  SAX version 1.0 somewhere; which won't work very 
+          //  well for JAXP 1.1 or beyond!
+          h.put(VERSION + "SAX-backlevel", "1.0");
+        }
+        catch (Exception e3)
+        {
+          // If we didn't find the SAX 2.0 class, look for a 1.0 one
+          // Note that either 1.0 or no SAX are both errors
+          h.put(ERROR + VERSION + "SAX-backlevel",
+                "ERROR attempting to load SAX version 1 class: " + e3.toString());
+            
+        }
+      }
+    }
+  }
+
+  /** 
+   * Manual table of known .jar sizes.  
+   * Only includes shipped versions of certain projects.
+   * key=jarsize, value=jarname ' from ' distro name
+   * Note assumption: two jars cannot have the same size!
+   *
+   * @see #getApparentVersion(String, long)
+   */
+  private static Hashtable jarVersions = new Hashtable();
+
+  /** 
+   * Static initializer for jarVersions table.  
+   * Doing this just once saves time and space.
+   *
+   * @see #getApparentVersion(String, long)
+   */
+  static 
+  {
+    // Note: hackish Hashtable, this could use improvement
+    jarVersions.put(new Long(857192), "xalan.jar from xalan-j_1_1");
+    jarVersions.put(new Long(440237), "xalan.jar from xalan-j_1_2");
+    jarVersions.put(new Long(436094), "xalan.jar from xalan-j_1_2_1");
+    jarVersions.put(new Long(426249), "xalan.jar from xalan-j_1_2_2");
+    jarVersions.put(new Long(702536), "xalan.jar from xalan-j_2_0_0");
+    jarVersions.put(new Long(720930), "xalan.jar from xalan-j_2_0_1");
+    jarVersions.put(new Long(732330), "xalan.jar from xalan-j_2_1_0");
+    jarVersions.put(new Long(872241), "xalan.jar from xalan-j_2_2_D10");
+    jarVersions.put(new Long(882739), "xalan.jar from xalan-j_2_2_D11");
+    jarVersions.put(new Long(923866), "xalan.jar from xalan-j_2_2_0");
+    jarVersions.put(new Long(905872), "xalan.jar from xalan-j_2_3_D1");
+    jarVersions.put(new Long(906122), "xalan.jar from xalan-j_2_3_0");
+    jarVersions.put(new Long(906248), "xalan.jar from xalan-j_2_3_1");
+    jarVersions.put(new Long(983377), "xalan.jar from xalan-j_2_4_D1");    
+    jarVersions.put(new Long(997276), "xalan.jar from xalan-j_2_4_0");
+    jarVersions.put(new Long(1031036), "xalan.jar from xalan-j_2_4_1");    
+    // Stop recording xalan.jar sizes as of Xalan Java 2.5.0    
+
+    jarVersions.put(new Long(596540), "xsltc.jar from xalan-j_2_2_0");
+    jarVersions.put(new Long(590247), "xsltc.jar from xalan-j_2_3_D1");
+    jarVersions.put(new Long(589914), "xsltc.jar from xalan-j_2_3_0");
+    jarVersions.put(new Long(589915), "xsltc.jar from xalan-j_2_3_1");
+    jarVersions.put(new Long(1306667), "xsltc.jar from xalan-j_2_4_D1");     
+    jarVersions.put(new Long(1328227), "xsltc.jar from xalan-j_2_4_0");
+    jarVersions.put(new Long(1344009), "xsltc.jar from xalan-j_2_4_1");
+    jarVersions.put(new Long(1348361), "xsltc.jar from xalan-j_2_5_D1");    
+    // Stop recording xsltc.jar sizes as of Xalan Java 2.5.0
+
+    jarVersions.put(new Long(1268634), "xsltc.jar-bundled from xalan-j_2_3_0");
+
+    jarVersions.put(new Long(100196), "xml-apis.jar from xalan-j_2_2_0 or xalan-j_2_3_D1");
+    jarVersions.put(new Long(108484), "xml-apis.jar from xalan-j_2_3_0, or xalan-j_2_3_1 from xml-commons-1.0.b2");
+    jarVersions.put(new Long(109049), "xml-apis.jar from xalan-j_2_4_0 from xml-commons RIVERCOURT1 branch");
+    jarVersions.put(new Long(113749), "xml-apis.jar from xalan-j_2_4_1 from factoryfinder-build of xml-commons RIVERCOURT1");
+    jarVersions.put(new Long(124704), "xml-apis.jar from tck-jaxp-1_2_0 branch of xml-commons");
+    jarVersions.put(new Long(124724), "xml-apis.jar from tck-jaxp-1_2_0 branch of xml-commons, tag: xml-commons-external_1_2_01");
+    jarVersions.put(new Long(194205), "xml-apis.jar from head branch of xml-commons, tag: xml-commons-external_1_3_02");
+
+    // If the below were more common I would update it to report 
+    //  errors better; but this is so old hardly anyone has it
+    jarVersions.put(new Long(424490), "xalan.jar from Xerces Tools releases - ERROR:DO NOT USE!");
+
+    jarVersions.put(new Long(1591855), "xerces.jar from xalan-j_1_1 from xerces-1...");
+    jarVersions.put(new Long(1498679), "xerces.jar from xalan-j_1_2 from xerces-1_2_0.bin");
+    jarVersions.put(new Long(1484896), "xerces.jar from xalan-j_1_2_1 from xerces-1_2_1.bin");
+    jarVersions.put(new Long(804460),  "xerces.jar from xalan-j_1_2_2 from xerces-1_2_2.bin");
+    jarVersions.put(new Long(1499244), "xerces.jar from xalan-j_2_0_0 from xerces-1_2_3.bin");
+    jarVersions.put(new Long(1605266), "xerces.jar from xalan-j_2_0_1 from xerces-1_3_0.bin");
+    jarVersions.put(new Long(904030), "xerces.jar from xalan-j_2_1_0 from xerces-1_4.bin");
+    jarVersions.put(new Long(904030), "xerces.jar from xerces-1_4_0.bin");
+    jarVersions.put(new Long(1802885), "xerces.jar from xerces-1_4_2.bin");
+    jarVersions.put(new Long(1734594), "xerces.jar from Xerces-J-bin.2.0.0.beta3");
+    jarVersions.put(new Long(1808883), "xerces.jar from xalan-j_2_2_D10,D11,D12 or xerces-1_4_3.bin");
+    jarVersions.put(new Long(1812019), "xerces.jar from xalan-j_2_2_0");
+    jarVersions.put(new Long(1720292), "xercesImpl.jar from xalan-j_2_3_D1");
+    jarVersions.put(new Long(1730053), "xercesImpl.jar from xalan-j_2_3_0 or xalan-j_2_3_1 from xerces-2_0_0");
+    jarVersions.put(new Long(1728861), "xercesImpl.jar from xalan-j_2_4_D1 from xerces-2_0_1");    
+    jarVersions.put(new Long(972027), "xercesImpl.jar from xalan-j_2_4_0 from xerces-2_1");
+    jarVersions.put(new Long(831587), "xercesImpl.jar from xalan-j_2_4_1 from xerces-2_2"); 
+    jarVersions.put(new Long(891817), "xercesImpl.jar from xalan-j_2_5_D1 from xerces-2_3");  
+    jarVersions.put(new Long(895924), "xercesImpl.jar from xerces-2_4");
+    jarVersions.put(new Long(1010806), "xercesImpl.jar from Xerces-J-bin.2.6.2"); 
+    jarVersions.put(new Long(1203860), "xercesImpl.jar from Xerces-J-bin.2.7.1");                           
+
+    jarVersions.put(new Long(37485), "xalanj1compat.jar from xalan-j_2_0_0");
+    jarVersions.put(new Long(38100), "xalanj1compat.jar from xalan-j_2_0_1");
+
+    jarVersions.put(new Long(18779), "xalanservlet.jar from xalan-j_2_0_0");
+    jarVersions.put(new Long(21453), "xalanservlet.jar from xalan-j_2_0_1");
+    jarVersions.put(new Long(24826), "xalanservlet.jar from xalan-j_2_3_1 or xalan-j_2_4_1");    
+    jarVersions.put(new Long(24831), "xalanservlet.jar from xalan-j_2_4_1");
+    // Stop recording xalanservlet.jar sizes as of Xalan Java 2.5.0; now a .war file
+    
+    // For those who've downloaded JAXP from sun
+    jarVersions.put(new Long(5618), "jaxp.jar from jaxp1.0.1");
+    jarVersions.put(new Long(136133), "parser.jar from jaxp1.0.1");
+    jarVersions.put(new Long(28404), "jaxp.jar from jaxp-1.1");
+    jarVersions.put(new Long(187162), "crimson.jar from jaxp-1.1");
+    jarVersions.put(new Long(801714), "xalan.jar from jaxp-1.1");
+    jarVersions.put(new Long(196399), "crimson.jar from crimson-1.1.1");
+    jarVersions.put(new Long(33323), "jaxp.jar from crimson-1.1.1 or jakarta-ant-1.4.1b1");
+    jarVersions.put(new Long(152717), "crimson.jar from crimson-1.1.2beta2");
+    jarVersions.put(new Long(88143), "xml-apis.jar from crimson-1.1.2beta2");
+    jarVersions.put(new Long(206384), "crimson.jar from crimson-1.1.3 or jakarta-ant-1.4.1b1");
+
+    // jakarta-ant: since many people use ant these days
+    jarVersions.put(new Long(136198), "parser.jar from jakarta-ant-1.3 or 1.2");
+    jarVersions.put(new Long(5537), "jaxp.jar from jakarta-ant-1.3 or 1.2");
+  }
+
+  /** Simple PrintWriter we send output to; defaults to System.out.  */
+  protected PrintWriter outWriter = new PrintWriter(System.out, true);
+
+  /**
+   * Bottleneck output: calls outWriter.println(s).  
+   * @param s String to print
+   */
+  protected void logMsg(String s)
+  {
+    outWriter.println(s);
+  }
+}
diff --git a/src/main/java/org/apache/xalan/xslt/ObjectFactory.java b/src/main/java/org/apache/xalan/xslt/ObjectFactory.java
new file mode 100755
index 0000000..1029b87
--- /dev/null
+++ b/src/main/java/org/apache/xalan/xslt/ObjectFactory.java
@@ -0,0 +1,661 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectFactory.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id: ObjectFactory.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services/";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                FileInputStream fis = null;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        fis = ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                    }
+	        } catch (Exception x) {
+	            fXalanProperties = null;
+	            fLastModified = -1;
+                    // assert(x instanceof FileNotFoundException
+	            //        || x instanceof SecurityException)
+	            // In both cases, ignore and continue w/ next location
+	        }
+                finally {
+                    // try to close the input stream if one was opened.
+                    if (fis != null) {
+                        try {
+                            fis.close();
+                        }
+                        // Ignore the exception.
+                        catch (IOException exc) {}
+                    }
+                }	            
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            FileInputStream fis = null;
+            try {
+                fis = ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+            finally {
+                // try to close the input stream if one was opened.
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    }
+                    // Ignore the exception.
+                    catch (IOException exc) {}
+                }
+            }               
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+        finally {
+            try {
+                // try to close the reader.
+                rd.close();
+            }
+            // Ignore the exception.
+            catch (IOException exc) {}
+        }          
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = 2276082712114762609L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xalan/xslt/SecuritySupport.java b/src/main/java/org/apache/xalan/xslt/SecuritySupport.java
new file mode 100755
index 0000000..49e207a
--- /dev/null
+++ b/src/main/java/org/apache/xalan/xslt/SecuritySupport.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xalan/xslt/SecuritySupport12.java b/src/main/java/org/apache/xalan/xslt/SecuritySupport12.java
new file mode 100755
index 0000000..e751f8b
--- /dev/null
+++ b/src/main/java/org/apache/xalan/xslt/SecuritySupport12.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport12.java 468646 2006-10-28 06:57:58Z minchau $
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xalan/xslt/package.html b/src/main/java/org/apache/xalan/xslt/package.html
new file mode 100644
index 0000000..61018f4
--- /dev/null
+++ b/src/main/java/org/apache/xalan/xslt/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468646 2006-10-28 06:57:58Z minchau $ -->
+<html>
+  <title>Xalan command-line interface.</title>
+  <body>
+    <p>Implementation of Xalan command-line interface.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xml/dtm/Axis.java b/src/main/java/org/apache/xml/dtm/Axis.java
new file mode 100644
index 0000000..915a358
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/Axis.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Axis.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * Specifies values related to XPath Axes.
+ * <p>The ancestor, descendant, following, preceding and self axes partition a
+ * document (ignoring attribute and namespace nodes): they do not overlap
+ * and together they contain all the nodes in the document.</p>
+ *
+ */
+public final class Axis
+{
+
+  /**
+   * The ancestor axis contains the ancestors of the context node;
+   *  the ancestors of the context node consist of the parent of context
+   *  node and the parent's parent and so on; thus, the ancestor axis will
+   *  always include the root node, unless the context node is the root node.
+   */
+  public static final int ANCESTOR = 0;
+
+  /**
+   * the ancestor-or-self axis contains the context node and the ancestors of
+   *  the context node; thus, the ancestor axis will always include the
+   *  root node.
+   */
+  public static final int ANCESTORORSELF = 1;
+
+  /**
+   * the attribute axis contains the attributes of the context node; the axis
+   *  will be empty unless the context node is an element.
+   */
+  public static final int ATTRIBUTE = 2;
+
+  /** The child axis contains the children of the context node. */
+  public static final int CHILD = 3;
+
+  /**
+   * The descendant axis contains the descendants of the context node;
+   *  a descendant is a child or a child of a child and so on; thus the
+   *  descendant axis never contains attribute or namespace nodes.
+   */
+  public static final int DESCENDANT = 4;
+
+  /**
+   * The descendant-or-self axis contains the context node and the
+   *  descendants of the context node.
+   */
+  public static final int DESCENDANTORSELF = 5;
+
+  /**
+   * the following axis contains all nodes in the same document as the
+   *  context node that are after the context node in document order, excluding
+   *  any descendants and excluding attribute nodes and namespace nodes.
+   */
+  public static final int FOLLOWING = 6;
+
+  /**
+   * The following-sibling axis contains all the following siblings of the
+   *  context node; if the context node is an attribute node or namespace node,
+   *  the following-sibling axis is empty.
+   */
+  public static final int FOLLOWINGSIBLING = 7;
+
+  /**
+   * The namespace axis contains the namespace nodes of the context node; the
+   *  axis will be empty unless the context node is an element.
+   */
+  public static final int NAMESPACEDECLS = 8;
+
+  /**
+   * The namespace axis contains the namespace nodes of the context node; the
+   *  axis will be empty unless the context node is an element.
+   */
+  public static final int NAMESPACE = 9;
+
+  /**
+   * The parent axis contains the parent of the context node,
+   *  if there is one.
+   */
+  public static final int PARENT = 10;
+
+  /**
+   * The preceding axis contains all nodes in the same document as the context
+   *  node that are before the context node in document order, excluding any
+   *  ancestors and excluding attribute nodes and namespace nodes
+   */
+  public static final int PRECEDING = 11;
+
+  /**
+   * The preceding-sibling axis contains all the preceding siblings of the
+   *  context node; if the context node is an attribute node or namespace node,
+   *  the preceding-sibling axis is empty.
+   */
+  public static final int PRECEDINGSIBLING = 12;
+
+  /** The self axis contains just the context node itself. */
+  public static final int SELF = 13;
+
+  /**
+   * A non-xpath axis, traversing the subtree including the subtree
+   *  root, descendants, attributes, and namespace node decls.
+   */
+  public static final int ALLFROMNODE = 14;
+
+  /**
+   * A non-xpath axis, traversing the the preceding and the ancestor nodes, 
+   * needed for inverseing select patterns to match patterns.
+   */
+  public static final int PRECEDINGANDANCESTOR = 15;
+  
+  // ===========================================
+  // All axis past this are absolute.
+  
+  /**
+   * A non-xpath axis, returns all nodes in the tree from and including the 
+   * root.
+   */
+  public static final int ALL = 16;
+
+  /**
+   * A non-xpath axis, returns all nodes that aren't namespaces or attributes, 
+   * from and including the root.
+   */
+  public static final int DESCENDANTSFROMROOT = 17;
+
+  /**
+   * A non-xpath axis, returns all nodes that aren't namespaces or attributes, 
+   * from and including the root.
+   */
+  public static final int DESCENDANTSORSELFFROMROOT = 18;
+
+  /**
+   * A non-xpath axis, returns root only.
+   */
+  public static final int ROOT = 19;
+
+  /**
+   * A non-xpath axis, for functions.
+   */
+  public static final int FILTEREDLIST = 20;
+
+  /**
+   * A table to identify whether an axis is a reverse axis;
+   */
+  private static final boolean[] isReverse = {
+      true,  // ancestor
+      true,  // ancestor-or-self
+      false, // attribute
+      false, // child
+      false, // descendant
+      false, // descendant-or-self
+      false, // following
+      false, // following-sibling
+      false, // namespace
+      false, // namespace-declarations
+      false, // parent (one node, has no order)
+      true,  // preceding
+      true,  // preceding-sibling
+      false  // self (one node, has no order)
+  };
+
+    /** The names of the axes for diagnostic purposes. */
+    private static final String[] names =
+    {
+      "ancestor",  // 0
+      "ancestor-or-self",  // 1
+      "attribute",  // 2
+      "child",  // 3
+      "descendant",  // 4
+      "descendant-or-self",  // 5
+      "following",  // 6
+      "following-sibling",  // 7
+      "namespace-decls",  // 8
+      "namespace",  // 9
+      "parent",  // 10
+      "preceding",  // 11
+      "preceding-sibling",  // 12
+      "self",  // 13
+      "all-from-node",  // 14
+      "preceding-and-ancestor",  // 15
+      "all",  // 16
+      "descendants-from-root",  // 17
+      "descendants-or-self-from-root",  // 18
+      "root",  // 19
+      "filtered-list"  // 20
+    };
+
+  public static boolean isReverse(int axis){
+      return isReverse[axis];
+  }
+    
+    public static String getNames(int index){
+    	return names[index];    
+    }
+    
+    public static int getNamesLength(){
+    	return names.length;
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTM.java b/src/main/java/org/apache/xml/dtm/DTM.java
new file mode 100644
index 0000000..0722ff7
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTM.java
@@ -0,0 +1,967 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTM.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xml.utils.XMLString;
+
+/**
+ * <code>DTM</code> is an XML document model expressed as a table
+ * rather than an object tree. It attempts to provide an interface to
+ * a parse tree that has very little object creation. (DTM
+ * implementations may also support incremental construction of the
+ * model, but that's hidden from the DTM API.)
+ *
+ * <p>Nodes in the DTM are identified by integer "handles".  A handle must
+ * be unique within a process, and carries both node identification and
+ * document identification.  It must be possible to compare two handles
+ * (and thus their nodes) for identity with "==".</p>
+ *
+ * <p>Namespace URLs, local-names, and expanded-names can all be
+ * represented by and tested as integer ID values.  An expanded name
+ * represents (and may or may not directly contain) a combination of
+ * the URL ID, and the local-name ID.  Note that the namespace URL id
+ * can be 0, which should have the meaning that the namespace is null.
+ * For consistancy, zero should not be used for a local-name index. </p>
+ *
+ * <p>Text content of a node is represented by an index and length,
+ * permitting efficient storage such as a shared FastStringBuffer.</p>
+ *
+ * <p>The model of the tree, as well as the general navigation model,
+ * is that of XPath 1.0, for the moment.  The model will eventually be
+ * adapted to match the XPath 2.0 data model, XML Schema, and
+ * InfoSet.</p>
+ *
+ * <p>DTM does _not_ directly support the W3C's Document Object
+ * Model. However, it attempts to come close enough that an
+ * implementation of DTM can be created that wraps a DOM and vice
+ * versa.</p>
+ *
+ * <p><strong>Please Note:</strong> The DTM API is still
+ * <strong>Subject To Change.</strong> This wouldn't affect most
+ * users, but might require updating some extensions.</p>
+ *
+ * <p> The largest change being contemplated is a reconsideration of
+ * the Node Handle representation.  We are still not entirely sure
+ * that an integer packed with two numeric subfields is really the
+ * best solution. It has been suggested that we move up to a Long, to
+ * permit more nodes per document without having to reduce the number
+ * of slots in the DTMManager. There's even been a proposal that we
+ * replace these integers with "cursor" objects containing the
+ * internal node id and a pointer to the actual DTM object; this might
+ * reduce the need to continuously consult the DTMManager to retrieve
+ * the latter, and might provide a useful "hook" back into normal Java
+ * heap management.  But changing this datatype would have huge impact
+ * on Xalan's internals -- especially given Java's lack of C-style
+ * typedefs -- so we won't cut over unless we're convinced the new
+ * solution really would be an improvement!</p>
+ * */
+public interface DTM
+{
+
+  /**
+   * Null node handles are represented by this value.
+   */
+  public static final int NULL = -1;
+
+  // These nodeType mnemonics and values are deliberately the same as those
+  // used by the DOM, for convenient mapping
+  //
+  // %REVIEW% Should we actually define these as initialized to,
+  // eg. org.w3c.dom.Document.ELEMENT_NODE?
+
+  /**
+   * The node is a <code>Root</code>.
+   */
+  public static final short ROOT_NODE = 0;
+  
+  /**
+   * The node is an <code>Element</code>.
+   */
+  public static final short ELEMENT_NODE = 1;
+
+  /**
+   * The node is an <code>Attr</code>.
+   */
+  public static final short ATTRIBUTE_NODE = 2;
+
+  /**
+   * The node is a <code>Text</code> node.
+   */
+  public static final short TEXT_NODE = 3;
+
+  /**
+   * The node is a <code>CDATASection</code>.
+   */
+  public static final short CDATA_SECTION_NODE = 4;
+
+  /**
+   * The node is an <code>EntityReference</code>.
+   */
+  public static final short ENTITY_REFERENCE_NODE = 5;
+
+  /**
+   * The node is an <code>Entity</code>.
+   */
+  public static final short ENTITY_NODE = 6;
+
+  /**
+   * The node is a <code>ProcessingInstruction</code>.
+   */
+  public static final short PROCESSING_INSTRUCTION_NODE = 7;
+
+  /**
+   * The node is a <code>Comment</code>.
+   */
+  public static final short COMMENT_NODE = 8;
+
+  /**
+   * The node is a <code>Document</code>.
+   */
+  public static final short DOCUMENT_NODE = 9;
+
+  /**
+   * The node is a <code>DocumentType</code>.
+   */
+  public static final short DOCUMENT_TYPE_NODE = 10;
+
+  /**
+   * The node is a <code>DocumentFragment</code>.
+   */
+  public static final short DOCUMENT_FRAGMENT_NODE = 11;
+
+  /**
+   * The node is a <code>Notation</code>.
+   */
+  public static final short NOTATION_NODE = 12;
+
+  /**
+   * The node is a <code>namespace node</code>. Note that this is not
+   * currently a node type defined by the DOM API.
+   */
+  public static final short NAMESPACE_NODE = 13;
+  
+  /**
+   * The number of valid nodetypes.
+   */
+  public static final short  NTYPES = 14;
+
+  // ========= DTM Implementation Control Functions. ==============
+  // %TBD% RETIRED -- do via setFeature if needed. Remove from impls.
+  // public void setParseBlockSize(int blockSizeSuggestion);
+
+  /**
+   * Set an implementation dependent feature.
+   * <p>
+   * %REVIEW% Do we really expect to set features on DTMs?
+   *
+   * @param featureId A feature URL.
+   * @param state true if this feature should be on, false otherwise.
+   */
+  public void setFeature(String featureId, boolean state);
+
+  /**
+   * Set a run time property for this DTM instance.
+   *
+   * @param property a <code>String</code> value
+   * @param value an <code>Object</code> value
+   */
+  public void setProperty(String property, Object value);
+
+  // ========= Document Navigation Functions =========
+
+  /**
+   * This returns a stateless "traverser", that can navigate over an
+   * XPath axis, though not in document order.
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+   */
+  public DTMAxisTraverser getAxisTraverser(final int axis);
+
+  /**
+   * This is a shortcut to the iterators that implement
+   * XPath axes.
+   * Returns a bare-bones iterator that must be initialized
+   * with a start node (using iterator.setStartNode()).
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+   */
+  public DTMAxisIterator getAxisIterator(final int axis);
+
+  /**
+   * Get an iterator that can navigate over an XPath Axis, predicated by
+   * the extended type ID.
+   *
+   * @param axis
+   * @param type An extended type ID.
+   *
+   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+   */
+  public DTMAxisIterator getTypedAxisIterator(final int axis, final int type);
+
+  /**
+   * Given a node handle, test if it has child nodes.
+   * <p> %REVIEW% This is obviously useful at the DOM layer, where it
+   * would permit testing this without having to create a proxy
+   * node. It's less useful in the DTM API, where
+   * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and
+   * almost as self-evident. But it's a convenience, and eases porting
+   * of DOM code to DTM.  </p>
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int true if the given node has child nodes.
+   */
+  public boolean hasChildNodes(int nodeHandle);
+
+  /**
+   * Given a node handle, get the handle of the node's first child.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int DTM node-number of first child,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getFirstChild(int nodeHandle);
+
+  /**
+   * Given a node handle, get the handle of the node's last child.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int Node-number of last child,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getLastChild(int nodeHandle);
+
+  /**
+   * Retrieves an attribute node by local name and namespace URI
+   *
+   * %TBD% Note that we currently have no way to support
+   * the DOM's old getAttribute() call, which accesses only the qname.
+   *
+   * @param elementHandle Handle of the node upon which to look up this attribute.
+   * @param namespaceURI The namespace URI of the attribute to
+   *   retrieve, or null.
+   * @param name The local name of the attribute to
+   *   retrieve.
+   * @return The attribute node handle with the specified name (
+   *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
+   *   attribute.
+   */
+  public int getAttributeNode(int elementHandle, String namespaceURI,
+                              String name);
+
+  /**
+   * Given a node handle, get the index of the node's first attribute.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return Handle of first attribute, or DTM.NULL to indicate none exists.
+   */
+  public int getFirstAttribute(int nodeHandle);
+
+  /**
+   * Given a node handle, get the index of the node's first namespace node.
+   *
+   * @param nodeHandle handle to node, which should probably be an element
+   *                   node, but need not be.
+   *
+   * @param inScope true if all namespaces in scope should be
+   *                   returned, false if only the node's own
+   *                   namespace declarations should be returned.
+   * @return handle of first namespace,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getFirstNamespaceNode(int nodeHandle, boolean inScope);
+
+  /**
+   * Given a node handle, advance to its next sibling.
+   * @param nodeHandle int Handle of the node.
+   * @return int Node-number of next sibling,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getNextSibling(int nodeHandle);
+
+  /**
+   * Given a node handle, find its preceeding sibling.
+   * WARNING: DTM implementations may be asymmetric; in some,
+   * this operation has been resolved by search, and is relatively expensive.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node-number of the previous sib,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getPreviousSibling(int nodeHandle);
+
+  /**
+   * Given a node handle, advance to the next attribute. If an
+   * element, we advance to its first attribute; if an attr, we advance to
+   * the next attr of the same element.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int DTM node-number of the resolved attr,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getNextAttribute(int nodeHandle);
+
+  /**
+   * Given a namespace handle, advance to the next namespace in the same scope
+   * (local or local-plus-inherited, as selected by getFirstNamespaceNode)
+   *
+   * @param baseHandle handle to original node from where the first child
+   * was relative to (needed to return nodes in document order).
+   * @param namespaceHandle handle to node which must be of type
+   * NAMESPACE_NODE.
+   * NEEDSDOC @param inScope
+   * @return handle of next namespace,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getNextNamespaceNode(int baseHandle, int namespaceHandle,
+                                  boolean inScope);
+
+  /**
+   * Given a node handle, find its parent node.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of parent,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getParent(int nodeHandle);
+
+  /**
+   * Given a DTM which contains only a single document, 
+   * find the Node Handle of the  Document node. Note 
+   * that if the DTM is configured so it can contain multiple
+   * documents, this call will return the Document currently
+   * under construction -- but may return null if it's between
+   * documents. Generally, you should use getOwnerDocument(nodeHandle)
+   * or getDocumentRoot(nodeHandle) instead.
+   *
+   * @return int Node handle of document, or DTM.NULL if a shared DTM
+   * can not tell us which Document is currently active.
+   */
+  public int getDocument();
+
+  /**
+   * Given a node handle, find the owning document node. This version mimics
+   * the behavior of the DOM call by the same name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of owning document, or DTM.NULL if the node was
+   * a Document.
+   * @see #getDocumentRoot(int nodeHandle)
+   */
+  public int getOwnerDocument(int nodeHandle);
+
+  /**
+   * Given a node handle, find the owning document node.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of owning document, or the node itself if it was
+   * a Document. (Note difference from DOM, where getOwnerDocument returns
+   * null for the Document node.)
+   * @see #getOwnerDocument(int nodeHandle)
+   */
+  public int getDocumentRoot(int nodeHandle);
+
+  /**
+   * Get the string-value of a node as a String object
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public XMLString getStringValue(int nodeHandle);
+
+  /**
+   * Get number of character array chunks in
+   * the string-value of a node.
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   * Note that a single text node may have multiple text chunks.
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return number of character array chunks in
+   *         the string-value of a node.
+   */
+  public int getStringValueChunkCount(int nodeHandle);
+
+  /**
+   * Get a character array chunk in the string-value of a node.
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   * Note that a single text node may have multiple text chunks.
+   *
+   * @param nodeHandle The node ID.
+   * @param chunkIndex Which chunk to get.
+   * @param startAndLen  A two-integer array which, upon return, WILL
+   * BE FILLED with values representing the chunk's start position
+   * within the returned character buffer and the length of the chunk.
+   * @return The character array buffer within which the chunk occurs,
+   * setting startAndLen's contents as a side-effect.
+   */
+  public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
+                                    int[] startAndLen);
+
+  /**
+   * Given a node handle, return an ID that represents the node's expanded name.
+   *
+   * @param nodeHandle The handle to the node in question.
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(int nodeHandle);
+
+  /**
+   * Given an expanded name, return an ID.  If the expanded-name does not
+   * exist in the internal tables, the entry will be created, and the ID will
+   * be returned.  Any additional nodes that are created that have this
+   * expanded name will use this ID.
+   *
+   * NEEDSDOC @param namespace
+   * NEEDSDOC @param localName
+   * NEEDSDOC @param type
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(String namespace, String localName, int type);
+
+  /**
+   * Given an expanded-name ID, return the local name part.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return String Local name of this node.
+   */
+  public String getLocalNameFromExpandedNameID(int ExpandedNameID);
+
+  /**
+   * Given an expanded-name ID, return the namespace URI part.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespaceFromExpandedNameID(int ExpandedNameID);
+
+  /**
+   * Given a node handle, return its DOM-style node name. This will
+   * include names such as #text or #document.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   * %REVIEW% Document when empty string is possible...
+   */
+  public String getNodeName(int nodeHandle);
+
+  /**
+   * Given a node handle, return the XPath node name.  This should be
+   * the name as described by the XPath data model, NOT the DOM-style
+   * name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node.
+   */
+  public String getNodeNameX(int nodeHandle);
+
+  /**
+   * Given a node handle, return its DOM-style localname.
+   * (As defined in Namespaces, this is the portion of the name after the
+   * prefix, if present, or the whole node name if no prefix exists)
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Local name of this node.
+   */
+  public String getLocalName(int nodeHandle);
+
+  /**
+   * Given a namespace handle, return the prefix that the namespace decl is
+   * mapping.
+   * Given a node handle, return the prefix used to map to the namespace.
+   * (As defined in Namespaces, this is the portion of the name before any
+   * colon character).
+   *
+   * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String prefix of this node's name, or "" if no explicit
+   * namespace prefix was given.
+   */
+  public String getPrefix(int nodeHandle);
+
+  /**
+   * Given a node handle, return its DOM-style namespace URI
+   * (As defined in Namespaces, this is the declared URI which this node's
+   * prefix -- or default in lieu thereof -- was mapped to.)
+   * @param nodeHandle the id of the node.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespaceURI(int nodeHandle);
+
+  /**
+   * Given a node handle, return its node value. This is mostly
+   * as defined by the DOM, but may ignore some conveniences.
+   * <p>
+   * @param nodeHandle The node id.
+   * @return String Value of this node, or null if not
+   * meaningful for this node type.
+   */
+  public String getNodeValue(int nodeHandle);
+
+  /**
+   * Given a node handle, return its DOM-style node type.
+   *
+   * <p>%REVIEW% Generally, returning short is false economy. Return int?</p>
+   *
+   * @param nodeHandle The node id.
+   * @return int Node type, as per the DOM's Node._NODE constants.
+   */
+  public short getNodeType(int nodeHandle);
+
+  /**
+   * Get the depth level of this node in the tree (equals 1 for
+   * a parentless node).
+   *
+   * @param nodeHandle The node id.
+   * @return the number of ancestors, plus one
+   * @xsl.usage internal
+   */
+  public short getLevel(int nodeHandle);
+
+  // ============== Document query functions ==============
+
+  /**
+   * Tests whether DTM DOM implementation implements a specific feature and
+   * that feature is supported by this node.
+   * @param feature The name of the feature to test.
+   * @param version This is the version number of the feature to test.
+   *   If the version is not
+   *   specified, supporting any version of the feature will cause the
+   *   method to return <code>true</code>.
+   * @return Returns <code>true</code> if the specified feature is
+   *   supported on this node, <code>false</code> otherwise.
+   */
+  public boolean isSupported(String feature, String version);
+
+  /**
+   * Return the base URI of the document entity. If it is not known
+   * (because the document was parsed from a socket connection or from
+   * standard input, for example), the value of this property is unknown.
+   *
+   * @return the document base URI String object or null if unknown.
+   */
+  public String getDocumentBaseURI();
+
+  /**
+   * Set the base URI of the document entity.
+   *
+   * @param baseURI the document base URI String object or null if unknown.
+   */
+  public void setDocumentBaseURI(String baseURI);
+
+  /**
+   * Return the system identifier of the document entity. If
+   * it is not known, the value of this property is null.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the system identifier String object or null if unknown.
+   */
+  public String getDocumentSystemIdentifier(int nodeHandle);
+
+  /**
+   * Return the name of the character encoding scheme
+   *        in which the document entity is expressed.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the document encoding String object.
+   */
+  public String getDocumentEncoding(int nodeHandle);
+
+  /**
+   * Return an indication of the standalone status of the document,
+   *        either "yes" or "no". This property is derived from the optional
+   *        standalone document declaration in the XML declaration at the
+   *        beginning of the document entity, and has no value if there is no
+   *        standalone document declaration.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the document standalone String object, either "yes", "no", or null.
+   */
+  public String getDocumentStandalone(int nodeHandle);
+
+  /**
+   * Return a string representing the XML version of the document. This
+   * property is derived from the XML declaration optionally present at the
+   * beginning of the document entity, and has no value if there is no XML
+   * declaration.
+   *
+   * @param documentHandle the document handle
+   * @return the document version String object
+   */
+  public String getDocumentVersion(int documentHandle);
+
+  /**
+   * Return an indication of
+   * whether the processor has read the complete DTD. Its value is a
+   * boolean. If it is false, then certain properties (indicated in their
+   * descriptions below) may be unknown. If it is true, those properties
+   * are never unknown.
+   *
+   * @return <code>true</code> if all declarations were processed;
+   *         <code>false</code> otherwise.
+   */
+  public boolean getDocumentAllDeclarationsProcessed();
+
+  /**
+   *   A document type declaration information item has the following properties:
+   *
+   *     1. [system identifier] The system identifier of the external subset, if
+   *        it exists. Otherwise this property has no value.
+   *
+   * @return the system identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationSystemIdentifier();
+
+  /**
+   * Return the public identifier of the external subset,
+   * normalized as described in 4.2.2 External Entities [XML]. If there is
+   * no external subset or if it has no public identifier, this property
+   * has no value.
+   *
+   * @return the public identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationPublicIdentifier();
+
+  /**
+   * Returns the <code>Element</code> whose <code>ID</code> is given by
+   * <code>elementId</code>. If no such element exists, returns
+   * <code>DTM.NULL</code>. Behavior is not defined if more than one element
+   * has this <code>ID</code>. Attributes (including those
+   * with the name "ID") are not of type ID unless so defined by DTD/Schema
+   * information available to the DTM implementation.
+   * Implementations that do not know whether attributes are of type ID or
+   * not are expected to return <code>DTM.NULL</code>.
+   *
+   * <p>%REVIEW% Presumably IDs are still scoped to a single document,
+   * and this operation searches only within a single document, right?
+   * Wouldn't want collisions between DTMs in the same process.</p>
+   *
+   * @param elementId The unique <code>id</code> value for an element.
+   * @return The handle of the matching element.
+   */
+  public int getElementById(String elementId);
+
+  /**
+   * The getUnparsedEntityURI function returns the URI of the unparsed
+   * entity with the specified name in the same document as the context
+   * node (see [3.3 Unparsed Entities]). It returns the empty string if
+   * there is no such entity.
+   * <p>
+   * XML processors may choose to use the System Identifier (if one
+   * is provided) to resolve the entity, rather than the URI in the
+   * Public Identifier. The details are dependent on the processor, and
+   * we would have to support some form of plug-in resolver to handle
+   * this properly. Currently, we simply return the System Identifier if
+   * present, and hope that it a usable URI or that our caller can
+   * map it to one.
+   * %REVIEW% Resolve Public Identifiers... or consider changing function name.
+   * <p>
+   * If we find a relative URI
+   * reference, XML expects it to be resolved in terms of the base URI
+   * of the document. The DOM doesn't do that for us, and it isn't
+   * entirely clear whether that should be done here; currently that's
+   * pushed up to a higher level of our application. (Note that DOM Level
+   * 1 didn't store the document's base URI.)
+   * %REVIEW% Consider resolving Relative URIs.
+   * <p>
+   * (The DOM's statement that "An XML processor may choose to
+   * completely expand entities before the structure model is passed
+   * to the DOM" refers only to parsed entities, not unparsed, and hence
+   * doesn't affect this function.)
+   *
+   * @param name A string containing the Entity Name of the unparsed
+   * entity.
+   *
+   * @return String containing the URI of the Unparsed Entity, or an
+   * empty string if no such entity exists.
+   */
+  public String getUnparsedEntityURI(String name);
+
+  // ============== Boolean methods ================
+
+  /**
+   * Return true if the xsl:strip-space or xsl:preserve-space was processed
+   * during construction of the document contained in this DTM.
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public boolean supportsPreStripping();
+
+  /**
+   * Figure out whether nodeHandle2 should be considered as being later
+   * in the document than nodeHandle1, in Document Order as defined
+   * by the XPath model. This may not agree with the ordering defined
+   * by other XML applications.
+   * <p>
+   * There are some cases where ordering isn't defined, and neither are
+   * the results of this function -- though we'll generally return true.
+   * <p>
+   * %REVIEW% Make sure this does the right thing with attribute nodes!!!
+   * <p>
+   * %REVIEW% Consider renaming for clarity. Perhaps isDocumentOrder(a,b)?
+   *
+   * @param firstNodeHandle DOM Node to perform position comparison on.
+   * @param secondNodeHandle DOM Node to perform position comparison on.
+   *
+   * @return false if secondNode comes before firstNode, otherwise return true.
+   * You can think of this as
+   * <code>(firstNode.documentOrderPosition &lt;= secondNode.documentOrderPosition)</code>.
+   */
+  public boolean isNodeAfter(int firstNodeHandle, int secondNodeHandle);
+
+  /**
+   * 2. [element content whitespace] A boolean indicating whether a
+   * text node represents white space appearing within element content
+   * (see [XML], 2.10 "White Space Handling").  Note that validating
+   * XML processors are required by XML 1.0 to provide this
+   * information... but that DOM Level 2 did not support it, since it
+   * depends on knowledge of the DTD which DOM2 could not guarantee
+   * would be available.
+   * <p>
+   * If there is no declaration for the containing element, an XML
+   * processor must assume that the whitespace could be meaningful and
+   * return false. If no declaration has been read, but the [all
+   * declarations processed] property of the document information item
+   * is false (so there may be an unread declaration), then the value
+   * of this property is indeterminate for white space characters and
+   * should probably be reported as false. It is always false for text
+   * nodes that contain anything other than (or in addition to) white
+   * space.
+   * <p>
+   * Note too that it always returns false for non-Text nodes.
+   * <p>
+   * %REVIEW% Joe wants to rename this isWhitespaceInElementContent() for clarity
+   *
+   * @param nodeHandle the node ID.
+   * @return <code>true</code> if the node definitely represents whitespace in
+   * element content; <code>false</code> otherwise.
+   */
+  public boolean isCharacterElementContentWhitespace(int nodeHandle);
+
+  /**
+   *    10. [all declarations processed] This property is not strictly speaking
+   *        part of the infoset of the document. Rather it is an indication of
+   *        whether the processor has read the complete DTD. Its value is a
+   *        boolean. If it is false, then certain properties (indicated in their
+   *        descriptions below) may be unknown. If it is true, those properties
+   *        are never unknown.
+   *
+   * @param documentHandle A node handle that must identify a document.
+   * @return <code>true</code> if all declarations were processed;
+   *         <code>false</code> otherwise.
+   */
+  public boolean isDocumentAllDeclarationsProcessed(int documentHandle);
+
+  /**
+   *     5. [specified] A flag indicating whether this attribute was actually
+   *        specified in the start-tag of its element, or was defaulted from the
+   *        DTD (or schema).
+   *
+   * @param attributeHandle The attribute handle
+   * @return <code>true</code> if the attribute was specified;
+   *         <code>false</code> if it was defaulted or the handle doesn't
+   *            refer to an attribute node.
+   */
+  public boolean isAttributeSpecified(int attributeHandle);
+
+  // ========== Direct SAX Dispatch, for optimization purposes ========
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value). Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   * @param normalize true if the content should be normalized according to
+   * the rules for the XPath
+   * <a href="http://www.w3.org/TR/xpath#function-normalize-space">normalize-space</a>
+   * function.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(
+    int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize)
+      throws org.xml.sax.SAXException;
+
+  /**
+   * Directly create SAX parser events representing the XML content of
+   * a DTM subtree. This is a "serialize" operation.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
+    throws org.xml.sax.SAXException;
+
+  /**
+   * Return an DOM node for the given node.
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A node representation of the DTM node.
+   */
+  public org.w3c.dom.Node getNode(int nodeHandle);
+
+  // ==== Construction methods (may not be supported by some implementations!) =====
+  // %REVIEW% What response occurs if not supported?
+
+  /**
+   * @return true iff we're building this model incrementally (eg
+   * we're partnered with a CoroutineParser) and thus require that the
+   * transformation and the parse run simultaneously. Guidance to the
+   * DTMManager.
+   */
+  public boolean needsTwoThreads();
+
+  // %REVIEW% Do these appends make any sense, should we support a
+  // wider set of methods (like the "append" methods in the
+  // current DTMDocumentImpl draft), or should we just support SAX
+  // listener interfaces?  Should it be a separate interface to
+  // make that distinction explicit?
+
+  /**
+   * Return this DTM's content handler, if it has one.
+   *
+   * @return null if this model doesn't respond to SAX events.
+   */
+  public org.xml.sax.ContentHandler getContentHandler();
+
+  /**
+   * Return this DTM's lexical handler, if it has one.
+   *
+   * %REVIEW% Should this return null if constrution already done/begun?
+   *
+   * @return null if this model doesn't respond to lexical SAX events.
+   */
+  public org.xml.sax.ext.LexicalHandler getLexicalHandler();
+
+  /**
+   * Return this DTM's EntityResolver, if it has one.
+   *
+   * @return null if this model doesn't respond to SAX entity ref events.
+   */
+  public org.xml.sax.EntityResolver getEntityResolver();
+
+  /**
+   * Return this DTM's DTDHandler, if it has one.
+   *
+   * @return null if this model doesn't respond to SAX dtd events.
+   */
+  public org.xml.sax.DTDHandler getDTDHandler();
+
+  /**
+   * Return this DTM's ErrorHandler, if it has one.
+   *
+   * @return null if this model doesn't respond to SAX error events.
+   */
+  public org.xml.sax.ErrorHandler getErrorHandler();
+
+  /**
+   * Return this DTM's DeclHandler, if it has one.
+   *
+   * @return null if this model doesn't respond to SAX Decl events.
+   */
+  public org.xml.sax.ext.DeclHandler getDeclHandler();
+
+  /**
+   * Append a child to "the end of the document". Please note that
+   * the node is always cloned in a base DTM, since our basic behavior
+   * is immutable so nodes can't be removed from their previous
+   * location.
+   *
+   * <p> %REVIEW%  DTM maintains an insertion cursor which
+   * performs a depth-first tree walk as nodes come in, and this operation
+   * is really equivalent to:
+   *    insertionCursor.appendChild(document.importNode(newChild)))
+   * where the insert point is the last element that was appended (or
+   * the last one popped back to by an end-element operation).</p>
+   *
+   * @param newChild Must be a valid new node handle.
+   * @param clone true if the child should be cloned into the document.
+   * @param cloneDepth if the clone argument is true, specifies that the
+   *                   clone should include all it's children.
+   */
+  public void appendChild(int newChild, boolean clone, boolean cloneDepth);
+
+  /**
+   * Append a text node child that will be constructed from a string,
+   * to the end of the document. Behavior is otherwise like appendChild().
+   *
+   * @param str Non-null reference to a string.
+   */
+  public void appendTextChild(String str);
+
+  /**
+   * Get the location of a node in the source document.
+   *
+   * @param node an <code>int</code> value
+   * @return a <code>SourceLocator</code> value or null if no location
+   * is available
+   */
+  public SourceLocator getSourceLocatorFor(int node);
+
+  /**
+   * As the DTM is registered with the DTMManager, this method
+   * will be called. This will give the DTM implementation a
+   * chance to initialize any subsystems that are required to
+   * build the DTM
+   */
+  public void documentRegistration();
+
+  /**
+   * As documents are released from the DTMManager, the DTM implementation
+   * will be notified of the event. This will allow the DTM implementation
+   * to shutdown any subsystem activity that may of been assoiated with
+   * the active DTM Implementation.
+   */
+
+   public void documentRelease();
+
+   /**
+    * Migrate a DTM built with an old DTMManager to a new DTMManager.
+    * After the migration, the new DTMManager will treat the DTM as
+    * one that is built by itself.
+    * This is used to support DTM sharing between multiple transformations.
+    * @param manager the DTMManager
+    */
+   public void migrateTo(DTMManager manager);
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMAxisIterator.java b/src/main/java/org/apache/xml/dtm/DTMAxisIterator.java
new file mode 100644
index 0000000..b84efaa
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMAxisIterator.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMAxisIterator.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * This class iterates over a single XPath Axis, and returns node handles.
+ */
+public interface DTMAxisIterator extends Cloneable
+{
+
+  /** Specifies the end of the iteration, and is the same as DTM.NULL.  */
+  public static final int END = DTM.NULL;
+
+  /**
+   * Get the next node in the iteration.
+   *
+   * @return The next node handle in the iteration, or END.
+   */
+  public int next();  
+  
+
+  /**
+   * Resets the iterator to the last start node.
+   *
+   * @return A DTMAxisIterator, which may or may not be the same as this 
+   *         iterator.
+   */
+  public DTMAxisIterator reset();
+
+  /**
+   * @return the number of nodes in this iterator.  This may be an expensive 
+   * operation when called the first time.
+   */
+  public int getLast();
+
+  /**
+   * @return The position of the current node in the set, as defined by XPath.
+   */
+  public int getPosition();
+
+  /**
+   * Remembers the current node for the next call to gotoMark().
+   */
+  public void setMark();
+
+  /**
+   * Restores the current node remembered by setMark().
+   */
+  public void gotoMark();
+
+  /**
+   * Set start to END should 'close' the iterator,
+   * i.e. subsequent call to next() should return END.
+   *
+   * @param node Sets the root of the iteration.
+   *
+   * @return A DTMAxisIterator set to the start of the iteration.
+   */
+  public DTMAxisIterator setStartNode(int node);
+
+  /**
+   * Get start to END should 'close' the iterator,
+   * i.e. subsequent call to next() should return END.
+   *
+   * @return The root node of the iteration.
+   */
+  public int getStartNode();
+
+  /**
+   * @return true if this iterator has a reversed axis, else false.
+   */
+  public boolean isReverse();
+
+  /**
+   * @return a deep copy of this iterator. The clone should not be reset 
+   * from its current position.
+   */
+  public DTMAxisIterator cloneIterator();
+  
+  /**
+   * Set if restartable.
+   */
+  public void setRestartable(boolean isRestartable);
+
+  /**
+   * Return the node at the given position.
+   * 
+   * @param position The position
+   * @return The node at the given position.
+   */
+  public int getNodeByPosition(int position);
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMAxisTraverser.java b/src/main/java/org/apache/xml/dtm/DTMAxisTraverser.java
new file mode 100644
index 0000000..9045235
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMAxisTraverser.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMAxisTraverser.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * A class that implements traverses DTMAxisTraverser interface can traverse
+ * a set of nodes, usually as defined by an XPath axis.  It is different from
+ * an iterator, because it does not need to hold state, and, in fact, must not
+ * hold any iteration-based state.  It is meant to be implemented as an inner
+ * class of a DTM, and returned by the getAxisTraverser(final int axis)
+ * function.
+ *
+ * <p>A DTMAxisTraverser can probably not traverse a reverse axis in
+ * document order.</p>
+ *
+ * <p>Typical usage:</p>
+ * <pre><code>
+ * for(int nodeHandle=myTraverser.first(myContext);
+ *     nodeHandle!=DTM.NULL;
+ *     nodeHandle=myTraverser.next(myContext,nodeHandle))
+ * { ... processing for node indicated by nodeHandle goes here ... }
+ * </code></pre>
+ *
+ * @author Scott Boag
+ */
+public abstract class DTMAxisTraverser
+{
+
+  /**
+   * By the nature of the stateless traversal, the context node can not be
+   * returned or the iteration will go into an infinate loop.  So to traverse 
+   * an axis, the first function must be used to get the first node.
+   *
+   * <p>This method needs to be overloaded only by those axis that process
+   * the self node. <\p>
+   *
+   * @param context The context node of this traversal. This is the point
+   * that the traversal starts from.
+   * @return the first node in the traversal.
+   */
+  public int first(int context)
+  {
+    return next(context, context);
+  }
+
+  /**
+   * By the nature of the stateless traversal, the context node can not be
+   * returned or the iteration will go into an infinate loop.  So to traverse 
+   * an axis, the first function must be used to get the first node.
+   *
+   * <p>This method needs to be overloaded only by those axis that process
+   * the self node. <\p>
+   *
+   * @param context The context node of this traversal. This is the point
+   * of origin for the traversal -- its "root node" or starting point.
+   * @param extendedTypeID The extended type ID that must match.
+   *
+   * @return the first node in the traversal.
+   */
+  public int first(int context, int extendedTypeID)
+  {
+    return next(context, context, extendedTypeID);
+  }
+
+  /**
+   * Traverse to the next node after the current node.
+   *
+   * @param context The context node of this traversal. This is the point
+   * of origin for the traversal -- its "root node" or starting point.
+   * @param current The current node of the traversal. This is the last known
+   * location in the traversal, typically the node-handle returned by the
+   * previous traversal step. For the first traversal step, context
+   * should be set equal to current. Note that in order to test whether
+   * context is in the set, you must use the first() method instead.
+   *
+   * @return the next node in the iteration, or DTM.NULL.
+   * @see #first(int)
+   */
+  public abstract int next(int context, int current);
+
+  /**
+   * Traverse to the next node after the current node that is matched
+   * by the extended type ID.
+   *
+   * @param context The context node of this traversal. This is the point
+   * of origin for the traversal -- its "root node" or starting point.
+   * @param current The current node of the traversal. This is the last known
+   * location in the traversal, typically the node-handle returned by the
+   * previous traversal step. For the first traversal step, context
+   * should be set equal to current. Note that in order to test whether
+   * context is in the set, you must use the first() method instead.
+   * @param extendedTypeID The extended type ID that must match.
+   *
+   * @return the next node in the iteration, or DTM.NULL.
+   * @see #first(int,int)
+   */
+  public abstract int next(int context, int current, int extendedTypeID);
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMConfigurationException.java b/src/main/java/org/apache/xml/dtm/DTMConfigurationException.java
new file mode 100644
index 0000000..5de4ca7
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMConfigurationException.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMConfigurationException.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+import javax.xml.transform.SourceLocator;
+
+/**
+ * Indicates a serious configuration error.
+ */
+public class DTMConfigurationException extends DTMException {
+    static final long serialVersionUID = -4607874078818418046L;
+
+    /**
+     * Create a new <code>DTMConfigurationException</code> with no
+     * detail mesage.
+     */
+    public DTMConfigurationException() {
+        super("Configuration Error");
+    }
+
+    /**
+     * Create a new <code>DTMConfigurationException</code> with
+     * the <code>String </code> specified as an error message.
+     *
+     * @param msg The error message for the exception.
+     */
+    public DTMConfigurationException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Create a new <code>DTMConfigurationException</code> with a
+     * given <code>Exception</code> base cause of the error.
+     *
+     * @param e The exception to be encapsulated in a
+     * DTMConfigurationException.
+     */
+    public DTMConfigurationException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Create a new <code>DTMConfigurationException</code> with the
+     * given <code>Exception</code> base cause and detail message.
+     *
+     * @param msg The detail message.
+     * @param e The exception to be wrapped in a DTMConfigurationException
+     */
+    public DTMConfigurationException(String msg, Throwable e) {
+        super(msg, e);
+    }
+
+    /**
+     * Create a new DTMConfigurationException from a message and a Locator.
+     *
+     * <p>This constructor is especially useful when an application is
+     * creating its own exception from within a DocumentHandler
+     * callback.</p>
+     *
+     * @param message The error or warning message.
+     * @param locator The locator object for the error or warning.
+     */
+    public DTMConfigurationException(String message,
+                                             SourceLocator locator) {
+        super(message, locator);
+    }
+
+    /**
+     * Wrap an existing exception in a DTMConfigurationException.
+     *
+     * @param message The error or warning message, or null to
+     *                use the message from the embedded exception.
+     * @param locator The locator object for the error or warning.
+     * @param e Any exception.
+     */
+    public DTMConfigurationException(String message,
+                                             SourceLocator locator,
+                                             Throwable e) {
+        super(message, locator, e);
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMDOMException.java b/src/main/java/org/apache/xml/dtm/DTMDOMException.java
new file mode 100644
index 0000000..42a770c
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMDOMException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMDOMException.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * Simple implementation of DOMException.
+ *
+ * %REVIEW% Several classes were implementing this internally;
+ * it makes more sense to have one shared version.
+ * @xsl.usage internal
+ */
+public class DTMDOMException extends org.w3c.dom.DOMException
+{
+    static final long serialVersionUID = 1895654266613192414L;
+  /**
+   * Constructs a DOM/DTM exception.
+   *
+   * @param code
+   * @param message
+   */
+  public DTMDOMException(short code, String message)
+  {
+    super(code, message);
+  }
+
+  /**
+   * Constructor DTMDOMException
+   *
+   *
+   * @param code
+   */
+  public DTMDOMException(short code)
+  {
+    super(code, "");
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMException.java b/src/main/java/org/apache/xml/dtm/DTMException.java
new file mode 100644
index 0000000..030dc1f
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMException.java
@@ -0,0 +1,383 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMException.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+
+/**
+ * This class specifies an exceptional condition that occured
+ * in the DTM module.
+ */
+public class DTMException extends RuntimeException {
+    static final long serialVersionUID = -775576419181334734L;
+
+    /** Field locator specifies where the error occured.
+     *  @serial */
+    SourceLocator locator;
+
+    /**
+     * Method getLocator retrieves an instance of a SourceLocator
+     * object that specifies where an error occured.
+     *
+     * @return A SourceLocator object, or null if none was specified.
+     */
+    public SourceLocator getLocator() {
+        return locator;
+    }
+
+    /**
+     * Method setLocator sets an instance of a SourceLocator
+     * object that specifies where an error occured.
+     *
+     * @param location A SourceLocator object, or null to clear the location.
+     */
+    public void setLocator(SourceLocator location) {
+        locator = location;
+    }
+
+    /** Field containedException specifies a wrapped exception.  May be null.
+     *  @serial */
+    Throwable containedException;
+
+    /**
+     * This method retrieves an exception that this exception wraps.
+     *
+     * @return An Throwable object, or null.
+     * @see #getCause
+     */
+    public Throwable getException() {
+        return containedException;
+    }
+
+    /**
+     * Returns the cause of this throwable or <code>null</code> if the
+     * cause is nonexistent or unknown.  (The cause is the throwable that
+     * caused this throwable to get thrown.)
+     */
+    public Throwable getCause() {
+
+        return ((containedException == this)
+                ? null
+                : containedException);
+    }
+
+    /**
+     * Initializes the <i>cause</i> of this throwable to the specified value.
+     * (The cause is the throwable that caused this throwable to get thrown.)
+     *
+     * <p>This method can be called at most once.  It is generally called from
+     * within the constructor, or immediately after creating the
+     * throwable.  If this throwable was created
+     * with {@link #DTMException(Throwable)} or
+     * {@link #DTMException(String,Throwable)}, this method cannot be called
+     * even once.
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @return  a reference to this <code>Throwable</code> instance.
+     * @throws IllegalArgumentException if <code>cause</code> is this
+     *         throwable.  (A throwable cannot
+     *         be its own cause.)
+     * @throws IllegalStateException if this throwable was
+     *         created with {@link #DTMException(Throwable)} or
+     *         {@link #DTMException(String,Throwable)}, or this method has already
+     *         been called on this throwable.
+     */
+    public synchronized Throwable initCause(Throwable cause) {
+
+        if ((this.containedException == null) && (cause != null)) {
+            throw new IllegalStateException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_OVERWRITE_CAUSE, null)); //"Can't overwrite cause");
+        }
+
+        if (cause == this) {
+            throw new IllegalArgumentException(
+                XMLMessages.createXMLMessage(XMLErrorResources.ER_SELF_CAUSATION_NOT_PERMITTED, null)); //"Self-causation not permitted");
+        }
+
+        this.containedException = cause;
+
+        return this;
+    }
+
+    /**
+     * Create a new DTMException.
+     *
+     * @param message The error or warning message.
+     */
+    public DTMException(String message) {
+
+        super(message);
+
+        this.containedException = null;
+        this.locator            = null;
+    }
+
+    /**
+     * Create a new DTMException wrapping an existing exception.
+     *
+     * @param e The exception to be wrapped.
+     */
+    public DTMException(Throwable e) {
+
+        super(e.getMessage());
+
+        this.containedException = e;
+        this.locator            = null;
+    }
+
+    /**
+     * Wrap an existing exception in a DTMException.
+     *
+     * <p>This is used for throwing processor exceptions before
+     * the processing has started.</p>
+     *
+     * @param message The error or warning message, or null to
+     *                use the message from the embedded exception.
+     * @param e Any exception
+     */
+    public DTMException(String message, Throwable e) {
+
+        super(((message == null) || (message.length() == 0))
+              ? e.getMessage()
+              : message);
+
+        this.containedException = e;
+        this.locator            = null;
+    }
+
+    /**
+     * Create a new DTMException from a message and a Locator.
+     *
+     * <p>This constructor is especially useful when an application is
+     * creating its own exception from within a DocumentHandler
+     * callback.</p>
+     *
+     * @param message The error or warning message.
+     * @param locator The locator object for the error or warning.
+     */
+    public DTMException(String message, SourceLocator locator) {
+
+        super(message);
+
+        this.containedException = null;
+        this.locator            = locator;
+    }
+
+    /**
+     * Wrap an existing exception in a DTMException.
+     *
+     * @param message The error or warning message, or null to
+     *                use the message from the embedded exception.
+     * @param locator The locator object for the error or warning.
+     * @param e Any exception
+     */
+    public DTMException(String message, SourceLocator locator,
+                                Throwable e) {
+
+        super(message);
+
+        this.containedException = e;
+        this.locator            = locator;
+    }
+
+    /**
+     * Get the error message with location information
+     * appended.
+     */
+    public String getMessageAndLocation() {
+
+        StringBuffer sbuffer = new StringBuffer();
+        String       message = super.getMessage();
+
+        if (null != message) {
+            sbuffer.append(message);
+        }
+
+        if (null != locator) {
+            String systemID = locator.getSystemId();
+            int    line     = locator.getLineNumber();
+            int    column   = locator.getColumnNumber();
+
+            if (null != systemID) {
+                sbuffer.append("; SystemID: ");
+                sbuffer.append(systemID);
+            }
+
+            if (0 != line) {
+                sbuffer.append("; Line#: ");
+                sbuffer.append(line);
+            }
+
+            if (0 != column) {
+                sbuffer.append("; Column#: ");
+                sbuffer.append(column);
+            }
+        }
+
+        return sbuffer.toString();
+    }
+
+    /**
+     * Get the location information as a string.
+     *
+     * @return A string with location info, or null
+     * if there is no location information.
+     */
+    public String getLocationAsString() {
+
+        if (null != locator) {
+            StringBuffer sbuffer  = new StringBuffer();
+            String       systemID = locator.getSystemId();
+            int          line     = locator.getLineNumber();
+            int          column   = locator.getColumnNumber();
+
+            if (null != systemID) {
+                sbuffer.append("; SystemID: ");
+                sbuffer.append(systemID);
+            }
+
+            if (0 != line) {
+                sbuffer.append("; Line#: ");
+                sbuffer.append(line);
+            }
+
+            if (0 != column) {
+                sbuffer.append("; Column#: ");
+                sbuffer.append(column);
+            }
+
+            return sbuffer.toString();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Print the the trace of methods from where the error
+     * originated.  This will trace all nested exception
+     * objects, as well as this object.
+     */
+    public void printStackTrace() {
+        printStackTrace(new java.io.PrintWriter(System.err, true));
+    }
+
+    /**
+     * Print the the trace of methods from where the error
+     * originated.  This will trace all nested exception
+     * objects, as well as this object.
+     * @param s The stream where the dump will be sent to.
+     */
+    public void printStackTrace(java.io.PrintStream s) {
+        printStackTrace(new java.io.PrintWriter(s));
+    }
+
+    /**
+     * Print the the trace of methods from where the error
+     * originated.  This will trace all nested exception
+     * objects, as well as this object.
+     * @param s The writer where the dump will be sent to.
+     */
+    public void printStackTrace(java.io.PrintWriter s) {
+
+        if (s == null) {
+            s = new java.io.PrintWriter(System.err, true);
+        }
+
+        try {
+            String locInfo = getLocationAsString();
+
+            if (null != locInfo) {
+                s.println(locInfo);
+            }
+
+            super.printStackTrace(s);
+        } catch (Throwable e) {}
+
+        boolean isJdk14OrHigher = false;
+        try {
+            Throwable.class.getMethod("getCause", (Class<?>) null);
+            isJdk14OrHigher = true;
+        } catch (NoSuchMethodException nsme) {
+            // do nothing
+        }        
+
+        // The printStackTrace method of the Throwable class in jdk 1.4 
+        // and higher will include the cause when printing the backtrace.
+        // The following code is only required when using jdk 1.3 or lower                
+        if (!isJdk14OrHigher) {
+            Throwable exception = getException();
+    
+            for (int i = 0; (i < 10) && (null != exception); i++) {
+                s.println("---------");
+    
+                try {
+                    if (exception instanceof DTMException) {
+                        String locInfo =
+                            ((DTMException) exception)
+                                .getLocationAsString();
+    
+                        if (null != locInfo) {
+                            s.println(locInfo);
+                        }
+                    }
+    
+                    exception.printStackTrace(s);
+                } catch (Throwable e) {
+                    s.println("Could not print stack trace...");
+                }
+    
+                try {
+                    Method meth =
+                        ((Object) exception).getClass().getMethod("getException",
+                            (Class<?>) null);
+    
+                    if (null != meth) {
+                        Throwable prev = exception;
+    
+                        exception = (Throwable) meth.invoke(exception, (Class<?>) null);
+    
+                        if (prev == exception) {
+                            break;
+                        }
+                    } else {
+                        exception = null;
+                    }
+                } catch (InvocationTargetException ite) {
+                    exception = null;
+                } catch (IllegalAccessException iae) {
+                    exception = null;
+                } catch (NoSuchMethodException nsme) {
+                    exception = null;
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMFilter.java b/src/main/java/org/apache/xml/dtm/DTMFilter.java
new file mode 100644
index 0000000..5d0dfe0
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMFilter.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMFilter.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * Simple filter for doing node tests.  Note the semantics of this are
+ * somewhat different that the DOM's NodeFilter.
+ */
+public interface DTMFilter
+{
+
+  // Constants for whatToShow.  These are used to set the node type that will 
+  // be traversed. These values may be ORed together before being passed to
+  // the DTMIterator.
+
+  /**
+   * Show all <code>Nodes</code>.
+   */
+  public static final int SHOW_ALL = 0xFFFFFFFF;
+
+  /**
+   * Show <code>Element</code> nodes.
+   */
+  public static final int SHOW_ELEMENT = 0x00000001;
+
+  /**
+   * Show <code>Attr</code> nodes. This is meaningful only when creating an
+   * iterator or tree-walker with an attribute node as its
+   * <code>root</code>; in this case, it means that the attribute node
+   * will appear in the first position of the iteration or traversal.
+   * Since attributes are never children of other nodes, they do not
+   * appear when traversing over the main document tree.
+   */
+  public static final int SHOW_ATTRIBUTE = 0x00000002;
+
+  /**
+   * Show <code>Text</code> nodes.
+   */
+  public static final int SHOW_TEXT = 0x00000004;
+
+  /**
+   * Show <code>CDATASection</code> nodes.
+   */
+  public static final int SHOW_CDATA_SECTION = 0x00000008;
+
+  /**
+   * Show <code>EntityReference</code> nodes. Note that if Entity References
+   * have been fully expanded while the tree was being constructed, these
+   * nodes will not appear and this mask has no effect.
+   */
+  public static final int SHOW_ENTITY_REFERENCE = 0x00000010;
+
+  /**
+   * Show <code>Entity</code> nodes. This is meaningful only when creating
+   * an iterator or tree-walker with an<code> Entity</code> node as its
+   * <code>root</code>; in this case, it means that the <code>Entity</code>
+   *  node will appear in the first position of the traversal. Since
+   * entities are not part of the document tree, they do not appear when
+   * traversing over the main document tree.
+   */
+  public static final int SHOW_ENTITY = 0x00000020;
+
+  /**
+   * Show <code>ProcessingInstruction</code> nodes.
+   */
+  public static final int SHOW_PROCESSING_INSTRUCTION = 0x00000040;
+
+  /**
+   * Show <code>Comment</code> nodes.
+   */
+  public static final int SHOW_COMMENT = 0x00000080;
+
+  /**
+   * Show <code>Document</code> nodes. (Of course, as with Attributes
+   * and such, this is meaningful only when the iteration root is the
+   * Document itself, since Document has no parent.)
+   */
+  public static final int SHOW_DOCUMENT = 0x00000100;
+
+  /**
+   * Show <code>DocumentType</code> nodes. 
+   */
+  public static final int SHOW_DOCUMENT_TYPE = 0x00000200;
+
+  /**
+   * Show <code>DocumentFragment</code> nodes. (Of course, as with
+   * Attributes and such, this is meaningful only when the iteration
+   * root is the Document itself, since DocumentFragment has no parent.)
+   */
+  public static final int SHOW_DOCUMENT_FRAGMENT = 0x00000400;
+
+  /**
+   * Show <code>Notation</code> nodes. This is meaningful only when creating
+   * an iterator or tree-walker with a <code>Notation</code> node as its
+   * <code>root</code>; in this case, it means that the
+   * <code>Notation</code> node will appear in the first position of the
+   * traversal. Since notations are not part of the document tree, they do
+   * not appear when traversing over the main document tree.
+   */
+  public static final int SHOW_NOTATION = 0x00000800;
+  
+  /**
+
+   * This bit instructs the iterator to show namespace nodes, which
+   * are modeled by DTM but not by the DOM.  Make sure this does not
+   * conflict with {@link org.w3c.dom.traversal.NodeFilter}.
+   * <p>
+   * %REVIEW% Might be safer to start from higher bits and work down,
+   * to leave room for the DOM to expand its set of constants... Or,
+   * possibly, to create a DTM-specific field for these additional bits.
+   */
+  public static final int SHOW_NAMESPACE = 0x00001000;
+
+  /**
+   * Special bit for filters implementing match patterns starting with
+   * a function.  Make sure this does not conflict with
+   * {@link org.w3c.dom.traversal.NodeFilter}.
+   * <p>
+   * %REVIEW% Might be safer to start from higher bits and work down,
+   * to leave room for the DOM to expand its set of constants... Or,
+   * possibly, to create a DTM-specific field for these additional bits.
+   */
+  public static final int SHOW_BYFUNCTION = 0x00010000;
+
+  /**
+   * Test whether a specified node is visible in the logical view of a
+   * <code>DTMIterator</code>. Normally, this function
+   * will be called by the implementation of <code>DTMIterator</code>; 
+   * it is not normally called directly from
+   * user code.
+   * 
+   * @param nodeHandle int Handle of the node.
+   * @param whatToShow one of SHOW_XXX values.
+   * @return one of FILTER_ACCEPT, FILTER_REJECT, or FILTER_SKIP.
+   */
+  public short acceptNode(int nodeHandle, int whatToShow);
+  
+  /**
+   * Test whether a specified node is visible in the logical view of a
+   * <code>DTMIterator</code>. Normally, this function
+   * will be called by the implementation of <code>DTMIterator</code>; 
+   * it is not normally called directly from
+   * user code.
+   * <p>
+   * TODO: Should this be setNameMatch(expandedName) followed by accept()?
+   * Or will we really be testing a different name at every invocation?
+   * 
+   * <p>%REVIEW% Under what circumstances will this be used? The cases
+   * I've considered are just as easy and just about as efficient if
+   * the name test is performed in the DTMIterator... -- Joe</p>
+   * 
+   * <p>%REVIEW% Should that 0xFFFF have a mnemonic assigned to it?
+   * Also: This representation is assuming the expanded name is indeed
+   * split into high/low 16-bit halfwords. If we ever change the
+   * balance between namespace and localname bits (eg because we
+   * decide there are many more localnames than namespaces, which is
+   * fairly likely), this is going to break. It might be safer to
+   * encapsulate the details with a makeExpandedName method and make
+   * that responsible for setting up the wildcard version as well.</p>
+   * 
+   * @param nodeHandle int Handle of the node.
+   * @param whatToShow one of SHOW_XXX values.
+   * @param expandedName a value defining the exanded name as defined in 
+   *                     the DTM interface.  Wild cards will be defined 
+   *                     by 0xFFFF in the namespace and/or localname
+   *			 portion of the expandedName.
+   * @return one of FILTER_ACCEPT, FILTER_REJECT, or FILTER_SKIP.  */
+  public short acceptNode(int nodeHandle, int whatToShow, int expandedName);
+ 
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMIterator.java b/src/main/java/org/apache/xml/dtm/DTMIterator.java
new file mode 100644
index 0000000..a251c11
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMIterator.java
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMIterator.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+
+ * <code>DTMIterators</code> are used to step through a (possibly
+ * filtered) set of nodes.  Their API is modeled largely after the DOM
+ * NodeIterator.
+ * 
+ * <p>A DTMIterator is a somewhat unusual type of iterator, in that it 
+ * can serve both single node iteration and random access.</p>
+ * 
+ * <p>The DTMIterator's traversal semantics, i.e. how it walks the tree,
+ * are specified when it is created, possibly and probably by an XPath
+ * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or 
+ * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.</p>
+ * 
+ * <p>A DTMIterator is meant to be created once as a master static object, and 
+ * then cloned many times for runtime use.  Or the master object itself may 
+ * be used for simpler use cases.</p>
+ *
+ * <p>At this time, we do not expect DTMIterator to emulate
+ * NodeIterator's "maintain relative position" semantics under
+ * document mutation.  It's likely to respond more like the
+ * TreeWalker's "current node" semantics. However, since the base DTM
+ * is immutable, this issue currently makes no practical
+ * difference.</p>
+ *
+ * <p>State: In progress!!</p> */
+public interface DTMIterator
+{
+
+  // Constants returned by acceptNode, borrowed from the DOM Traversal chapter
+  // %REVIEW% Should we explicitly initialize them from, eg,
+  // org.w3c.dom.traversal.NodeFilter.FILTER_ACCEPT?
+
+  /**
+   * Accept the node.
+   */
+  public static final short FILTER_ACCEPT = 1;
+
+  /**
+   * Reject the node. Same behavior as FILTER_SKIP. (In the DOM these
+   * differ when applied to a TreeWalker but have the same result when
+   * applied to a NodeIterator).
+   */
+  public static final short FILTER_REJECT = 2;
+
+  /**
+   * Skip this single node. 
+   */
+  public static final short FILTER_SKIP = 3;
+    
+  /**
+   * Get an instance of a DTM that "owns" a node handle.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTM using just the iterator.
+   *
+   * @param nodeHandle the nodeHandle.
+   *
+   * @return a non-null DTM reference.
+   */
+  public DTM getDTM(int nodeHandle);
+  
+  /**
+   * Get an instance of the DTMManager.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTMManager using just the iterator.
+   *
+   * @return a non-null DTMManager reference.
+   */
+  public DTMManager getDTMManager();
+
+  /**
+   * The root node of the <code>DTMIterator</code>, as specified when it
+   * was created.  Note the root node is not the root node of the 
+   * document tree, but the context node from where the iteration 
+   * begins and ends.
+   *
+   * @return nodeHandle int Handle of the context node.
+   */
+  public int getRoot();
+
+  /**
+   * Reset the root node of the <code>DTMIterator</code>, overriding
+   * the value specified when it was created.  Note the root node is
+   * not the root node of the document tree, but the context node from
+   * where the iteration begins.
+   *
+   * @param nodeHandle int Handle of the context node.
+   * @param environment The environment object.  
+   * The environment in which this iterator operates, which should provide:
+   * <ul>
+   * <li>a node (the context node... same value as "root" defined below) </li>
+   * <li>a pair of non-zero positive integers (the context position and the context size) </li>
+   * <li>a set of variable bindings </li>
+   * <li>a function library </li>
+   * <li>the set of namespace declarations in scope for the expression.</li>
+   * <ul>
+   * 
+   * <p>At this time the exact implementation of this environment is application 
+   * dependent.  Probably a proper interface will be created fairly soon.</p>
+   * 
+   */
+  public void setRoot(int nodeHandle, Object environment);
+  
+  /**
+   * Reset the iterator to the start. After resetting, the next node returned
+   * will be the root node -- or, if that's filtered out, the first node
+   * within the root's subtree which is _not_ skipped by the filters.
+   */
+  public void reset();
+
+  /**
+   * This attribute determines which node types are presented via the
+   * iterator. The available set of constants is defined above.  
+   * Nodes not accepted by
+   * <code>whatToShow</code> will be skipped, but their children may still
+   * be considered.
+   *
+   * @return one of the SHOW_XXX constants, or several ORed together.
+   */
+  public int getWhatToShow();
+
+  /**
+   * <p>The value of this flag determines whether the children of entity
+   * reference nodes are visible to the iterator. If false, they  and
+   * their descendants will be rejected. Note that this rejection takes
+   * precedence over <code>whatToShow</code> and the filter. </p>
+   * 
+   * <p> To produce a view of the document that has entity references
+   * expanded and does not expose the entity reference node itself, use
+   * the <code>whatToShow</code> flags to hide the entity reference node
+   * and set <code>expandEntityReferences</code> to true when creating the
+   * iterator. To produce a view of the document that has entity reference
+   * nodes but no entity expansion, use the <code>whatToShow</code> flags
+   * to show the entity reference node and set
+   * <code>expandEntityReferences</code> to false.</p>
+   *
+   * <p>NOTE: In Xalan's use of DTM we will generally have fully expanded
+   * entity references when the document tree was built, and thus this
+   * flag will have no effect.</p>
+   *
+   * @return true if entity references will be expanded.  */
+  public boolean getExpandEntityReferences();
+
+  /**
+   * Returns the next node in the set and advances the position of the
+   * iterator in the set. After a <code>DTMIterator</code> has setRoot called,
+   * the first call to <code>nextNode()</code> returns that root or (if it
+   * is rejected by the filters) the first node within its subtree which is
+   * not filtered out.
+   * @return The next node handle in the set being iterated over, or
+   *  <code>DTM.NULL</code> if there are no more members in that set.
+   */
+  public int nextNode();
+
+  /**
+   * Returns the previous node in the set and moves the position of the
+   * <code>DTMIterator</code> backwards in the set.
+   * @return The previous node handle in the set being iterated over,
+   *   or <code>DTM.NULL</code> if there are no more members in that set.
+   */
+  public int previousNode();
+
+  /**
+   * Detaches the <code>DTMIterator</code> from the set which it iterated
+   * over, releasing any computational resources and placing the iterator
+   * in the INVALID state. After <code>detach</code> has been invoked,
+   * calls to <code>nextNode</code> or <code>previousNode</code> will
+   * raise a runtime exception.
+   */
+  public void detach();
+  
+  /**
+   * Specify if it's OK for detach to release the iterator for reuse.
+   * 
+   * @param allowRelease true if it is OK for detach to release this iterator 
+   * for pooling.
+   */
+  public void allowDetachToRelease(boolean allowRelease);
+
+  /**
+   * Get the current node in the iterator. Note that this differs from
+   * the DOM's NodeIterator, where the current position lies between two
+   * nodes (as part of the maintain-relative-position semantic).
+   *
+   * @return The current node handle, or -1.
+   */
+  public int getCurrentNode();
+
+  /**
+   * Tells if this NodeSetDTM is "fresh", in other words, if
+   * the first nextNode() that is called will return the
+   * first node in the set.
+   *
+   * @return true if the iteration of this list has not yet begun.
+   */
+  public boolean isFresh();
+
+  //========= Random Access ==========
+
+  /**
+   * If setShouldCacheNodes(true) is called, then nodes will
+   * be cached, enabling random access, and giving the ability to do 
+   * sorts and the like.  They are not cached by default.
+   *
+   * %REVIEW% Shouldn't the other random-access methods throw an exception
+   * if they're called on a DTMIterator with this flag set false?
+   *
+   * @param b true if the nodes should be cached.
+   */
+  public void setShouldCacheNodes(boolean b);
+  
+  /**
+   * Tells if this iterator can have nodes added to it or set via 
+   * the <code>setItem(int node, int index)</code> method.
+   * 
+   * @return True if the nodelist can be mutated.
+   */
+  public boolean isMutable();
+
+  /** Get the current position within the cached list, which is one
+   * less than the next nextNode() call will retrieve.  i.e. if you
+   * call getCurrentPos() and the return is 0, the next fetch will
+   * take place at index 1.
+   *
+   * @return The position of the iteration.
+   */
+  public int getCurrentPos();
+
+  /**
+   * If an index is requested, NodeSetDTM will call this method
+   * to run the iterator to the index.  By default this sets
+   * m_next to the index.  If the index argument is -1, this
+   * signals that the iterator should be run to the end and
+   * completely fill the cache.
+   *
+   * @param index The index to run to, or -1 if the iterator should be run
+   *              to the end.
+   */
+  public void runTo(int index);
+
+  /**
+   * Set the current position in the node set.
+   * 
+   * @param i Must be a valid index.
+   */
+  public void setCurrentPos(int i);
+
+  /**
+   * Returns the <code>node handle</code> of an item in the collection. If
+   * <code>index</code> is greater than or equal to the number of nodes in
+   * the list, this returns <code>null</code>.
+   *
+   * @param index of the item.
+   * @return The node handle at the <code>index</code>th position in the
+   *   <code>DTMIterator</code>, or <code>-1</code> if that is not a valid
+   *   index.
+   */
+  public int item(int index);
+  
+  /**
+   * Sets the node at the specified index of this vector to be the
+   * specified node. The previous component at that position is discarded.
+   *
+   * <p>The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.  
+   * The iterator must be in cached mode.</p>
+   * 
+   * <p>Meant to be used for sorted iterators.</p>
+   *
+   * @param node Node to set
+   * @param index Index of where to set the node
+   */
+  public void setItem(int node, int index);
+  
+  /**
+   * The number of nodes in the list. The range of valid child node indices
+   * is 0 to <code>length-1</code> inclusive. Note that this requires running
+   * the iterator to completion, and presumably filling the cache.
+   *
+   * @return The number of nodes in the list.
+   */
+  public int getLength();
+    
+  //=========== Cloning operations. ============
+  
+  /**
+   * Get a cloned Iterator that is reset to the start of the iteration.
+   *
+   * @return A clone of this iteration that has been reset.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException;
+
+  /**
+   * Get a clone of this iterator, but don't reset the iteration in the 
+   * process, so that it may be used from the current position.
+   *
+   * @return A clone of this object.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException;
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * 
+   * @return true if all the nodes in the iteration well be returned in document 
+   * order.
+   */
+  public boolean isDocOrdered();
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis();
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMManager.java b/src/main/java/org/apache/xml/dtm/DTMManager.java
new file mode 100644
index 0000000..d716c57
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMManager.java
@@ -0,0 +1,430 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMManager.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.XMLStringFactory;
+
+/**
+ * A DTMManager instance can be used to create DTM and
+ * DTMIterator objects, and manage the DTM objects in the system.
+ *
+ * <p>The system property that determines which Factory implementation
+ * to create is named "org.apache.xml.utils.DTMFactory". This
+ * property names a concrete subclass of the DTMFactory abstract
+ *  class. If the property is not defined, a platform default is be used.</p>
+ *
+ * <p>An instance of this class <emph>must</emph> be safe to use across
+ * thread instances.  It is expected that a client will create a single instance
+ * of a DTMManager to use across multiple threads.  This will allow sharing
+ * of DTMs across multiple processes.</p>
+ *
+ * <p>Note: this class is incomplete right now.  It will be pretty much
+ * modeled after javax.xml.transform.TransformerFactory in terms of its
+ * factory support.</p>
+ *
+ * <p>State: In progress!!</p>
+ */
+public abstract class DTMManager
+{
+
+  /** The default property name to load the manager. */
+  private static final String defaultPropName =
+    "org.apache.xml.dtm.DTMManager";
+  
+  /** The default class name to use as the manager. */
+  private static String defaultClassName =
+    "org.apache.xml.dtm.ref.DTMManagerDefault";
+
+  /**
+   * Factory for creating XMLString objects.
+   *  %TBD% Make this set by the caller.
+   */
+  protected XMLStringFactory m_xsf = null;
+
+  /**
+   * Default constructor is protected on purpose.
+   */
+  protected DTMManager(){}
+
+  /**
+   * Get the XMLStringFactory used for the DTMs.
+   *
+   *
+   * @return a valid XMLStringFactory object, or null if it hasn't been set yet.
+   */
+  public XMLStringFactory getXMLStringFactory()
+  {
+    return m_xsf;
+  }
+
+  /**
+   * Set the XMLStringFactory used for the DTMs.
+   *
+   *
+   * @param xsf a valid XMLStringFactory object, should not be null.
+   */
+  public void setXMLStringFactory(XMLStringFactory xsf)
+  {
+    m_xsf = xsf;
+  }
+
+  /**
+   * Obtain a new instance of a <code>DTMManager</code>.
+   * This static method creates a new factory instance
+   * This method uses the following ordered lookup procedure to determine
+   * the <code>DTMManager</code> implementation class to
+   * load:
+   * <ul>
+   * <li>
+   * Use the <code>org.apache.xml.dtm.DTMManager</code> system
+   * property.
+   * </li>
+   * <li>
+   * Use the JAVA_HOME(the parent directory where jdk is
+   * installed)/lib/xalan.properties for a property file that contains the
+   * name of the implementation class keyed on the same value as the
+   * system property defined above.
+   * </li>
+   * <li>
+   * Use the Services API (as detailed in the JAR specification), if
+   * available, to determine the classname. The Services API will look
+   * for a classname in the file
+   * <code>META-INF/services/org.apache.xml.dtm.DTMManager</code>
+   * in jars available to the runtime.
+   * </li>
+   * <li>
+   * Use the default <code>DTMManager</code> classname, which is
+   * <code>org.apache.xml.dtm.ref.DTMManagerDefault</code>.
+   * </li>
+   * </ul>
+   *
+   * Once an application has obtained a reference to a <code>
+   * DTMManager</code> it can use the factory to configure
+   * and obtain parser instances.
+   *
+   * @return new DTMManager instance, never null.
+   *
+   * @throws DTMConfigurationException
+   * if the implementation is not available or cannot be instantiated.
+   */
+  public static DTMManager newInstance(XMLStringFactory xsf) 
+           throws DTMConfigurationException
+  {
+    DTMManager factoryImpl = null;
+    try
+    {
+      factoryImpl = (DTMManager) ObjectFactory
+        .createObject(defaultPropName, defaultClassName);
+    }
+    catch (ObjectFactory.ConfigurationError e)
+    {
+      throw new DTMConfigurationException(XMLMessages.createXMLMessage(
+        XMLErrorResources.ER_NO_DEFAULT_IMPL, null), e.getException());
+        //"No default implementation found");
+    }
+
+    if (factoryImpl == null)
+    {
+      throw new DTMConfigurationException(XMLMessages.createXMLMessage(
+        XMLErrorResources.ER_NO_DEFAULT_IMPL, null));
+        //"No default implementation found");
+    }
+
+    factoryImpl.setXMLStringFactory(xsf);
+
+    return factoryImpl;
+  }
+
+  /**
+   * Get an instance of a DTM, loaded with the content from the
+   * specified source.  If the unique flag is true, a new instance will
+   * always be returned.  Otherwise it is up to the DTMManager to return a
+   * new instance or an instance that it already created and may be being used
+   * by someone else.
+   * 
+   * (More parameters may eventually need to be added for error handling
+   * and entity resolution, and to better control selection of implementations.)
+   *
+   * @param source the specification of the source object, which may be null,
+   *               in which case it is assumed that node construction will take
+   *               by some other means.
+   * @param unique true if the returned DTM must be unique, probably because it
+   * is going to be mutated.
+   * @param whiteSpaceFilter Enables filtering of whitespace nodes, and may
+   *                         be null.
+   * @param incremental true if the DTM should be built incrementally, if
+   *                    possible.
+   * @param doIndexing true if the caller considers it worth it to use 
+   *                   indexing schemes.
+   *
+   * @return a non-null DTM reference.
+   */
+  public abstract DTM getDTM(javax.xml.transform.Source source,
+                             boolean unique, DTMWSFilter whiteSpaceFilter,
+                             boolean incremental, boolean doIndexing);
+
+  /**
+   * Get the instance of DTM that "owns" a node handle.
+   *
+   * @param nodeHandle the nodeHandle.
+   *
+   * @return a non-null DTM reference.
+   */
+  public abstract DTM getDTM(int nodeHandle);
+
+  /**
+   * Given a W3C DOM node, try and return a DTM handle.
+   * Note: calling this may be non-optimal.
+   *
+   * @param node Non-null reference to a DOM node.
+   *
+   * @return a valid DTM handle.
+   */
+  public abstract int getDTMHandleFromNode(org.w3c.dom.Node node);
+
+  /**
+   * Creates a DTM representing an empty <code>DocumentFragment</code> object.
+   * @return a non-null DTM reference.
+   */
+  public abstract DTM createDocumentFragment();
+
+  /**
+   * Release a DTM either to a lru pool, or completely remove reference.
+   * DTMs without system IDs are always hard deleted.
+   * State: experimental.
+   *
+   * @param dtm The DTM to be released.
+   * @param shouldHardDelete True if the DTM should be removed no matter what.
+   * @return true if the DTM was removed, false if it was put back in a lru pool.
+   */
+  public abstract boolean release(DTM dtm, boolean shouldHardDelete);
+
+  /**
+   * Create a new <code>DTMIterator</code> based on an XPath
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param xpathCompiler ??? Somehow we need to pass in a subpart of the
+   * expression.  I hate to do this with strings, since the larger expression
+   * has already been parsed.
+   *
+   * @param pos The position in the expression.
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public abstract DTMIterator createDTMIterator(Object xpathCompiler,
+          int pos);
+
+  /**
+   * Create a new <code>DTMIterator</code> based on an XPath
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param xpathString Must be a valid string expressing a
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param presolver An object that can resolve prefixes to namespace URLs.
+   *
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public abstract DTMIterator createDTMIterator(String xpathString,
+          PrefixResolver presolver);
+
+  /**
+   * Create a new <code>DTMIterator</code> based only on a whatToShow
+   * and a DTMFilter.  The traversal semantics are defined as the
+   * descendant access.
+   * <p>
+   * Note that DTMIterators may not be an exact match to DOM
+   * NodeIterators. They are initialized and used in much the same way
+   * as a NodeIterator, but their response to document mutation is not
+   * currently defined.
+   *
+   * @param whatToShow This flag specifies which node types may appear in
+   *   the logical view of the tree presented by the iterator. See the
+   *   description of <code>NodeFilter</code> for the set of possible
+   *   <code>SHOW_</code> values.These flags can be combined using
+   *   <code>OR</code>.
+   * @param filter The <code>NodeFilter</code> to be used with this
+   *   <code>DTMFilter</code>, or <code>null</code> to indicate no filter.
+   * @param entityReferenceExpansion The value of this flag determines
+   *   whether entity reference nodes are expanded.
+   *
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public abstract DTMIterator createDTMIterator(int whatToShow,
+          DTMFilter filter, boolean entityReferenceExpansion);
+
+  /**
+   * Create a new <code>DTMIterator</code> that holds exactly one node.
+   *
+   * @param node The node handle that the DTMIterator will iterate to.
+   *
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public abstract DTMIterator createDTMIterator(int node);
+  
+  /* Flag indicating whether an incremental transform is desired */
+  public boolean m_incremental = false;
+  
+  /*
+   * Flag set by FEATURE_SOURCE_LOCATION.
+   * This feature specifies whether the transformation phase should
+   * keep track of line and column numbers for the input source
+   * document. 
+   */
+  public boolean m_source_location = false; 
+  
+  /**
+   * Get a flag indicating whether an incremental transform is desired 
+   * @return incremental boolean.
+   *
+   */
+  public boolean getIncremental()
+  {
+    return m_incremental;  
+  }
+  
+  /**
+   * Set a flag indicating whether an incremental transform is desired
+   * This flag should have the same value as the FEATURE_INCREMENTAL feature
+   * which is set by the TransformerFactory.setAttribut() method before a
+   * DTMManager is created
+   * @param incremental boolean to use to set m_incremental.
+   *
+   */
+  public void setIncremental(boolean incremental)
+  {
+    m_incremental = incremental;  
+  }
+  
+  /**
+   * Get a flag indicating whether the transformation phase should
+   * keep track of line and column numbers for the input source
+   * document.
+   * @return source location boolean
+   *
+   */
+  public boolean getSource_location()
+  {
+    return m_source_location;  
+  }  
+  
+  /**
+   * Set a flag indicating whether the transformation phase should
+   * keep track of line and column numbers for the input source
+   * document.
+   * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature
+   * which is set by the TransformerFactory.setAttribut() method before a
+   * DTMManager is created
+   * @param sourceLocation boolean to use to set m_source_location
+   */
+  public void setSource_location(boolean sourceLocation){
+    m_source_location = sourceLocation;
+  }
+  
+
+  // -------------------- private methods --------------------
+
+   /**
+   * Temp debug code - this will be removed after we test everything
+   */
+  private static boolean debug;
+
+  static
+  {
+    try
+    {
+      debug = System.getProperty("dtm.debug") != null;
+    }
+    catch (SecurityException ex){}
+  }
+
+  /** This value, set at compile time, controls how many bits of the
+   * DTM node identifier numbers are used to identify a node within a
+   * document, and thus sets the maximum number of nodes per
+   * document. The remaining bits are used to identify the DTM
+   * document which contains this node.
+   *
+   * If you change IDENT_DTM_NODE_BITS, be sure to rebuild _ALL_ the
+   * files which use it... including the IDKey testcases.
+   *
+   * (FuncGenerateKey currently uses the node identifier directly and
+   * thus is affected when this changes. The IDKEY results will still be
+   * _correct_ (presuming no other breakage), but simple equality
+   * comparison against the previous "golden" files will probably
+   * complain.)
+   * */
+  public static final int IDENT_DTM_NODE_BITS = 16;
+    
+
+  /** When this bitmask is ANDed with a DTM node handle number, the result
+   * is the low bits of the node's index number within that DTM. To obtain
+   * the high bits, add the DTM ID portion's offset as assigned in the DTM 
+   * Manager.
+   */
+  public static final int IDENT_NODE_DEFAULT = (1<<IDENT_DTM_NODE_BITS)-1;
+
+
+  /** When this bitmask is ANDed with a DTM node handle number, the result
+   * is the DTM's document identity number.
+   */
+  public static final int IDENT_DTM_DEFAULT = ~IDENT_NODE_DEFAULT;
+
+  /** This is the maximum number of DTMs available.  The highest DTM is
+    * one less than this.
+   */
+  public static final int IDENT_MAX_DTMS = (IDENT_DTM_DEFAULT >>> IDENT_DTM_NODE_BITS) + 1;
+
+
+  /**
+   * %TBD% Doc
+   *
+   * NEEDSDOC @param dtm
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public abstract int getDTMIdentity(DTM dtm);
+
+  /**
+   * %TBD% Doc
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public int getDTMIdentityMask()
+  {
+    return IDENT_DTM_DEFAULT;
+  }
+
+  /**
+   * %TBD% Doc
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public int getNodeIdentityMask()
+  {
+    return IDENT_NODE_DEFAULT;
+  }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/DTMWSFilter.java b/src/main/java/org/apache/xml/dtm/DTMWSFilter.java
new file mode 100644
index 0000000..7a16fe1
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/DTMWSFilter.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMWSFilter.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm;
+
+/**
+ * This interface is meant to be implemented by a client of the DTM, and allows
+ * stripping of whitespace nodes.
+ */
+public interface DTMWSFilter
+{
+  /**
+   * Do not strip whitespace child nodes of this element.
+   */
+  public static final short NOTSTRIP = 1;
+
+  /**
+   * Strip whitespace child nodes of this element.
+   */
+  public static final short STRIP = 2;
+
+  /**
+   * Inherit whitespace stripping behavior of the parent node.
+   */
+  public static final short INHERIT = 3;
+
+  /**
+   * Test whether whitespace-only text nodes are visible in the logical 
+   * view of <code>DTM</code>. Normally, this function
+   * will be called by the implementation of <code>DTM</code>; 
+   * it is not normally called directly from
+   * user code.
+   * 
+   * @param elementHandle int Handle of the element.
+   * @return one of NOTSTRIP, STRIP, or INHERIT.
+   */
+  public short getShouldStripSpace(int elementHandle, DTM dtm);
+  
+}
diff --git a/src/main/java/org/apache/xml/dtm/ObjectFactory.java b/src/main/java/org/apache/xml/dtm/ObjectFactory.java
new file mode 100755
index 0000000..09f308d
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ObjectFactory.java
@@ -0,0 +1,661 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectFactory.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id: ObjectFactory.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services/";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                FileInputStream fis = null;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        fis = ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                    }
+	        } catch (Exception x) {
+	            fXalanProperties = null;
+	            fLastModified = -1;
+                    // assert(x instanceof FileNotFoundException
+	            //        || x instanceof SecurityException)
+	            // In both cases, ignore and continue w/ next location
+	        }
+                finally {
+                    // try to close the input stream if one was opened.
+                    if (fis != null) {
+                        try {
+                            fis.close();
+                        }
+                        // Ignore the exception.
+                        catch (IOException exc) {}
+                    }
+                }	            
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            FileInputStream fis = null;
+            try {
+                fis = ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+            finally {
+                // try to close the input stream if one was opened.
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    }
+                    // Ignore the exception.
+                    catch (IOException exc) {}
+                }
+            }               
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+        finally {
+            try {
+                // try to close the reader.
+                rd.close();
+            }
+            // Ignore the exception.
+            catch (IOException exc) {}
+        }          
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = 5122054096615067992L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xml/dtm/SecuritySupport.java b/src/main/java/org/apache/xml/dtm/SecuritySupport.java
new file mode 100644
index 0000000..6ea002c
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/SecuritySupport.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xml/dtm/SecuritySupport12.java b/src/main/java/org/apache/xml/dtm/SecuritySupport12.java
new file mode 100644
index 0000000..7b083d0
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/SecuritySupport12.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/ChunkedIntArray.java b/src/main/java/org/apache/xml/dtm/ref/ChunkedIntArray.java
new file mode 100644
index 0000000..31517a7
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/ChunkedIntArray.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ChunkedIntArray.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+ 
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+/**
+ * <code>ChunkedIntArray</code> is an extensible array of blocks of integers.
+ * (I'd consider Vector, but it's unable to handle integers except by
+ * turning them into Objects.)
+
+ * <p>Making this a separate class means some call-and-return overhead. But
+ * doing it all inline tends to be fragile and expensive in coder time,
+ * not to mention driving up code size. If you want to inline it, feel free.
+ * The Java text suggest that private and Final methods may be inlined, 
+ * and one can argue that this beast need not be made subclassable...</p>
+ *
+ * <p>%REVIEW% This has strong conceptual overlap with the IntVector class.
+ * It would probably be a good thing to merge the two, when time permits.<p>
+ */
+final class ChunkedIntArray
+{
+  final int slotsize=4; // Locked, MUST be power of two in current code
+  // Debugging tip: Cranking lowbits down to 4 or so is a good
+  // way to pound on the array addressing code.
+  static final int lowbits=10; // How many bits address within chunks
+  static final int chunkalloc=1<<lowbits;
+  static final int lowmask=chunkalloc-1;
+  
+  ChunksVector chunks=new ChunksVector();
+  final int fastArray[] = new int[chunkalloc];
+  int lastUsed=0;
+
+  /**
+   * Create a new CIA with specified record size. Currently record size MUST
+   * be a power of two... and in fact is hardcoded to 4.
+   */
+  ChunkedIntArray(int slotsize)
+  {
+    if(this.slotsize<slotsize)
+      throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CHUNKEDINTARRAY_NOT_SUPPORTED, new Object[]{Integer.toString(slotsize)})); //"ChunkedIntArray("+slotsize+") not currently supported");
+    else if (this.slotsize>slotsize)
+      System.out.println("*****WARNING: ChunkedIntArray("+slotsize+") wasting "+(this.slotsize-slotsize)+" words per slot");
+    chunks.addElement(fastArray);
+  }
+  /**
+   * Append a 4-integer record to the CIA, starting with record 1. (Since
+   * arrays are initialized to all-0, 0 has been reserved as the "unknown"
+   * value in DTM.)
+   * @return the index at which this record was inserted.
+   */
+  int appendSlot(int w0, int w1, int w2, int w3)
+  {
+    /*
+    try
+    {
+      int newoffset = (lastUsed+1)*slotsize;
+      fastArray[newoffset] = w0;
+      fastArray[newoffset+1] = w1;
+      fastArray[newoffset+2] = w2;
+      fastArray[newoffset+3] = w3;
+      return ++lastUsed;
+    }
+    catch(ArrayIndexOutOfBoundsException aioobe)
+    */
+    {
+      final int slotsize=4;
+      int newoffset = (lastUsed+1)*slotsize;
+      int chunkpos = newoffset >> lowbits;
+      int slotpos = (newoffset & lowmask);
+
+      // Grow if needed
+      if (chunkpos > chunks.size() - 1)
+        chunks.addElement(new int[chunkalloc]);
+      int[] chunk = chunks.elementAt(chunkpos);
+      chunk[slotpos] = w0;
+      chunk[slotpos+1] = w1;
+      chunk[slotpos+2] = w2;
+      chunk[slotpos+3] = w3;
+
+      return ++lastUsed;
+    }
+  }
+  /**
+   * Retrieve an integer from the CIA by record number and column within
+   * the record, both 0-based (though position 0 is reserved for special
+   * purposes).
+   * @param position int Record number
+   * @param slotpos int Column number
+   */
+  int readEntry(int position, int offset) throws ArrayIndexOutOfBoundsException
+  {
+    /*
+    try
+    {
+      return fastArray[(position*slotsize)+offset];
+    }
+    catch(ArrayIndexOutOfBoundsException aioobe)
+    */
+    {
+      // System.out.println("Using slow read (1)");
+      if (offset>=slotsize)
+        throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot");
+      position*=slotsize;
+      int chunkpos = position >> lowbits;
+      int slotpos = position & lowmask;
+      int[] chunk = chunks.elementAt(chunkpos);
+      return chunk[slotpos + offset];
+    }
+  }
+  
+  // Check that the node at index "position" is not an ancestor
+  // of the node at index "startPos". IF IT IS, DO NOT ACCEPT IT AND
+  // RETURN -1. If position is NOT an ancestor, return position.
+  // Special case: The Document node (position==0) is acceptable.
+  //
+  // This test supports DTM.getNextPreceding.
+  int specialFind(int startPos, int position)
+  {
+          // We have to look all the way up the ancestor chain
+          // to make sure we don't have an ancestor.
+          int ancestor = startPos;
+          while(ancestor > 0)
+          {
+                // Get the node whose index == ancestor
+                ancestor*=slotsize;
+                int chunkpos = ancestor >> lowbits;
+                int slotpos = ancestor & lowmask;
+                int[] chunk = chunks.elementAt(chunkpos);
+                                                        
+                // Get that node's parent (Note that this assumes w[1]
+                // is the parent node index. That's really a DTM feature
+                // rather than a ChunkedIntArray feature.)
+                ancestor = chunk[slotpos + 1];
+
+                if(ancestor == position)
+                         break;
+          }
+
+          if (ancestor <= 0) 
+          {
+                  return position;
+          }
+          return -1;
+  }
+  
+  /**
+   * @return int index of highest-numbered record currently in use
+   */
+  int slotsUsed()
+  {
+    return lastUsed;
+  }
+
+  /** Disard the highest-numbered record. This is used in the string-buffer
+   CIA; when only a single characters() chunk has been recieved, its index
+   is moved into the Text node rather than being referenced by indirection
+   into the text accumulator.
+   */
+  void discardLast()
+  {
+    --lastUsed;
+  }
+
+  /**
+   * Overwrite the integer found at a specific record and column.
+   * Used to back-patch existing records, most often changing their
+   * "next sibling" reference from 0 (unknown) to something meaningful
+   * @param position int Record number
+   * @param offset int Column number
+   * @param value int New contents
+   */
+  void writeEntry(int position, int offset, int value) throws ArrayIndexOutOfBoundsException
+  {
+    /*
+    try
+    {
+      fastArray[( position*slotsize)+offset] = value;
+    }
+    catch(ArrayIndexOutOfBoundsException aioobe)
+    */
+    {
+      if (offset >= slotsize)
+        throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot");
+      position*=slotsize;
+      int chunkpos = position >> lowbits;
+      int slotpos = position & lowmask;
+      int[] chunk = chunks.elementAt(chunkpos);
+      chunk[slotpos + offset] = value; // ATOMIC!
+    }
+  }
+
+  /**
+   * Overwrite an entire (4-integer) record at the specified index.
+   * Mostly used to create record 0, the Document node.
+   * @param position integer Record number
+   * @param w0 int 
+   * @param w1 int
+   * @param w2 int
+   * @param w3 int
+   */
+  void writeSlot(int position, int w0, int w1, int w2, int w3)
+  {
+      position *= slotsize;
+      int chunkpos = position >> lowbits;
+      int slotpos = (position & lowmask);
+
+    // Grow if needed
+    if (chunkpos > chunks.size() - 1)
+      chunks.addElement(new int[chunkalloc]);
+    int[] chunk = chunks.elementAt(chunkpos);
+    chunk[slotpos] = w0;
+    chunk[slotpos + 1] = w1;
+    chunk[slotpos + 2] = w2;
+    chunk[slotpos + 3] = w3;
+  }
+
+  /**
+   * Retrieve the contents of a record into a user-supplied buffer array.
+   * Used to reduce addressing overhead when code will access several
+   * columns of the record.
+   * @param position int Record number
+   * @param buffer int[] Integer array provided by user, must be large enough
+   * to hold a complete record.
+   */
+  void readSlot(int position, int[] buffer)
+  {
+    /*
+    try
+    {
+      System.arraycopy(fastArray, position*slotsize, buffer, 0, slotsize);
+    }
+    catch(ArrayIndexOutOfBoundsException aioobe)
+    */
+    {
+      // System.out.println("Using slow read (2): "+position);
+      position *= slotsize;
+      int chunkpos = position >> lowbits;
+      int slotpos = (position & lowmask);
+
+      // Grow if needed
+      if (chunkpos > chunks.size() - 1)
+        chunks.addElement(new int[chunkalloc]);
+      int[] chunk = chunks.elementAt(chunkpos);
+      System.arraycopy(chunk,slotpos,buffer,0,slotsize);
+    }
+  }
+
+  class ChunksVector
+  {
+    final int BLOCKSIZE = 64;
+    int[] m_map[] = new int[BLOCKSIZE][];
+    int m_mapSize = BLOCKSIZE;
+    int pos = 0;
+    
+    ChunksVector()
+    {
+    }
+    
+    final int size()
+    {
+      return pos;
+    }
+    
+    void addElement(int[] value)
+    {
+      if(pos >= m_mapSize)
+      {
+        int orgMapSize = m_mapSize;
+        while(pos >= m_mapSize)
+          m_mapSize+=BLOCKSIZE;
+        int[] newMap[] = new int[m_mapSize][];
+        System.arraycopy(m_map, 0, newMap, 0, orgMapSize);
+        m_map = newMap;
+      }
+      // For now, just do a simple append.  A sorted insert only 
+      // makes sense if we're doing an binary search or some such.
+      m_map[pos] = value;
+      pos++;
+    }
+    
+    final int[] elementAt(int pos)
+    {
+      return m_map[pos];
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/CoroutineManager.java b/src/main/java/org/apache/xml/dtm/ref/CoroutineManager.java
new file mode 100644
index 0000000..d353149
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/CoroutineManager.java
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: CoroutineManager.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import java.util.BitSet;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+
+/**
+ * <p>Support the coroutine design pattern.</p>
+ * 
+ * <p>A coroutine set is a very simple cooperative non-preemptive
+ * multitasking model, where the switch from one task to another is
+ * performed via an explicit request. Coroutines interact according to
+ * the following rules:</p>
+ *
+ * <ul>
+ * <li>One coroutine in the set has control, which it retains until it
+ * either exits or resumes another coroutine.</li>
+ * <li>A coroutine is activated when it is resumed by some other coroutine
+ * for the first time.</li>
+ * <li>An active coroutine that gives up control by resuming another in
+ * the set retains its context -- including call stack and local variables
+ * -- so that if/when it is resumed, it will proceed from the point at which
+ * it last gave up control.</li>
+ * </ul>
+ *
+ * <p>Coroutines can be thought of as falling somewhere between pipes and
+ * subroutines. Like call/return, there is an explicit flow of control
+ * from one coroutine to another. Like pipes, neither coroutine is
+ * actually "in charge", and neither must exit in order to transfer
+ * control to the other. </p>
+ * 
+ * <p>One classic application of coroutines is in compilers, where both
+ * the parser and the lexer are maintaining complex state
+ * information. The parser resumes the lexer to process incoming
+ * characters into lexical tokens, and the lexer resumes the parser
+ * when it has reached a point at which it has a reliably interpreted
+ * set of tokens available for semantic processing. Structuring this
+ * as call-and-return would require saving and restoring a
+ * considerable amount of state each time. Structuring it as two tasks
+ * connected by a queue may involve higher overhead (in systems which
+ * can optimize the coroutine metaphor), isn't necessarily as clear in
+ * intent, may have trouble handling cases where data flows in both
+ * directions, and may not handle some of the more complex cases where
+ * more than two coroutines are involved.</p>
+ * 
+ * <p>Most coroutine systems also provide a way to pass data between the
+ * source and target of a resume operation; this is sometimes referred
+ * to as "yielding" a value.  Others rely on the fact that, since only
+ * one member of a coroutine set is running at a time and does not
+ * lose control until it chooses to do so, data structures may be
+ * directly shared between them with only minimal precautions.</p>
+ * 
+ * <p>"Note: This should not be taken to mean that producer/consumer
+ * problems should be always be done with coroutines." Queueing is
+ * often a better solution when only two threads of execution are
+ * involved and full two-way handshaking is not required. It's a bit
+ * difficult to find short pedagogical examples that require
+ * coroutines for a clear solution.</p>
+ * 
+ * <p>The fact that only one of a group of coroutines is running at a
+ * time, and the control transfer between them is explicit, simplifies
+ * their possible interactions, and in some implementations permits
+ * them to be implemented more efficiently than general multitasking.
+ * In some situations, coroutines can be compiled out entirely;
+ * in others, they may only require a few instructions more than a
+ * simple function call.</p>
+ *
+ * <p>This version is built on top of standard Java threading, since
+ * that's all we have available right now. It's been encapsulated for
+ * code clarity and possible future optimization.</p>
+ * 
+ * <p>(Two possible approaches: wait-notify based and queue-based. Some
+ * folks think that a one-item queue is a cleaner solution because it's
+ * more abstract -- but since coroutine _is_ an abstraction I'm not really
+ * worried about that; folks should be able to switch this code without
+ * concern.)</p>
+ * 
+ * <p>%TBD% THIS SHOULD BE AN INTERFACE, to facilitate building other
+ * implementations... perhaps including a true coroutine system
+ * someday, rather than controlled threading. Arguably Coroutine
+ * itself should be an interface much like Runnable, but I think that
+ * can be built on top of this.</p>
+ * */
+public class CoroutineManager
+{
+  /** "Is this coroutine ID number already in use" lookup table.
+   * Currently implemented as a bitset as a compromise between
+   * compactness and speed of access, but obviously other solutions
+   * could be applied.
+   * */
+  BitSet m_activeIDs=new BitSet();
+
+  /** Limit on the coroutine ID numbers accepted. I didn't want the
+   * in-use table to grow without bound. If we switch to a more efficient
+   * sparse-array mechanism, it may be possible to raise or eliminate
+   * this boundary.
+   * @xsl.usage internal
+   */
+  static final int m_unreasonableId=1024;
+
+  /** Internal field used to hold the data being explicitly passed
+   * from one coroutine to another during a co_resume() operation.
+   * (Of course implicit data sharing may also occur; one of the reasons
+   * for using coroutines is that you're guaranteed that none of the
+   * other coroutines in your set are using shared structures at the time
+   * you access them.)
+   *
+   * %REVIEW% It's been proposed that we be able to pass types of data
+   * other than Object -- more specific object types, or
+   * lighter-weight primitives.  This would seem to create a potential
+   * explosion of "pass x recieve y back" methods (or require
+   * fracturing resume into two calls, resume-other and
+   * wait-to-be-resumed), and the weight issue could be managed by
+   * reusing a mutable buffer object to contain the primitive
+   * (remember that only one coroutine runs at a time, so once the
+   * buffer's set it won't be walked on). Typechecking objects is
+   * interesting from a code-robustness point of view, but it's
+   * unclear whether it makes sense to encapsulate that in the
+   * coroutine code or let the callers do it, since it depends on RTTI
+   * either way. Restricting the parameters to objects implementing a
+   * specific CoroutineParameter interface does _not_ seem to be a net
+   * win; applications can do so if they want via front-end code, but
+   * there seem to be too many use cases involving passing an existing
+   * object type that you may not have the freedom to alter and may
+   * not want to spend time wrapping another object around.
+   * */
+  Object m_yield=null;
+
+  // Expose???
+  final static int NOBODY=-1;
+  final static int ANYBODY=-1;
+
+  /** Internal field used to confirm that the coroutine now waking up is
+   * in fact the one we intended to resume. Some such selection mechanism
+   * is needed when more that two coroutines are operating within the same
+   * group.
+   */
+  int m_nextCoroutine=NOBODY;
+  
+  /** <p>Each coroutine in the set managed by a single
+   * CoroutineManager is identified by a small positive integer. This
+   * brings up the question of how to manage those integers to avoid
+   * reuse... since if two coroutines use the same ID number, resuming
+   * that ID could resume either. I can see arguments for either
+   * allowing applications to select their own numbers (they may want
+   * to declare mnemonics via manefest constants) or generating
+   * numbers on demand.  This routine's intended to support both
+   * approaches.</p>
+   *
+   * <p>%REVIEW% We could use an object as the identifier. Not sure
+   * it's a net gain, though it would allow the thread to be its own
+   * ID. Ponder.</p>
+   *
+   * @param coroutineID  If >=0, requests that we reserve this number.
+   * If <0, requests that we find, reserve, and return an available ID
+   * number.
+   *
+   * @return If >=0, the ID number to be used by this coroutine. If <0,
+   * an error occurred -- the ID requested was already in use, or we
+   * couldn't assign one without going over the "unreasonable value" mark
+   * */
+  public synchronized int co_joinCoroutineSet(int coroutineID)
+  {
+    if(coroutineID>=0)
+      {
+        if(coroutineID>=m_unreasonableId || m_activeIDs.get(coroutineID))
+          return -1;
+      }
+    else
+      {
+        // What I want is "Find first clear bit". That doesn't exist.
+        // JDK1.2 added "find last set bit", but that doesn't help now.
+        coroutineID=0;
+        while(coroutineID<m_unreasonableId)
+          {
+            if(m_activeIDs.get(coroutineID))
+              ++coroutineID;
+            else
+              break;
+          }
+        if(coroutineID>=m_unreasonableId)
+          return -1;
+      }
+
+    m_activeIDs.set(coroutineID);
+    return coroutineID;
+  }
+
+  /** In the standard coroutine architecture, coroutines are
+   * identified by their method names and are launched and run up to
+   * their first yield by simply resuming them; its's presumed that
+   * this recognizes the not-already-running case and does the right
+   * thing. We seem to need a way to achieve that same threadsafe
+   * run-up...  eg, start the coroutine with a wait.
+   *
+   * %TBD% whether this makes any sense...
+   *
+   * @param thisCoroutine the identifier of this coroutine, so we can
+   * recognize when we are being resumed.
+   * @exception java.lang.NoSuchMethodException if thisCoroutine isn't
+   * a registered member of this group. %REVIEW% whether this is the
+   * best choice.
+   * */
+  public synchronized Object co_entry_pause(int thisCoroutine) throws java.lang.NoSuchMethodException
+  {
+    if(!m_activeIDs.get(thisCoroutine))
+      throw new java.lang.NoSuchMethodException();
+
+    while(m_nextCoroutine != thisCoroutine)
+      {
+        try 
+          {
+            wait();
+          }
+        catch(java.lang.InterruptedException e)
+          {
+            // %TBD% -- Declare? Encapsulate? Ignore? Or
+            // dance widdershins about the instruction cache?
+          }
+      }
+    
+    return m_yield;
+  }
+
+  /** Transfer control to another coroutine which has already been started and
+   * is waiting on this CoroutineManager. We won't return from this call
+   * until that routine has relinquished control.
+   *
+   * %TBD% What should we do if toCoroutine isn't registered? Exception?
+   *
+   * @param arg_object A value to be passed to the other coroutine.
+   * @param thisCoroutine Integer identifier for this coroutine. This is the
+   * ID we watch for to see if we're the ones being resumed.
+   * @param toCoroutine  Integer identifier for the coroutine we wish to
+   * invoke. 
+   * @exception java.lang.NoSuchMethodException if toCoroutine isn't a
+   * registered member of this group. %REVIEW% whether this is the best choice.
+   * */
+  public synchronized Object co_resume(Object arg_object,int thisCoroutine,int toCoroutine) throws java.lang.NoSuchMethodException
+  {
+    if(!m_activeIDs.get(toCoroutine))
+      throw new java.lang.NoSuchMethodException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COROUTINE_NOT_AVAIL, new Object[]{Integer.toString(toCoroutine)})); //"Coroutine not available, id="+toCoroutine);
+
+    // We expect these values to be overwritten during the notify()/wait()
+    // periods, as other coroutines in this set get their opportunity to run.
+    m_yield=arg_object;
+    m_nextCoroutine=toCoroutine;
+
+    notify();
+    while(m_nextCoroutine != thisCoroutine || m_nextCoroutine==ANYBODY || m_nextCoroutine==NOBODY)
+      {
+        try 
+          {
+            // System.out.println("waiting...");
+            wait();
+          }
+        catch(java.lang.InterruptedException e)
+          {
+            // %TBD% -- Declare? Encapsulate? Ignore? Or
+            // dance deasil about the program counter?
+          }
+      }
+
+    if(m_nextCoroutine==NOBODY)
+      {
+        // Pass it along
+        co_exit(thisCoroutine);
+        // And inform this coroutine that its partners are Going Away
+        // %REVIEW% Should this throw/return something more useful?
+        throw new java.lang.NoSuchMethodException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COROUTINE_CO_EXIT, null)); //"CoroutineManager recieved co_exit() request");
+      }
+    
+    return m_yield;
+  }
+  
+  /** Terminate this entire set of coroutines. The others will be
+   * deregistered and have exceptions thrown at them. Note that this
+   * is intended as a panic-shutdown operation; under normal
+   * circumstances a coroutine should always end with co_exit_to() in
+   * order to politely inform at least one of its partners that it is
+   * going away.
+   *
+   * %TBD% This may need significantly more work. 
+   *
+   * %TBD% Should this just be co_exit_to(,,CoroutineManager.PANIC)?
+   *
+   * @param thisCoroutine Integer identifier for the coroutine requesting exit.
+   * */
+  public synchronized void co_exit(int thisCoroutine)
+  {
+    m_activeIDs.clear(thisCoroutine);
+    m_nextCoroutine=NOBODY; // %REVIEW%
+    notify();
+  }
+
+  /** Make the ID available for reuse and terminate this coroutine,
+   * transferring control to the specified coroutine. Note that this
+   * returns immediately rather than waiting for any further coroutine
+   * traffic, so the thread can proceed with other shutdown activities.
+   *
+   * @param arg_object    A value to be passed to the other coroutine.
+   * @param thisCoroutine Integer identifier for the coroutine leaving the set.
+   * @param toCoroutine   Integer identifier for the coroutine we wish to
+   * invoke. 
+   * @exception java.lang.NoSuchMethodException if toCoroutine isn't a
+   * registered member of this group. %REVIEW% whether this is the best choice.
+   * */
+  public synchronized void co_exit_to(Object arg_object,int thisCoroutine,int toCoroutine) throws java.lang.NoSuchMethodException
+  {
+    if(!m_activeIDs.get(toCoroutine))
+      throw new java.lang.NoSuchMethodException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COROUTINE_NOT_AVAIL, new Object[]{Integer.toString(toCoroutine)})); //"Coroutine not available, id="+toCoroutine);
+    
+    // We expect these values to be overwritten during the notify()/wait()
+    // periods, as other coroutines in this set get their opportunity to run.
+    m_yield=arg_object;
+    m_nextCoroutine=toCoroutine;
+
+    m_activeIDs.clear(thisCoroutine);
+
+    notify();
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMAxisIterNodeList.java b/src/main/java/org/apache/xml/dtm/ref/DTMAxisIterNodeList.java
new file mode 100644
index 0000000..d4acca4
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMAxisIterNodeList.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMAxisIterNodeList.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisIterator;
+import org.apache.xml.utils.IntVector;
+
+import org.w3c.dom.Node;
+
+/**
+ * <code>DTMAxisNodeList</code> gives us an implementation of the DOM's
+ * NodeList interface wrapped around a DTM Iterator. The author
+ * considers this something of an abominations, since NodeList was not
+ * intended to be a general purpose "list of nodes" API and is
+ * generally considered by the DOM WG to have be a mistake... but I'm
+ * told that some of the XPath/XSLT folks say they must have this
+ * solution.
+ *
+ * Please note that this is not necessarily equivlaent to a DOM
+ * NodeList operating over the same document. In particular:
+ * <ul>
+ *
+ * <li>If there are several Text nodes in logical succession (ie,
+ * across CDATASection and EntityReference boundaries), we will return
+ * only the first; the caller is responsible for stepping through
+ * them.
+ * (%REVIEW% Provide a convenience routine here to assist, pending
+ * proposed DOM Level 3 getAdjacentText() operation?) </li>
+ *
+ * <li>Since the whole XPath/XSLT architecture assumes that the source
+ * document is not altered while we're working with it, we do not
+ * promise to implement the DOM NodeList's "live view" response to
+ * document mutation. </li>
+ *
+ * </ul>
+ *
+ * <p>State: In progress!!</p>
+ * */
+public class DTMAxisIterNodeList extends DTMNodeListBase {
+    private DTM m_dtm;
+    private DTMAxisIterator m_iter;
+    private IntVector m_cachedNodes;
+    private int m_last = -1;
+    //================================================================
+    // Methods unique to this class
+    private DTMAxisIterNodeList() {
+    }
+
+    /**
+     * Public constructor: Wrap a DTMNodeList around an existing
+     * and preconfigured DTMAxisIterator
+     */
+    public DTMAxisIterNodeList(DTM dtm, DTMAxisIterator dtmAxisIterator) {
+        if (dtmAxisIterator == null) {
+            m_last = 0;
+        } else {
+            m_cachedNodes = new IntVector();
+            m_dtm = dtm;
+        }
+        m_iter = dtmAxisIterator;
+    }
+
+    /**
+     * Access the wrapped DTMIterator. I'm not sure whether anyone will
+     * need this or not, but let's write it and think about it.
+     *
+     */
+    public DTMAxisIterator getDTMAxisIterator() {
+        return m_iter;
+    }
+  
+
+    //================================================================
+    // org.w3c.dom.NodeList API follows
+
+    /**
+     * Returns the <code>index</code>th item in the collection. If 
+     * <code>index</code> is greater than or equal to the number of nodes in 
+     * the list, this returns <code>null</code>.
+     * @param index Index into the collection.
+     * @return The node at the <code>index</code>th position in the 
+     *   <code>NodeList</code>, or <code>null</code> if that is not a valid 
+     *   index.
+     */
+    public Node item(int index) {
+        if (m_iter != null) {
+            int node;
+            int count = m_cachedNodes.size();
+
+            if (count > index) {
+                node = m_cachedNodes.elementAt(index);
+                return m_dtm.getNode(node);
+            } else if (m_last == -1) {
+                while (((node = m_iter.next()) != DTMAxisIterator.END)
+                           && count <= index) {
+                    m_cachedNodes.addElement(node);
+                    count++;
+                }
+                if (node == DTMAxisIterator.END) {
+                    m_last = count;
+                } else {
+                    return m_dtm.getNode(node);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The number of nodes in the list. The range of valid child node indices 
+     * is 0 to <code>length-1</code> inclusive. 
+     */
+    public int getLength() {
+        if (m_last == -1) {
+            int node;
+            while ((node = m_iter.next()) != DTMAxisIterator.END) {
+                m_cachedNodes.addElement(node);
+            }
+            m_last = m_cachedNodes.size();
+        }
+        return m_last;
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMAxisIteratorBase.java b/src/main/java/org/apache/xml/dtm/ref/DTMAxisIteratorBase.java
new file mode 100644
index 0000000..99c176b
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMAxisIteratorBase.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMAxisIteratorBase.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTMAxisIterator;
+
+/**
+ * This class serves as a default base for implementations of mutable
+ * DTMAxisIterators.
+ */
+public abstract class DTMAxisIteratorBase implements DTMAxisIterator
+{
+
+  /** The position of the last node within the iteration, as defined by XPath.
+   * Note that this is _not_ the node's handle within the DTM. Also, don't
+   * confuse it with the current (most recently returned) position.
+   */
+  protected int _last = -1;
+
+  /** The position of the current node within the iteration, as defined by XPath.
+   * Note that this is _not_ the node's handle within the DTM!
+   */
+  protected int _position = 0;
+
+  /** The position of the marked node within the iteration;
+   * a saved itaration state that we may want to come back to.
+   * Note that only one mark is maintained; there is no stack.
+   */
+  protected int _markedNode;
+
+  /** The handle to the start, or root, of the iteration.
+   * Set this to END to construct an empty iterator.
+   */
+  protected int _startNode = DTMAxisIterator.END;
+
+  /** True if the start node should be considered part of the iteration.
+   * False will cause it to be skipped.
+   */
+  protected boolean _includeSelf = false;
+
+  /** True if this iteration can be restarted. False otherwise (eg, if
+   * we are iterating over a stream that can not be re-scanned, or if
+   * the iterator was produced by cloning another iterator.)
+   */
+  protected boolean _isRestartable = true;
+  
+  /**
+   * Get start to END should 'close' the iterator,
+   * i.e. subsequent call to next() should return END.
+   *
+   * @return The root node of the iteration.
+   */
+  public int getStartNode()
+  {
+    return _startNode;
+  }
+
+  /**
+   * @return A DTMAxisIterator which has been reset to the start node,
+   * which may or may not be the same as this iterator.
+   * */
+  public DTMAxisIterator reset()
+  {
+
+    final boolean temp = _isRestartable;
+
+    _isRestartable = true;
+
+    setStartNode(_startNode);
+
+    _isRestartable = temp;
+
+    return this;
+  }
+
+  /**
+   * Set the flag to include the start node in the iteration. 
+   *
+   *
+   * @return This default method returns just returns this DTMAxisIterator,
+   * after setting the flag.
+   * (Returning "this" permits C++-style chaining of
+   * method calls into a single expression.)
+   */
+  public DTMAxisIterator includeSelf()
+  {
+
+    _includeSelf = true;
+
+    return this;
+  }
+
+  /** Returns the position of the last node within the iteration, as
+   * defined by XPath.  In a forward iterator, I believe this equals the number of nodes which this
+   * iterator will yield. In a reverse iterator, I believe it should return
+   * 1 (since the "last" is the first produced.)
+   *
+   * This may be an expensive operation when called the first time, since
+   * it may have to iterate through a large part of the document to produce
+   * its answer.
+   *
+   * @return The number of nodes in this iterator (forward) or 1 (reverse).
+   */
+  public int getLast()
+  {
+
+    if (_last == -1)		// Not previously established
+    {
+      // Note that we're doing both setMark() -- which saves _currentChild
+      // -- and explicitly saving our position counter (number of nodes
+      // yielded so far).
+      //
+      // %REVIEW% Should position also be saved by setMark()?
+      // (It wasn't in the XSLTC version, but I don't understand why not.)
+
+      final int temp = _position; // Save state
+      setMark();
+
+      reset();			// Count the nodes found by this iterator
+      do
+      {
+        _last++;
+      }
+      while (next() != END);
+
+      gotoMark();		// Restore saved state
+      _position = temp;
+    }
+
+    return _last;
+  }
+
+  /**
+   * @return The position of the current node within the set, as defined by
+   * XPath. Note that this is one-based, not zero-based.
+   */
+  public int getPosition()
+  {
+    return _position == 0 ? 1 : _position;
+  }
+
+  /**
+   * @return true if this iterator has a reversed axis, else false
+   */
+  public boolean isReverse()
+  {
+    return false;
+  }
+
+  /**
+   * Returns a deep copy of this iterator. Cloned iterators may not be
+   * restartable. The iterator being cloned may or may not become
+   * non-restartable as a side effect of this operation.
+   *
+   * @return a deep copy of this iterator.
+   */
+  public DTMAxisIterator cloneIterator()
+  {
+
+    try
+    {
+      final DTMAxisIteratorBase clone = (DTMAxisIteratorBase) super.clone();
+
+      clone._isRestartable = false;
+
+      // return clone.reset();
+      return clone;
+    }
+    catch (CloneNotSupportedException e)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(e);
+    }
+  }
+
+  /**
+   * Do any final cleanup that is required before returning the node that was
+   * passed in, and then return it. The intended use is
+   * <br />
+   * <code>return returnNode(node);</code>
+   *
+   * %REVIEW% If we're calling it purely for side effects, should we really
+   * be bothering with a return value? Something like
+   * <br />
+   * <code> accept(node); return node; </code>
+   * <br />
+   * would probably optimize just about as well and avoid questions
+   * about whether what's returned could ever be different from what's
+   * passed in.
+   *
+   * @param node Node handle which iteration is about to yield.
+   *
+   * @return The node handle passed in.  */
+  protected final int returnNode(final int node)
+  {
+    _position++;
+
+    return node;
+  }
+
+  /**
+   * Reset the position to zero. NOTE that this does not change the iteration
+   * state, only the position number associated with that state.
+   *
+   * %REVIEW% Document when this would be used?
+   *
+   * @return This instance.
+   */
+  protected final DTMAxisIterator resetPosition()
+  {
+
+    _position = 0;
+
+    return this;
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return true;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return -1;
+  }
+  
+  public void setRestartable(boolean isRestartable) {
+    _isRestartable = isRestartable;
+  }  
+
+  /**
+   * Return the node at the given position.
+   * 
+   * @param position The position
+   * @return The node at the given position.
+   */
+  public int getNodeByPosition(int position)
+  {
+    if (position > 0) {
+      final int pos = isReverse() ? getLast() - position + 1
+                                   : position;
+      int node;
+      while ((node = next()) != DTMAxisIterator.END) {
+        if (pos == getPosition()) {
+          return node;
+        }
+      }
+    }
+    return END;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMChildIterNodeList.java b/src/main/java/org/apache/xml/dtm/ref/DTMChildIterNodeList.java
new file mode 100644
index 0000000..29104db
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMChildIterNodeList.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMChildIterNodeList.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+import org.w3c.dom.Node;
+
+/**
+ * <code>DTMNodeList</code> gives us an implementation of the DOM's
+ * NodeList interface wrapped around a DTM Iterator. The author
+ * considers this something of an abominations, since NodeList was not
+ * intended to be a general purpose "list of nodes" API and is
+ * generally considered by the DOM WG to have be a mistake... but I'm
+ * told that some of the XPath/XSLT folks say they must have this
+ * solution.
+ *
+ * Please note that this is not necessarily equivlaent to a DOM
+ * NodeList operating over the same document. In particular:
+ * <ul>
+ *
+ * <li>If there are several Text nodes in logical succession (ie,
+ * across CDATASection and EntityReference boundaries), we will return
+ * only the first; the caller is responsible for stepping through
+ * them.
+ * (%REVIEW% Provide a convenience routine here to assist, pending
+ * proposed DOM Level 3 getAdjacentText() operation?) </li>
+ *
+ * <li>Since the whole XPath/XSLT architecture assumes that the source
+ * document is not altered while we're working with it, we do not
+ * promise to implement the DOM NodeList's "live view" response to
+ * document mutation. </li>
+ *
+ * </ul>
+ *
+ * <p>State: In progress!!</p>
+ * */
+public class DTMChildIterNodeList extends DTMNodeListBase {
+    private int m_firstChild;
+    private DTM m_parentDTM;
+
+    //================================================================
+    // Methods unique to this class
+    private DTMChildIterNodeList() {
+    }
+
+    /**
+     * Public constructor: Create a NodeList to support
+     * DTMNodeProxy.getChildren().
+     *
+     * Unfortunately AxisIterators and DTMIterators don't share an API,
+     * so I can't use the existing Axis.CHILD iterator. Rather than
+     * create Yet Another Class, let's set up a special case of this
+     * one.
+     *
+     * @param parentDTM The DTM containing this node
+     * @param parentHandle DTM node-handle integer
+     *
+     */
+    public DTMChildIterNodeList(DTM parentDTM,int parentHandle) {
+        m_parentDTM=parentDTM;
+        m_firstChild=parentDTM.getFirstChild(parentHandle);
+    }
+
+
+    //================================================================
+    // org.w3c.dom.NodeList API follows
+
+    /**
+     * Returns the <code>index</code>th item in the collection. If 
+     * <code>index</code> is greater than or equal to the number of nodes in 
+     * the list, this returns <code>null</code>.
+     * @param index Index into the collection.
+     * @return The node at the <code>index</code>th position in the 
+     *   <code>NodeList</code>, or <code>null</code> if that is not a valid 
+     *   index.
+     */
+    public Node item(int index) {
+        int handle=m_firstChild;
+        while(--index>=0 && handle!=DTM.NULL) {
+            handle=m_parentDTM.getNextSibling(handle);
+        }
+        if (handle == DTM.NULL) {
+            return null;
+        }
+        return m_parentDTM.getNode(handle);
+    }
+
+    /**
+     * The number of nodes in the list. The range of valid child node indices 
+     * is 0 to <code>length-1</code> inclusive. 
+     */
+    public int getLength() {
+        int count=0;
+        for (int handle=m_firstChild;
+             handle!=DTM.NULL;
+             handle=m_parentDTM.getNextSibling(handle)) {
+            ++count;
+        }
+        return count;
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBase.java b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBase.java
new file mode 100644
index 0000000..d0647bf
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBase.java
@@ -0,0 +1,2371 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMDefaultBase.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.*;
+import org.apache.xml.utils.SuballocatedIntVector;
+import org.apache.xml.utils.BoolStack;
+
+import java.util.Vector;
+
+import javax.xml.transform.Source;
+
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.res.XMLErrorResources;
+
+import java.io.*; // for dumpDTM
+
+/**
+ * The <code>DTMDefaultBase</code> class serves as a helper base for DTMs.
+ * It sets up structures for navigation and type, while leaving data
+ * management and construction to the derived classes.
+ */
+public abstract class DTMDefaultBase implements DTM
+{
+    static final boolean JJK_DEBUG=false;
+
+  // This constant is likely to be removed in the future. Use the 
+  // getDocument() method instead of ROOTNODE to get at the root 
+  // node of a DTM.
+  /** The identity of the root node. */
+  public static final int ROOTNODE = 0;
+	
+  /**
+   * The number of nodes, which is also used to determine the next
+   *  node index.
+   */
+  protected int m_size = 0;
+
+  /** The expanded names, one array element for each node. */
+  protected SuballocatedIntVector m_exptype;
+
+  /** First child values, one array element for each node. */
+  protected SuballocatedIntVector m_firstch;
+
+  /** Next sibling values, one array element for each node. */
+  protected SuballocatedIntVector m_nextsib;
+
+  /** Previous sibling values, one array element for each node. */
+  protected SuballocatedIntVector m_prevsib;
+
+  /** Previous sibling values, one array element for each node. */
+  protected SuballocatedIntVector m_parent;
+
+  /** Vector of SuballocatedIntVectors of NS decl sets */
+  protected Vector m_namespaceDeclSets = null;
+
+  /** SuballocatedIntVector  of elements at which corresponding
+   * namespaceDeclSets were defined */
+  protected SuballocatedIntVector m_namespaceDeclSetElements = null;
+
+  /**
+   * These hold indexes to elements based on namespace and local name.
+   * The base lookup is the the namespace.  The second lookup is the local
+   * name, and the last array contains the the first free element
+   * at the start, and the list of element handles following.
+   */
+  protected int[][][] m_elemIndexes;
+
+  /** The default block size of the node arrays */
+  public static final int DEFAULT_BLOCKSIZE = 512;  // favor small docs.
+  
+  /** The number of blocks for the node arrays */
+  public static final int DEFAULT_NUMBLOCKS = 32;
+  
+  /** The number of blocks used for small documents & RTFs */
+  public static final int DEFAULT_NUMBLOCKS_SMALL = 4;
+  
+  /** The block size of the node arrays */
+  //protected final int m_blocksize;
+
+  /**
+   * The value to use when the information has not been built yet.
+   */
+  protected static final int NOTPROCESSED = DTM.NULL - 1;
+
+  /**
+   * The DTM manager who "owns" this DTM.
+   */
+
+  public DTMManager m_mgr;
+
+  /**
+   * m_mgr cast to DTMManagerDefault, or null if it isn't an instance
+   * (Efficiency hook)
+   */
+  protected DTMManagerDefault m_mgrDefault=null;
+
+
+  /** The document identity number(s). If we have overflowed the addressing
+   * range of the first that was assigned to us, we may add others. */
+  protected SuballocatedIntVector m_dtmIdent;
+
+  /** The mask for the identity.
+      %REVIEW% Should this really be set to the _DEFAULT? What if
+      a particular DTM wanted to use another value? */
+  //protected final static int m_mask = DTMManager.IDENT_NODE_DEFAULT;
+
+  /** The base URI for this document. */
+  protected String m_documentBaseURI;
+
+  /**
+   * The whitespace filter that enables elements to strip whitespace or not.
+   */
+  protected DTMWSFilter m_wsfilter;
+
+  /** Flag indicating whether to strip whitespace nodes */
+  protected boolean m_shouldStripWS = false;
+
+  /** Stack of flags indicating whether to strip whitespace nodes */
+  protected BoolStack m_shouldStripWhitespaceStack;
+
+  /** The XMLString factory for creating XMLStrings. */
+  protected XMLStringFactory m_xstrf;
+
+  /**
+   * The table for exandedNameID lookups.  This may or may not be the same
+   * table as is contained in the DTMManagerDefault.
+   */
+  protected ExpandedNameTable m_expandedNameTable;
+
+  /** true if indexing is turned on. */
+  protected boolean m_indexing;
+
+  /**
+   * Construct a DTMDefaultBase object using the default block size.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   */
+  public DTMDefaultBase(DTMManager mgr, Source source, int dtmIdentity,
+  			DTMWSFilter whiteSpaceFilter,
+  			XMLStringFactory xstringfactory, boolean doIndexing)
+  {
+    this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
+         doIndexing, DEFAULT_BLOCKSIZE, true, false);
+  }
+
+  /**
+   * Construct a DTMDefaultBase object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   * @param blocksize The block size of the DTM.
+   * @param usePrevsib true if we want to build the previous sibling node array.
+   * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
+   */
+  public DTMDefaultBase(DTMManager mgr, Source source, int dtmIdentity,
+                        DTMWSFilter whiteSpaceFilter,
+                        XMLStringFactory xstringfactory, boolean doIndexing,
+                        int blocksize, boolean usePrevsib,
+                        boolean newNameTable)
+  {    
+    // Use smaller sizes for the internal node arrays if the block size
+    // is small.
+    int numblocks;    
+    if (blocksize <= 64)
+    {
+      numblocks = DEFAULT_NUMBLOCKS_SMALL;
+      m_dtmIdent= new SuballocatedIntVector(4, 1);
+    }
+    else
+    {
+      numblocks = DEFAULT_NUMBLOCKS;
+      m_dtmIdent= new SuballocatedIntVector(32);
+    }
+    
+    m_exptype = new SuballocatedIntVector(blocksize, numblocks);
+    m_firstch = new SuballocatedIntVector(blocksize, numblocks);
+    m_nextsib = new SuballocatedIntVector(blocksize, numblocks);
+    m_parent  = new SuballocatedIntVector(blocksize, numblocks);
+    
+    // Only create the m_prevsib array if the usePrevsib flag is true.
+    // Some DTM implementations (e.g. SAXImpl) do not need this array.
+    // We can save the time to build it in those cases.
+    if (usePrevsib)
+      m_prevsib = new SuballocatedIntVector(blocksize, numblocks);
+
+    m_mgr = mgr;
+    if(mgr instanceof DTMManagerDefault)
+      m_mgrDefault=(DTMManagerDefault)mgr;
+    
+    m_documentBaseURI = (null != source) ? source.getSystemId() : null;
+    m_dtmIdent.setElementAt(dtmIdentity,0);
+    m_wsfilter = whiteSpaceFilter;
+    m_xstrf = xstringfactory;
+    m_indexing = doIndexing;
+
+    if (doIndexing)
+    {
+      m_expandedNameTable = new ExpandedNameTable();
+    }
+    else
+    {
+      // Note that this fails if we aren't talking to an instance of
+      // DTMManagerDefault
+      m_expandedNameTable = m_mgrDefault.getExpandedNameTable(this);
+    }
+
+    if (null != whiteSpaceFilter)
+    {
+      m_shouldStripWhitespaceStack = new BoolStack();
+
+      pushShouldStripWhitespace(false);
+    }
+  }
+
+  /**
+   * Ensure that the size of the element indexes can hold the information.
+   *
+   * @param namespaceID Namespace ID index.
+   * @param LocalNameID Local name ID.
+   */
+  protected void ensureSizeOfIndex(int namespaceID, int LocalNameID)
+  {
+
+    if (null == m_elemIndexes)
+    {
+      m_elemIndexes = new int[namespaceID + 20][][];
+    }
+    else if (m_elemIndexes.length <= namespaceID)
+    {
+      int[][][] indexes = m_elemIndexes;
+
+      m_elemIndexes = new int[namespaceID + 20][][];
+
+      System.arraycopy(indexes, 0, m_elemIndexes, 0, indexes.length);
+    }
+
+    int[][] localNameIndex = m_elemIndexes[namespaceID];
+
+    if (null == localNameIndex)
+    {
+      localNameIndex = new int[LocalNameID + 100][];
+      m_elemIndexes[namespaceID] = localNameIndex;
+    }
+    else if (localNameIndex.length <= LocalNameID)
+    {
+      int[][] indexes = localNameIndex;
+
+      localNameIndex = new int[LocalNameID + 100][];
+
+      System.arraycopy(indexes, 0, localNameIndex, 0, indexes.length);
+
+      m_elemIndexes[namespaceID] = localNameIndex;
+    }
+
+    int[] elemHandles = localNameIndex[LocalNameID];
+
+    if (null == elemHandles)
+    {
+      elemHandles = new int[128];
+      localNameIndex[LocalNameID] = elemHandles;
+      elemHandles[0] = 1;
+    }
+    else if (elemHandles.length <= elemHandles[0] + 1)
+    {
+      int[] indexes = elemHandles;
+
+      elemHandles = new int[elemHandles[0] + 1024];
+
+      System.arraycopy(indexes, 0, elemHandles, 0, indexes.length);
+
+      localNameIndex[LocalNameID] = elemHandles;
+    }
+  }
+
+  /**
+   * Add a node to the element indexes. The node will not be added unless
+   * it's an element.
+   *
+   * @param expandedTypeID The expanded type ID of the node.
+   * @param identity The node identity index.
+   */
+  protected void indexNode(int expandedTypeID, int identity)
+  {
+
+    ExpandedNameTable ent = m_expandedNameTable;
+    short type = ent.getType(expandedTypeID);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      int namespaceID = ent.getNamespaceID(expandedTypeID);
+      int localNameID = ent.getLocalNameID(expandedTypeID);
+
+      ensureSizeOfIndex(namespaceID, localNameID);
+
+      int[] index = m_elemIndexes[namespaceID][localNameID];
+
+      index[index[0]] = identity;
+
+      index[0]++;
+    }
+  }
+
+  /**
+   * Find the first index that occurs in the list that is greater than or
+   * equal to the given value.
+   *
+   * @param list A list of integers.
+   * @param start The start index to begin the search.
+   * @param len The number of items to search.
+   * @param value Find the slot that has a value that is greater than or
+   * identical to this argument.
+   *
+   * @return The index in the list of the slot that is higher or identical
+   * to the identity argument, or -1 if no node is higher or equal.
+   */
+  protected int findGTE(int[] list, int start, int len, int value)
+  {
+
+    int low = start;
+    int high = start + (len - 1);
+    int end = high;
+
+    while (low <= high)
+    {
+      int mid = (low + high) / 2;
+      int c = list[mid];
+
+      if (c > value)
+        high = mid - 1;
+      else if (c < value)
+        low = mid + 1;
+      else
+        return mid;
+    }
+
+    return (low <= end && list[low] > value) ? low : -1;
+  }
+
+  /**
+   * Find the first matching element from the index at or after the
+   * given node.
+   *
+   * @param nsIndex The namespace index lookup.
+   * @param lnIndex The local name index lookup.
+   * @param firstPotential The first potential match that is worth looking at.
+   *
+   * @return The first node that is greater than or equal to the
+   *         firstPotential argument, or DTM.NOTPROCESSED if not found.
+   */
+  int findElementFromIndex(int nsIndex, int lnIndex, int firstPotential)
+  {
+
+    int[][][] indexes = m_elemIndexes;
+
+    if (null != indexes && nsIndex < indexes.length)
+    {
+      int[][] lnIndexs = indexes[nsIndex];
+
+      if (null != lnIndexs && lnIndex < lnIndexs.length)
+      {
+        int[] elems = lnIndexs[lnIndex];
+
+        if (null != elems)
+        {
+          int pos = findGTE(elems, 1, elems[0], firstPotential);
+
+          if (pos > -1)
+          {
+            return elems[pos];
+          }
+        }
+      }
+    }
+
+    return NOTPROCESSED;
+  }
+
+  /**
+   * Get the next node identity value in the list, and call the iterator
+   * if it hasn't been added yet.
+   *
+   * @param identity The node identity (index).
+   * @return identity+1, or DTM.NULL.
+   */
+  protected abstract int getNextNodeIdentity(int identity);
+
+  /**
+   * This method should try and build one or more nodes in the table.
+   *
+   * @return The true if a next node is found or false if
+   *         there are no more nodes.
+   */
+  protected abstract boolean nextNode();
+
+  /**
+   * Get the number of nodes that have been added.
+   *
+   * @return the number of nodes that have been mapped.
+   */
+  protected abstract int getNumberOfNodes();
+
+  /** Stateless axis traversers, lazely built. */
+  protected DTMAxisTraverser[] m_traversers;
+
+//    /**
+//     * Ensure that the size of the information arrays can hold another entry
+//     * at the given index.
+//     *
+//     * @param index On exit from this function, the information arrays sizes must be
+//     * at least index+1.
+//     */
+//    protected void ensureSize(int index)
+//    {
+//        // We've cut over to Suballocated*Vector, which are self-sizing.
+//    }
+
+  /**
+   * Get the simple type ID for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The simple type ID, or DTM.NULL.
+   */
+  protected short _type(int identity)
+  {
+
+    int info = _exptype(identity);
+
+    if (NULL != info)
+      return m_expandedNameTable.getType(info);
+    else
+      return NULL;
+  }
+
+  /**
+   * Get the expanded type ID for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The expanded type ID, or DTM.NULL.
+   */
+  protected int _exptype(int identity)
+  {
+  	if (identity == DTM.NULL)
+  	return NULL;
+    // Reorganized test and loop into single flow
+    // Tiny performance improvement, saves a few bytes of code, clearer.
+    // %OPT% Other internal getters could be treated simliarly
+    while (identity>=m_size)
+    {
+      if (!nextNode() && identity >= m_size)
+        return NULL;
+    }
+    return m_exptype.elementAt(identity);
+
+  }
+
+  /**
+   * Get the level in the tree for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The tree level, or DTM.NULL.
+   */
+  protected int _level(int identity)
+  {
+    while (identity>=m_size)
+    {
+      boolean isMore = nextNode();
+      if (!isMore && identity >= m_size)
+        return NULL;
+    }
+
+    int i=0;
+    while(NULL != (identity=_parent(identity)))
+      ++i;
+    return i;
+  }
+
+  /**
+   * Get the first child for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The first child identity, or DTM.NULL.
+   */
+  protected int _firstch(int identity)
+  {
+
+    // Boiler-plate code for each of the _xxx functions, except for the array.
+    int info = (identity >= m_size) ? NOTPROCESSED : m_firstch.elementAt(identity);
+
+    // Check to see if the information requested has been processed, and,
+    // if not, advance the iterator until we the information has been
+    // processed.
+    while (info == NOTPROCESSED)
+    {
+      boolean isMore = nextNode();
+
+      if (identity >= m_size &&!isMore)
+        return NULL;
+      else
+      {
+        info = m_firstch.elementAt(identity);
+        if(info == NOTPROCESSED && !isMore)
+          return NULL;
+      }
+    }
+
+    return info;
+  }
+
+  /**
+   * Get the next sibling for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The next sibling identity, or DTM.NULL.
+   */
+  protected int _nextsib(int identity)
+  {
+    // Boiler-plate code for each of the _xxx functions, except for the array.
+    int info = (identity >= m_size) ? NOTPROCESSED : m_nextsib.elementAt(identity);
+
+    // Check to see if the information requested has been processed, and,
+    // if not, advance the iterator until we the information has been
+    // processed.
+    while (info == NOTPROCESSED)
+    {
+      boolean isMore = nextNode();
+
+      if (identity >= m_size &&!isMore)
+        return NULL;
+      else
+      {
+        info = m_nextsib.elementAt(identity);
+        if(info == NOTPROCESSED && !isMore)
+          return NULL;
+      }
+    }
+
+    return info;
+  }
+
+  /**
+   * Get the previous sibling for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The previous sibling identity, or DTM.NULL.
+   */
+  protected int _prevsib(int identity)
+  {
+
+    if (identity < m_size)
+      return m_prevsib.elementAt(identity);
+
+    // Check to see if the information requested has been processed, and,
+    // if not, advance the iterator until we the information has been
+    // processed.
+    while (true)
+    {
+      boolean isMore = nextNode();
+
+      if (identity >= m_size && !isMore)
+        return NULL;
+      else if (identity < m_size)
+        return m_prevsib.elementAt(identity);
+    }
+  }
+
+  /**
+   * Get the parent for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The parent identity, or DTM.NULL.
+   */
+  protected int _parent(int identity)
+  {
+
+    if (identity < m_size)
+      return m_parent.elementAt(identity);
+
+    // Check to see if the information requested has been processed, and,
+    // if not, advance the iterator until we the information has been
+    // processed.
+    while (true)
+    {
+      boolean isMore = nextNode();
+
+      if (identity >= m_size && !isMore)
+        return NULL;
+      else if (identity < m_size)
+        return m_parent.elementAt(identity);
+    }
+  }
+
+  /**
+   * Diagnostics function to dump the DTM.
+   */
+  public void dumpDTM(OutputStream os)
+  {
+    try
+    {
+      if(os==null)
+      {
+	      File f = new File("DTMDump"+((Object)this).hashCode()+".txt");
+ 	      System.err.println("Dumping... "+f.getAbsolutePath());
+ 	      os=new FileOutputStream(f);
+      }
+      PrintStream ps = new PrintStream(os);
+
+      while (nextNode()){}
+
+      int nRecords = m_size;
+
+      ps.println("Total nodes: " + nRecords);
+
+      for (int index = 0; index < nRecords; ++index)
+      {
+      	int i=makeNodeHandle(index);
+        ps.println("=========== index=" + index + " handle=" + i + " ===========");
+        ps.println("NodeName: " + getNodeName(i));
+        ps.println("NodeNameX: " + getNodeNameX(i));
+        ps.println("LocalName: " + getLocalName(i));
+        ps.println("NamespaceURI: " + getNamespaceURI(i));
+        ps.println("Prefix: " + getPrefix(i));
+
+        int exTypeID = _exptype(index);
+
+        ps.println("Expanded Type ID: "
+                           + Integer.toHexString(exTypeID));
+
+        int type = _type(index);
+        String typestring;
+
+        switch (type)
+        {
+        case DTM.ATTRIBUTE_NODE :
+          typestring = "ATTRIBUTE_NODE";
+          break;
+        case DTM.CDATA_SECTION_NODE :
+          typestring = "CDATA_SECTION_NODE";
+          break;
+        case DTM.COMMENT_NODE :
+          typestring = "COMMENT_NODE";
+          break;
+        case DTM.DOCUMENT_FRAGMENT_NODE :
+          typestring = "DOCUMENT_FRAGMENT_NODE";
+          break;
+        case DTM.DOCUMENT_NODE :
+          typestring = "DOCUMENT_NODE";
+          break;
+        case DTM.DOCUMENT_TYPE_NODE :
+          typestring = "DOCUMENT_NODE";
+          break;
+        case DTM.ELEMENT_NODE :
+          typestring = "ELEMENT_NODE";
+          break;
+        case DTM.ENTITY_NODE :
+          typestring = "ENTITY_NODE";
+          break;
+        case DTM.ENTITY_REFERENCE_NODE :
+          typestring = "ENTITY_REFERENCE_NODE";
+          break;
+        case DTM.NAMESPACE_NODE :
+          typestring = "NAMESPACE_NODE";
+          break;
+        case DTM.NOTATION_NODE :
+          typestring = "NOTATION_NODE";
+          break;
+        case DTM.NULL :
+          typestring = "NULL";
+          break;
+        case DTM.PROCESSING_INSTRUCTION_NODE :
+          typestring = "PROCESSING_INSTRUCTION_NODE";
+          break;
+        case DTM.TEXT_NODE :
+          typestring = "TEXT_NODE";
+          break;
+        default :
+          typestring = "Unknown!";
+          break;
+        }
+
+        ps.println("Type: " + typestring);
+
+        int firstChild = _firstch(index);
+
+        if (DTM.NULL == firstChild)
+          ps.println("First child: DTM.NULL");
+        else if (NOTPROCESSED == firstChild)
+          ps.println("First child: NOTPROCESSED");
+        else
+          ps.println("First child: " + firstChild);
+
+        if (m_prevsib != null)
+        {
+          int prevSibling = _prevsib(index);
+
+          if (DTM.NULL == prevSibling)
+            ps.println("Prev sibling: DTM.NULL");
+          else if (NOTPROCESSED == prevSibling)
+            ps.println("Prev sibling: NOTPROCESSED");
+          else
+            ps.println("Prev sibling: " + prevSibling);
+        }
+
+        int nextSibling = _nextsib(index);
+
+        if (DTM.NULL == nextSibling)
+          ps.println("Next sibling: DTM.NULL");
+        else if (NOTPROCESSED == nextSibling)
+          ps.println("Next sibling: NOTPROCESSED");
+        else
+          ps.println("Next sibling: " + nextSibling);
+
+        int parent = _parent(index);
+
+        if (DTM.NULL == parent)
+          ps.println("Parent: DTM.NULL");
+        else if (NOTPROCESSED == parent)
+          ps.println("Parent: NOTPROCESSED");
+        else
+          ps.println("Parent: " + parent);
+
+        int level = _level(index);
+
+        ps.println("Level: " + level);
+        ps.println("Node Value: " + getNodeValue(i));
+        ps.println("String Value: " + getStringValue(i));
+      }
+    }
+    catch(IOException ioe)
+    {
+      ioe.printStackTrace(System.err);
+        throw new RuntimeException(ioe.getMessage());
+    }
+  }
+  
+  /**
+   * Diagnostics function to dump a single node.
+   * 
+   * %REVIEW% KNOWN GLITCH: If you pass it a node index rather than a 
+   * node handle, it works just fine... but the displayed identity 
+   * number before the colon is different, which complicates comparing
+   * it with nodes printed the other way. We could always OR the DTM ID
+   * into the value, to suppress that distinction...
+   * 
+   * %REVIEW% This might want to be moved up to DTMDefaultBase, or possibly
+   * DTM itself, since it's a useful diagnostic and uses only DTM's public
+   * APIs.
+   */
+  public String dumpNode(int nodeHandle)
+  {	  
+	  if(nodeHandle==DTM.NULL)
+		  return "[null]";
+		  
+        String typestring;
+        switch (getNodeType(nodeHandle))
+        {
+        case DTM.ATTRIBUTE_NODE :
+          typestring = "ATTR";
+          break;
+        case DTM.CDATA_SECTION_NODE :
+          typestring = "CDATA";
+          break;
+        case DTM.COMMENT_NODE :
+          typestring = "COMMENT";
+          break;
+        case DTM.DOCUMENT_FRAGMENT_NODE :
+          typestring = "DOC_FRAG";
+          break;
+        case DTM.DOCUMENT_NODE :
+          typestring = "DOC";
+          break;
+        case DTM.DOCUMENT_TYPE_NODE :
+          typestring = "DOC_TYPE";
+          break;
+        case DTM.ELEMENT_NODE :
+          typestring = "ELEMENT";
+          break;
+        case DTM.ENTITY_NODE :
+          typestring = "ENTITY";
+          break;
+        case DTM.ENTITY_REFERENCE_NODE :
+          typestring = "ENT_REF";
+          break;
+        case DTM.NAMESPACE_NODE :
+          typestring = "NAMESPACE";
+          break;
+        case DTM.NOTATION_NODE :
+          typestring = "NOTATION";
+          break;
+        case DTM.NULL :
+          typestring = "null";
+          break;
+        case DTM.PROCESSING_INSTRUCTION_NODE :
+          typestring = "PI";
+          break;
+        case DTM.TEXT_NODE :
+          typestring = "TEXT";
+          break;
+        default :
+          typestring = "Unknown!";
+          break;
+        }
+
+      StringBuffer sb=new StringBuffer();
+	  sb.append("["+nodeHandle+": "+typestring+
+				"(0x"+Integer.toHexString(getExpandedTypeID(nodeHandle))+") "+
+				getNodeNameX(nodeHandle)+" {"+getNamespaceURI(nodeHandle)+"}"+
+				"=\""+ getNodeValue(nodeHandle)+"\"]");
+	  return sb.toString();
+  }
+
+  // ========= DTM Implementation Control Functions. ==============
+
+  /**
+   * Set an implementation dependent feature.
+   * <p>
+   * %REVIEW% Do we really expect to set features on DTMs?
+   *
+   * @param featureId A feature URL.
+   * @param state true if this feature should be on, false otherwise.
+   */
+  public void setFeature(String featureId, boolean state){}
+
+  // ========= Document Navigation Functions =========
+
+  /**
+   * Given a node handle, test if it has child nodes.
+   * <p> %REVIEW% This is obviously useful at the DOM layer, where it
+   * would permit testing this without having to create a proxy
+   * node. It's less useful in the DTM API, where
+   * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and
+   * almost as self-evident. But it's a convenience, and eases porting
+   * of DOM code to DTM.  </p>
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int true if the given node has child nodes.
+   */
+  public boolean hasChildNodes(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int firstChild = _firstch(identity);
+
+    return firstChild != DTM.NULL;
+  }
+	
+  /** Given a node identity, return a node handle. If extended addressing
+   * has been used (multiple DTM IDs), we need to map the high bits of the
+   * identity into the proper DTM ID.
+   * 
+   * This has been made FINAL to facilitate inlining, since we do not expect
+   * any subclass of DTMDefaultBase to ever change the algorithm. (I don't
+   * really like doing so, and would love to have an excuse not to...)
+   * 
+   * %REVIEW% Is it worth trying to specialcase small documents?
+   * %REVIEW% Should this be exposed at the package/public layers?
+   * 
+   * @param nodeIdentity Internal offset to this node's records.
+   * @return NodeHandle (external representation of node)
+   * */
+  final public int makeNodeHandle(int nodeIdentity)
+  {
+    if(NULL==nodeIdentity) return NULL;
+		
+    if(JJK_DEBUG && nodeIdentity>DTMManager.IDENT_NODE_DEFAULT)
+      System.err.println("GONK! (only useful in limited situations)");
+
+    return m_dtmIdent.elementAt(nodeIdentity >>> DTMManager.IDENT_DTM_NODE_BITS)
+      + (nodeIdentity & DTMManager.IDENT_NODE_DEFAULT) ;											
+  }
+	
+  /** Given a node handle, return a node identity. If extended addressing
+   * has been used (multiple DTM IDs), we need to map the high bits of the
+   * identity into the proper DTM ID and thence find the proper offset
+   * to add to the low bits of the identity
+   * 
+   * This has been made FINAL to facilitate inlining, since we do not expect
+   * any subclass of DTMDefaultBase to ever change the algorithm. (I don't
+   * really like doing so, and would love to have an excuse not to...)
+   * 
+   * %OPT% Performance is critical for this operation.
+   *
+   * %REVIEW% Should this be exposed at the package/public layers?
+   * 
+   * @param nodeHandle (external representation of node)
+   * @return nodeIdentity Internal offset to this node's records.
+   * */
+  final public int makeNodeIdentity(int nodeHandle)
+  {
+    if(NULL==nodeHandle) return NULL;
+
+    if(m_mgrDefault!=null)
+    {
+      // Optimization: use the DTMManagerDefault's fast DTMID-to-offsets
+      // table.  I'm not wild about this solution but this operation
+      // needs need extreme speed.
+
+      int whichDTMindex=nodeHandle>>>DTMManager.IDENT_DTM_NODE_BITS;
+
+      // %REVIEW% Wish I didn't have to perform the pre-test, but
+      // someone is apparently asking DTMs whether they contain nodes
+      // which really don't belong to them. That's probably a bug
+      // which should be fixed, but until it is:
+      if(m_mgrDefault.m_dtms[whichDTMindex]!=this)
+	return NULL;
+      else
+	return
+	  m_mgrDefault.m_dtm_offsets[whichDTMindex]
+	  | (nodeHandle & DTMManager.IDENT_NODE_DEFAULT);
+    }
+	  
+    int whichDTMid=m_dtmIdent.indexOf(nodeHandle & DTMManager.IDENT_DTM_DEFAULT);
+    return (whichDTMid==NULL) 
+      ? NULL
+      : (whichDTMid << DTMManager.IDENT_DTM_NODE_BITS)
+      + (nodeHandle & DTMManager.IDENT_NODE_DEFAULT);
+  }
+
+
+  /**
+   * Given a node handle, get the handle of the node's first child.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int DTM node-number of first child, or DTM.NULL to indicate none exists.
+   */
+  public int getFirstChild(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int firstChild = _firstch(identity);
+
+    return makeNodeHandle(firstChild);
+  }
+  
+  /**
+   * Given a node handle, get the handle of the node's first child.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int DTM node-number of first child, or DTM.NULL to indicate none exists.
+   */
+  public int getTypedFirstChild(int nodeHandle, int nodeType)
+  {
+
+    int firstChild, eType;
+    if (nodeType < DTM.NTYPES) {
+      for (firstChild = _firstch(makeNodeIdentity(nodeHandle));
+           firstChild != DTM.NULL;
+           firstChild = _nextsib(firstChild)) {
+        eType = _exptype(firstChild);
+        if (eType == nodeType
+               || (eType >= DTM.NTYPES
+                      && m_expandedNameTable.getType(eType) == nodeType)) {
+          return makeNodeHandle(firstChild);
+        }
+      }
+    } else {
+      for (firstChild = _firstch(makeNodeIdentity(nodeHandle));
+           firstChild != DTM.NULL;
+           firstChild = _nextsib(firstChild)) {
+        if (_exptype(firstChild) == nodeType) {
+          return makeNodeHandle(firstChild);
+        }
+      }
+    }
+    return DTM.NULL;
+  }
+
+  /**
+   * Given a node handle, advance to its last child.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int Node-number of last child,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getLastChild(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int child = _firstch(identity);
+    int lastChild = DTM.NULL;
+
+    while (child != DTM.NULL)
+    {
+      lastChild = child;
+      child = _nextsib(child);
+    }
+
+    return makeNodeHandle(lastChild);
+  }
+
+  /**
+   * Retrieves an attribute node by by qualified name and namespace URI.
+   *
+   * @param nodeHandle int Handle of the node upon which to look up this attribute..
+   * @param namespaceURI The namespace URI of the attribute to
+   *   retrieve, or null.
+   * @param name The local name of the attribute to
+   *   retrieve.
+   * @return The attribute node handle with the specified name (
+   *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
+   *   attribute.
+   */
+  public abstract int getAttributeNode(int nodeHandle, String namespaceURI,
+                                       String name);
+
+  /**
+   * Given a node handle, get the index of the node's first attribute.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return Handle of first attribute, or DTM.NULL to indicate none exists.
+   */
+  public int getFirstAttribute(int nodeHandle)
+  {
+    int nodeID = makeNodeIdentity(nodeHandle);
+
+    return makeNodeHandle(getFirstAttributeIdentity(nodeID));
+  }
+
+  /**
+   * Given a node identity, get the index of the node's first attribute.
+   *
+   * @param identity int identity of the node.
+   * @return Identity of first attribute, or DTM.NULL to indicate none exists.
+   */
+  protected int getFirstAttributeIdentity(int identity) {
+    int type = _type(identity);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      // Assume that attributes and namespaces immediately follow the element.
+      while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+      {
+
+        // Assume this can not be null.
+        type = _type(identity);
+
+        if (type == DTM.ATTRIBUTE_NODE)
+        {
+          return identity;
+        }
+        else if (DTM.NAMESPACE_NODE != type)
+        {
+          break;
+        }
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Given a node handle and an expanded type ID, get the index of the node's
+   * attribute of that type, if any.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @param attType int expanded type ID of the required attribute.
+   * @return Handle of attribute of the required type, or DTM.NULL to indicate
+   * none exists.
+   */
+  protected int getTypedAttribute(int nodeHandle, int attType) {
+    int type = getNodeType(nodeHandle);
+    if (DTM.ELEMENT_NODE == type) {
+      int identity = makeNodeIdentity(nodeHandle);
+
+      while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+      {
+        type = _type(identity);
+
+        if (type == DTM.ATTRIBUTE_NODE)
+        {
+          if (_exptype(identity) == attType) return makeNodeHandle(identity);
+        }
+        else if (DTM.NAMESPACE_NODE != type)
+        {
+          break;
+        }
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Given a node handle, advance to its next sibling.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again.
+   * @param nodeHandle int Handle of the node.
+   * @return int Node-number of next sibling,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getNextSibling(int nodeHandle)
+  {
+  	if (nodeHandle == DTM.NULL)
+  	return DTM.NULL;
+    return makeNodeHandle(_nextsib(makeNodeIdentity(nodeHandle)));
+  }
+  
+  /**
+   * Given a node handle, advance to its next sibling.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again.
+   * @param nodeHandle int Handle of the node.
+   * @return int Node-number of next sibling,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getTypedNextSibling(int nodeHandle, int nodeType)
+  {
+  	if (nodeHandle == DTM.NULL)
+  	return DTM.NULL;
+  	int node = makeNodeIdentity(nodeHandle);
+  	int eType;
+  	while ((node = _nextsib(node)) != DTM.NULL && 
+  	((eType = _exptype(node)) != nodeType && 
+  	m_expandedNameTable.getType(eType)!= nodeType)); 
+  	//_type(node) != nodeType));
+        
+    return (node == DTM.NULL ? DTM.NULL : makeNodeHandle(node));
+  }
+
+  /**
+   * Given a node handle, find its preceeding sibling.
+   * WARNING: DTM is asymmetric; this operation is resolved by search, and is
+   * relatively expensive.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node-number of the previous sib,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getPreviousSibling(int nodeHandle)
+  {
+    if (nodeHandle == DTM.NULL)
+      return DTM.NULL;
+    
+    if (m_prevsib != null)
+      return makeNodeHandle(_prevsib(makeNodeIdentity(nodeHandle)));
+    else
+    {
+      // If the previous sibling array is not built, we get at
+      // the previous sibling using the parent, firstch and 
+      // nextsib arrays. 
+      int nodeID = makeNodeIdentity(nodeHandle);
+      int parent = _parent(nodeID);
+      int node = _firstch(parent);
+      int result = DTM.NULL;
+      while (node != nodeID)
+      {
+        result = node;
+        node = _nextsib(node);
+      }
+      return makeNodeHandle(result);
+    }
+  }
+
+  /**
+   * Given a node handle, advance to the next attribute.
+   * If an attr, we advance to
+   * the next attr on the same node.  If not an attribute, we return NULL.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return int DTM node-number of the resolved attr,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getNextAttribute(int nodeHandle) {
+    int nodeID = makeNodeIdentity(nodeHandle);
+
+    if (_type(nodeID) == DTM.ATTRIBUTE_NODE) {
+      return makeNodeHandle(getNextAttributeIdentity(nodeID));
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Given a node identity for an attribute, advance to the next attribute.
+   *
+   * @param identity int identity of the attribute node.  This
+   * <strong>must</strong> be an attribute node.
+   *
+   * @return int DTM node-identity of the resolved attr,
+   * or DTM.NULL to indicate none exists.
+   *
+   */
+  protected int getNextAttributeIdentity(int identity) {
+    // Assume that attributes and namespace nodes immediately follow the element
+    while (DTM.NULL != (identity = getNextNodeIdentity(identity))) {
+      int type = _type(identity);
+
+      if (type == DTM.ATTRIBUTE_NODE) {
+        return identity;
+      } else if (type != DTM.NAMESPACE_NODE) {
+        break;
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /** Lazily created namespace lists. */
+  private Vector m_namespaceLists = null;  // on demand
+
+
+  /** Build table of namespace declaration
+   * locations during DTM construction. Table is a Vector of
+   * SuballocatedIntVectors containing the namespace node HANDLES declared at
+   * that ID, plus an SuballocatedIntVector of the element node INDEXES at which
+   * these declarations appeared.
+   *
+   * NOTE: Since this occurs during model build, nodes will be encountered
+   * in doucment order and thus the table will be ordered by element,
+   * permitting binary-search as a possible retrieval optimization.
+   *
+   * %REVIEW% Directly managed arrays rather than vectors?
+   * %REVIEW% Handles or IDs? Given usage, I think handles.
+   * */
+  protected void declareNamespaceInContext(int elementNodeIndex,int namespaceNodeIndex)
+  {
+    SuballocatedIntVector nsList=null;
+    if(m_namespaceDeclSets==null)
+      {
+
+        // First
+        m_namespaceDeclSetElements=new SuballocatedIntVector(32);
+        m_namespaceDeclSetElements.addElement(elementNodeIndex);
+        m_namespaceDeclSets=new Vector();
+        nsList=new SuballocatedIntVector(32);
+        m_namespaceDeclSets.addElement(nsList);
+      }
+    else
+      {
+        // Most recent. May be -1 (none) if DTM was pruned.
+        // %OPT% Is there a lastElement() method? Should there be?
+        int last=m_namespaceDeclSetElements.size()-1;
+	        
+        if(last>=0 && elementNodeIndex==m_namespaceDeclSetElements.elementAt(last))
+          {
+            nsList=(SuballocatedIntVector)m_namespaceDeclSets.elementAt(last);
+          }
+      }
+    if(nsList==null)
+      {
+        m_namespaceDeclSetElements.addElement(elementNodeIndex);
+
+        SuballocatedIntVector inherited =
+                                findNamespaceContext(_parent(elementNodeIndex));
+
+        if (inherited!=null) {
+            // %OPT% Count-down might be faster, but debuggability may
+            // be better this way, and if we ever decide we want to
+            // keep this ordered by expanded-type...
+            int isize=inherited.size();
+
+            // Base the size of a new namespace list on the
+            // size of the inherited list - but within reason!
+            nsList=new SuballocatedIntVector(Math.max(Math.min(isize+16,2048),
+                                                      32));
+
+            for(int i=0;i<isize;++i)
+              {
+                nsList.addElement(inherited.elementAt(i));
+              }
+        } else {
+            nsList=new SuballocatedIntVector(32);
+        }
+
+        m_namespaceDeclSets.addElement(nsList);
+      }
+
+    // Handle overwriting inherited.
+    // %OPT% Keep sorted? (By expanded-name rather than by doc order...)
+    // Downside: Would require insertElementAt if not found,
+    // which has recopying costs. But these are generally short lists...
+    int newEType=_exptype(namespaceNodeIndex);
+
+    for(int i=nsList.size()-1;i>=0;--i)
+      {
+        if(newEType==getExpandedTypeID(nsList.elementAt(i)))
+          {
+            nsList.setElementAt(makeNodeHandle(namespaceNodeIndex),i);
+            return;
+          }
+      }
+    nsList.addElement(makeNodeHandle(namespaceNodeIndex));
+  }
+
+  /** Retrieve list of namespace declaration locations
+     * active at this node. List is an SuballocatedIntVector whose
+     * entries are the namespace node HANDLES declared at that ID.
+     *
+     * %REVIEW% Directly managed arrays rather than vectors?
+     * %REVIEW% Handles or IDs? Given usage, I think handles.
+     * */
+  protected SuballocatedIntVector findNamespaceContext(int elementNodeIndex)
+  {
+    if (null!=m_namespaceDeclSetElements)
+      {
+        // %OPT% Is binary-search really saving us a lot versus linear?
+        // (... It may be, in large docs with many NS decls.)
+        int wouldBeAt=findInSortedSuballocatedIntVector(m_namespaceDeclSetElements,
+                                            elementNodeIndex);
+        if(wouldBeAt>=0) // Found it
+          return (SuballocatedIntVector) m_namespaceDeclSets.elementAt(wouldBeAt);
+        if(wouldBeAt == -1) // -1-wouldbeat == 0
+          return null; // Not after anything; definitely not found
+
+        // Not found, but we know where it should have been.
+        // Search back until we find an ancestor or run out.
+        wouldBeAt=-1-wouldBeAt;
+
+        // Decrement wouldBeAt to find last possible ancestor
+        int candidate=m_namespaceDeclSetElements.elementAt(-- wouldBeAt);
+        int ancestor=_parent(elementNodeIndex);
+
+        // Special case: if the candidate is before the given node, and
+        // is in the earliest possible position in the document, it
+        // must have the namespace declarations we're interested in.
+        if (wouldBeAt == 0 && candidate < ancestor) {
+          int rootHandle = getDocumentRoot(makeNodeHandle(elementNodeIndex));
+          int rootID = makeNodeIdentity(rootHandle);
+          int uppermostNSCandidateID;
+
+          if (getNodeType(rootHandle) == DTM.DOCUMENT_NODE) {
+            int ch = _firstch(rootID);
+            uppermostNSCandidateID = (ch != DTM.NULL) ? ch : rootID;
+          } else {
+            uppermostNSCandidateID = rootID;
+          }
+
+          if (candidate == uppermostNSCandidateID) {
+            return (SuballocatedIntVector)m_namespaceDeclSets.elementAt(wouldBeAt);
+          }
+        }
+
+        while(wouldBeAt>=0 && ancestor>0)
+          {
+            if (candidate==ancestor) {
+                // Found ancestor in list
+                return (SuballocatedIntVector)m_namespaceDeclSets.elementAt(wouldBeAt);
+            } else if (candidate<ancestor) {
+                // Too deep in tree
+                do {
+                  ancestor=_parent(ancestor);
+                } while (candidate < ancestor);
+            } else if(wouldBeAt > 0){
+              // Too late in list
+              candidate=m_namespaceDeclSetElements.elementAt(--wouldBeAt);
+            }
+            else
+            	break;
+          }
+      }
+
+    return null; // No namespaces known at this node
+  }
+
+  /**
+     * Subroutine: Locate the specified node within
+     * m_namespaceDeclSetElements, or the last element which
+     * preceeds it in document order
+     *
+     * %REVIEW% Inlne this into findNamespaceContext? Create SortedSuballocatedIntVector type?
+     *
+     * @return If positive or zero, the index of the found item.
+     * If negative, index of the point at which it would have appeared,
+     * encoded as -1-index and hence reconvertable by subtracting
+     * it from -1. (Encoding because I don't want to recompare the strings
+     * but don't want to burn bytes on a datatype to hold a flagged value.)
+     */
+  protected int findInSortedSuballocatedIntVector(SuballocatedIntVector vector, int lookfor)
+  {
+    // Binary search
+    int i = 0;
+    if(vector != null) {
+      int first = 0;
+      int last  = vector.size() - 1;
+
+      while (first <= last) {
+        i = (first + last) / 2;
+        int test = lookfor-vector.elementAt(i);
+        if(test == 0) {
+          return i; // Name found
+        }
+        else if (test < 0) {
+          last = i - 1; // looked too late
+        }
+        else {
+          first = i + 1; // looked ot early
+        }
+      }
+
+      if (first > i) {
+        i = first; // Clean up at loop end
+      }
+    }
+
+    return -1 - i; // not-found has to be encoded.
+  }
+
+
+  /**
+   * Given a node handle, get the index of the node's first child.
+   * If not yet resolved, waits for more nodes to be added to the document and
+   * tries again
+   *
+   * @param nodeHandle handle to node, which should probably be an element
+   *                   node, but need not be.
+   *
+   * @param inScope    true if all namespaces in scope should be returned,
+   *                   false if only the namespace declarations should be
+   *                   returned.
+   * @return handle of first namespace, or DTM.NULL to indicate none exists.
+   */
+  public int getFirstNamespaceNode(int nodeHandle, boolean inScope)
+  {
+        if(inScope)
+        {
+            int identity = makeNodeIdentity(nodeHandle);
+            if (_type(identity) == DTM.ELEMENT_NODE)
+            {
+              SuballocatedIntVector nsContext=findNamespaceContext(identity);
+              if(nsContext==null || nsContext.size()<1)
+                return NULL;
+
+              return nsContext.elementAt(0);
+            }
+            else
+              return NULL;
+          }
+        else
+          {
+            // Assume that attributes and namespaces immediately
+            // follow the element.
+            //
+            // %OPT% Would things be faster if all NS nodes were built
+            // before all Attr nodes? Some costs at build time for 2nd
+            // pass...
+            int identity = makeNodeIdentity(nodeHandle);
+            if (_type(identity) == DTM.ELEMENT_NODE)
+            {
+              while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+              {
+                int type = _type(identity);
+                if (type == DTM.NAMESPACE_NODE)
+                    return makeNodeHandle(identity);
+                else if (DTM.ATTRIBUTE_NODE != type)
+                    break;
+              }
+              return NULL;
+            }
+            else
+              return NULL;
+          }
+  }
+
+  /**
+   * Given a namespace handle, advance to the next namespace.
+   *
+   * @param baseHandle handle to original node from where the first namespace
+   * was relative to (needed to return nodes in document order).
+   * @param nodeHandle A namespace handle for which we will find the next node.
+   * @param inScope true if all namespaces that are in scope should be processed,
+   * otherwise just process the nodes in the given element handle.
+   * @return handle of next namespace, or DTM.NULL to indicate none exists.
+   */
+  public int getNextNamespaceNode(int baseHandle, int nodeHandle,
+                                  boolean inScope)
+  {
+        if(inScope)
+          {
+            //Since we've been given the base, try direct lookup
+            //(could look from nodeHandle but this is at least one
+            //comparison/get-parent faster)
+            //SuballocatedIntVector nsContext=findNamespaceContext(nodeHandle & m_mask);
+
+                SuballocatedIntVector nsContext=findNamespaceContext(makeNodeIdentity(baseHandle));
+
+            if(nsContext==null)
+              return NULL;
+            int i=1 + nsContext.indexOf(nodeHandle);
+            if(i<=0 || i==nsContext.size())
+              return NULL;
+
+            return nsContext.elementAt(i);
+          }
+        else
+          {
+            // Assume that attributes and namespace nodes immediately follow the element.
+            int identity = makeNodeIdentity(nodeHandle);
+            while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+              {
+                int type = _type(identity);
+                if (type == DTM.NAMESPACE_NODE)
+                  {
+                    return makeNodeHandle(identity);
+                  }
+                else if (type != DTM.ATTRIBUTE_NODE)
+                  {
+                    break;
+                  }
+              }
+          }
+     return DTM.NULL;
+  }
+
+  /**
+   * Given a node handle, find its parent node.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node-number of parent,
+   * or DTM.NULL to indicate none exists.
+   */
+  public int getParent(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+
+    if (identity > 0)
+      return makeNodeHandle(_parent(identity));
+    else
+      return DTM.NULL;
+  }
+
+  /**
+   * Find the Document node handle for the document currently under construction.
+   * PLEASE NOTE that most people should use getOwnerDocument(nodeHandle) instead;
+   * this version of the operation is primarily intended for use during negotiation
+   * with the DTM Manager.
+   * 
+   *  @return int Node handle of document, which should always be valid.
+   */
+  public int getDocument()
+  {
+    return m_dtmIdent.elementAt(0); // makeNodeHandle(0)
+  }
+
+  /**
+   * Given a node handle, find the owning document node.  This has the exact
+   * same semantics as the DOM Document method of the same name, in that if
+   * the nodeHandle is a document node, it will return NULL.
+   *
+   * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM
+   * binding layer. Included here as a convenience function and to
+   * aid porting of DOM code to DTM.</p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of owning document, or -1 if the node was a Docment
+   */
+  public int getOwnerDocument(int nodeHandle)
+  {
+
+    if (DTM.DOCUMENT_NODE == getNodeType(nodeHandle))
+  	    return DTM.NULL;
+
+    return getDocumentRoot(nodeHandle);
+  }
+
+  /**
+   * Given a node handle, find the owning document node.  Unlike the DOM,
+   * this considers the owningDocument of a Document to be itself.
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of owning document, or the nodeHandle if it is
+   *             a Document.
+   */
+  public int getDocumentRoot(int nodeHandle)
+  {
+    return getManager().getDTM(nodeHandle).getDocument();
+  }
+
+  /**
+   * Get the string-value of a node as a String object
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public abstract XMLString getStringValue(int nodeHandle);
+
+  /**
+   * Get number of character array chunks in
+   * the string-value of a node.
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   * Note that a single text node may have multiple text chunks.
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return number of character array chunks in
+   *         the string-value of a node.
+   */
+  public int getStringValueChunkCount(int nodeHandle)
+  {
+
+    // %TBD%
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//("getStringValueChunkCount not yet supported!");
+
+    return 0;
+  }
+
+  /**
+   * Get a character array chunk in the string-value of a node.
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   * Note that a single text node may have multiple text chunks.
+   *
+   * @param nodeHandle The node ID.
+   * @param chunkIndex Which chunk to get.
+   * @param startAndLen An array of 2 where the start position and length of
+   *                    the chunk will be returned.
+   *
+   * @return The character array reference where the chunk occurs.
+   */
+  public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
+                                    int[] startAndLen)
+  {
+
+    // %TBD%
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"getStringValueChunk not yet supported!");
+
+    return null;
+  }
+
+  /**
+   * Given a node handle, return an ID that represents the node's expanded name.
+   *
+   * @param nodeHandle The handle to the node in question.
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(int nodeHandle)
+  {
+    // %REVIEW% This _should_ only be null if someone asked the wrong DTM about the node...
+    // which one would hope would never happen...
+    int id=makeNodeIdentity(nodeHandle);
+    if(id==NULL)
+      return NULL;
+    return _exptype(id);
+  }
+
+  /**
+   * Given an expanded name, return an ID.  If the expanded-name does not
+   * exist in the internal tables, the entry will be created, and the ID will
+   * be returned.  Any additional nodes that are created that have this
+   * expanded name will use this ID.
+   *
+   * @param type The simple type, i.e. one of ELEMENT, ATTRIBUTE, etc.
+   *
+   * @param namespace The namespace URI, which may be null, may be an empty
+   *                  string (which will be the same as null), or may be a
+   *                  namespace URI.
+   * @param localName The local name string, which must be a valid
+   *                  <a href="http://www.w3.org/TR/REC-xml-names/">NCName</a>.
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(String namespace, String localName, int type)
+  {
+
+    ExpandedNameTable ent = m_expandedNameTable;
+
+    return ent.getExpandedTypeID(namespace, localName, type);
+  }
+
+  /**
+   * Given an expanded-name ID, return the local name part.
+   *
+   * @param expandedNameID an ID that represents an expanded-name.
+   * @return String Local name of this node.
+   */
+  public String getLocalNameFromExpandedNameID(int expandedNameID)
+  {
+    return m_expandedNameTable.getLocalName(expandedNameID);
+  }
+
+  /**
+   * Given an expanded-name ID, return the namespace URI part.
+   *
+   * @param expandedNameID an ID that represents an expanded-name.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespaceFromExpandedNameID(int expandedNameID)
+  {
+    return m_expandedNameTable.getNamespace(expandedNameID);
+  }
+
+  /**
+   * Returns the namespace type of a specific node
+   * @param nodeHandle the id of the node.
+   * @return the ID of the namespace.
+   */
+  public int getNamespaceType(final int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int expandedNameID = _exptype(identity);
+
+    return m_expandedNameTable.getNamespaceID(expandedNameID);
+  }
+
+  /**
+   * Given a node handle, return its DOM-style node name. This will
+   * include names such as #text or #document.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   * %REVIEW% Document when empty string is possible...
+   * %REVIEW-COMMENT% It should never be empty, should it?
+   */
+  public abstract String getNodeName(int nodeHandle);
+
+  /**
+   * Given a node handle, return the XPath node name.  This should be
+   * the name as described by the XPath data model, NOT the DOM-style
+   * name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   */
+  public String getNodeNameX(int nodeHandle)
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMDefaultBase abstract method */
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!");
+
+    return null;
+  }
+
+  /**
+   * Given a node handle, return its XPath-style localname.
+   * (As defined in Namespaces, this is the portion of the name after any
+   * colon character).
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Local name of this node.
+   */
+  public abstract String getLocalName(int nodeHandle);
+
+  /**
+   * Given a namespace handle, return the prefix that the namespace decl is
+   * mapping.
+   * Given a node handle, return the prefix used to map to the namespace.
+   *
+   * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
+   * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb  </p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String prefix of this node's name, or "" if no explicit
+   * namespace prefix was given.
+   */
+  public abstract String getPrefix(int nodeHandle);
+
+  /**
+   * Given a node handle, return its DOM-style namespace URI
+   * (As defined in Namespaces, this is the declared URI which this node's
+   * prefix -- or default in lieu thereof -- was mapped to.)
+   *
+   * <p>%REVIEW% Null or ""? -sb</p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public abstract String getNamespaceURI(int nodeHandle);
+
+  /**
+   * Given a node handle, return its node value. This is mostly
+   * as defined by the DOM, but may ignore some conveniences.
+   * <p>
+   *
+   * @param nodeHandle The node id.
+   * @return String Value of this node, or null if not
+   * meaningful for this node type.
+   */
+  public abstract String getNodeValue(int nodeHandle);
+
+  /**
+   * Given a node handle, return its DOM-style node type.
+   * <p>
+   * %REVIEW% Generally, returning short is false economy. Return int?
+   * %REVIEW% Make assumption that node has already arrived.  Is OK?
+   *
+   * @param nodeHandle The node id.
+   * @return int Node type, as per the DOM's Node._NODE constants.
+   */
+  public short getNodeType(int nodeHandle)
+  {
+  	if (nodeHandle == DTM.NULL)
+  	return DTM.NULL;
+    return m_expandedNameTable.getType(_exptype(makeNodeIdentity(nodeHandle)));
+  }
+
+  /**
+   * Get the depth level of this node in the tree (equals 1 for
+   * a parentless node).
+   *
+   * @param nodeHandle The node id.
+   * @return the number of ancestors, plus one
+   * @xsl.usage internal
+   */
+  public short getLevel(int nodeHandle)
+  {
+    // Apparently, the axis walker stuff requires levels to count from 1.
+    int identity = makeNodeIdentity(nodeHandle);
+    return (short) (_level(identity) + 1);
+  }
+  
+  /**
+   * Get the identity of this node in the tree 
+   *
+   * @param nodeHandle The node handle.
+   * @return the node identity
+   * @xsl.usage internal
+   */
+  public int getNodeIdent(int nodeHandle)
+  {
+    /*if (nodeHandle != DTM.NULL)
+      return nodeHandle & m_mask;
+    else 
+      return DTM.NULL;*/
+      
+      return makeNodeIdentity(nodeHandle); 
+  }
+  
+  /**
+   * Get the handle of this node in the tree 
+   *
+   * @param nodeId The node identity.
+   * @return the node handle
+   * @xsl.usage internal
+   */
+  public int getNodeHandle(int nodeId)
+  {
+    /*if (nodeId != DTM.NULL)
+      return nodeId | m_dtmIdent;
+    else 
+      return DTM.NULL;*/
+      
+      return makeNodeHandle(nodeId);
+  }
+
+  // ============== Document query functions ==============
+
+  /**
+   * Tests whether DTM DOM implementation implements a specific feature and
+   * that feature is supported by this node.
+   *
+   * @param feature The name of the feature to test.
+   * @param version This is the version number of the feature to test.
+   *   If the version is not
+   *   specified, supporting any version of the feature will cause the
+   *   method to return <code>true</code>.
+   * @return Returns <code>true</code> if the specified feature is
+   *   supported on this node, <code>false</code> otherwise.
+   */
+  public boolean isSupported(String feature, String version)
+  {
+
+    // %TBD%
+    return false;
+  }
+
+  /**
+   * Return the base URI of the document entity. If it is not known
+   * (because the document was parsed from a socket connection or from
+   * standard input, for example), the value of this property is unknown.
+   *
+   * @return the document base URI String object or null if unknown.
+   */
+  public String getDocumentBaseURI()
+  {
+    return m_documentBaseURI;
+  }
+
+  /**
+   * Set the base URI of the document entity.
+   *
+   * @param baseURI the document base URI String object or null if unknown.
+   */
+  public void setDocumentBaseURI(String baseURI)
+  {
+    m_documentBaseURI = baseURI;
+  }
+
+  /**
+   * Return the system identifier of the document entity. If
+   * it is not known, the value of this property is unknown.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the system identifier String object or null if unknown.
+   */
+  public String getDocumentSystemIdentifier(int nodeHandle)
+  {
+
+    // %REVIEW%  OK? -sb
+    return m_documentBaseURI;
+  }
+
+  /**
+   * Return the name of the character encoding scheme
+   *        in which the document entity is expressed.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the document encoding String object.
+   * @xsl.usage internal
+   */
+  public String getDocumentEncoding(int nodeHandle)
+  {
+
+    // %REVIEW%  OK??  -sb
+    return "UTF-8";
+  }
+
+  /**
+   * Return an indication of the standalone status of the document,
+   *        either "yes" or "no". This property is derived from the optional
+   *        standalone document declaration in the XML declaration at the
+   *        beginning of the document entity, and has no value if there is no
+   *        standalone document declaration.
+   *
+   * @param nodeHandle The node id, which can be any valid node handle.
+   * @return the document standalone String object, either "yes", "no", or null.
+   */
+  public String getDocumentStandalone(int nodeHandle)
+  {
+    return null;
+  }
+
+  /**
+   * Return a string representing the XML version of the document. This
+   * property is derived from the XML declaration optionally present at the
+   * beginning of the document entity, and has no value if there is no XML
+   * declaration.
+   *
+   * @param documentHandle The document handle
+   *
+   * @return the document version String object.
+   */
+  public String getDocumentVersion(int documentHandle)
+  {
+    return null;
+  }
+
+  /**
+   * Return an indication of
+   * whether the processor has read the complete DTD. Its value is a
+   * boolean. If it is false, then certain properties (indicated in their
+   * descriptions below) may be unknown. If it is true, those properties
+   * are never unknown.
+   *
+   * @return <code>true</code> if all declarations were processed;
+   *         <code>false</code> otherwise.
+   */
+  public boolean getDocumentAllDeclarationsProcessed()
+  {
+
+    // %REVIEW% OK?
+    return true;
+  }
+
+  /**
+   *   A document type declaration information item has the following properties:
+   *
+   *     1. [system identifier] The system identifier of the external subset, if
+   *        it exists. Otherwise this property has no value.
+   *
+   * @return the system identifier String object, or null if there is none.
+   */
+  public abstract String getDocumentTypeDeclarationSystemIdentifier();
+
+  /**
+   * Return the public identifier of the external subset,
+   * normalized as described in 4.2.2 External Entities [XML]. If there is
+   * no external subset or if it has no public identifier, this property
+   * has no value.
+   *
+   * @return the public identifier String object, or null if there is none.
+   */
+  public abstract String getDocumentTypeDeclarationPublicIdentifier();
+
+  /**
+   * Returns the <code>Element</code> whose <code>ID</code> is given by
+   * <code>elementId</code>. If no such element exists, returns
+   * <code>DTM.NULL</code>. Behavior is not defined if more than one element
+   * has this <code>ID</code>. Attributes (including those
+   * with the name "ID") are not of type ID unless so defined by DTD/Schema
+   * information available to the DTM implementation.
+   * Implementations that do not know whether attributes are of type ID or
+   * not are expected to return <code>DTM.NULL</code>.
+   *
+   * <p>%REVIEW% Presumably IDs are still scoped to a single document,
+   * and this operation searches only within a single document, right?
+   * Wouldn't want collisions between DTMs in the same process.</p>
+   *
+   * @param elementId The unique <code>id</code> value for an element.
+   * @return The handle of the matching element.
+   */
+  public abstract int getElementById(String elementId);
+
+  /**
+   * The getUnparsedEntityURI function returns the URI of the unparsed
+   * entity with the specified name in the same document as the context
+   * node (see [3.3 Unparsed Entities]). It returns the empty string if
+   * there is no such entity.
+   * <p>
+   * XML processors may choose to use the System Identifier (if one
+   * is provided) to resolve the entity, rather than the URI in the
+   * Public Identifier. The details are dependent on the processor, and
+   * we would have to support some form of plug-in resolver to handle
+   * this properly. Currently, we simply return the System Identifier if
+   * present, and hope that it a usable URI or that our caller can
+   * map it to one.
+   * TODO: Resolve Public Identifiers... or consider changing function name.
+   * <p>
+   * If we find a relative URI
+   * reference, XML expects it to be resolved in terms of the base URI
+   * of the document. The DOM doesn't do that for us, and it isn't
+   * entirely clear whether that should be done here; currently that's
+   * pushed up to a higher level of our application. (Note that DOM Level
+   * 1 didn't store the document's base URI.)
+   * TODO: Consider resolving Relative URIs.
+   * <p>
+   * (The DOM's statement that "An XML processor may choose to
+   * completely expand entities before the structure model is passed
+   * to the DOM" refers only to parsed entities, not unparsed, and hence
+   * doesn't affect this function.)
+   *
+   * @param name A string containing the Entity Name of the unparsed
+   * entity.
+   *
+   * @return String containing the URI of the Unparsed Entity, or an
+   * empty string if no such entity exists.
+   */
+  public abstract String getUnparsedEntityURI(String name);
+
+  // ============== Boolean methods ================
+
+  /**
+   * Return true if the xsl:strip-space or xsl:preserve-space was processed
+   * during construction of the DTM document.
+   *
+   * @return true if this DTM supports prestripping.
+   */
+  public boolean supportsPreStripping()
+  {
+    return true;
+  }
+
+  /**
+   * Figure out whether nodeHandle2 should be considered as being later
+   * in the document than nodeHandle1, in Document Order as defined
+   * by the XPath model. This may not agree with the ordering defined
+   * by other XML applications.
+   * <p>
+   * There are some cases where ordering isn't defined, and neither are
+   * the results of this function -- though we'll generally return false.
+   *
+   * @param nodeHandle1 Node handle to perform position comparison on.
+   * @param nodeHandle2 Second Node handle to perform position comparison on .
+   *
+   * @return true if node1 comes before node2, otherwise return false.
+   * You can think of this as
+   * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
+   */
+  public boolean isNodeAfter(int nodeHandle1, int nodeHandle2)
+  {
+		// These return NULL if the node doesn't belong to this document.
+    int index1 = makeNodeIdentity(nodeHandle1);
+    int index2 = makeNodeIdentity(nodeHandle2);
+
+    return index1!=NULL && index2!=NULL && index1 <= index2;
+  }
+
+  /**
+   *     2. [element content whitespace] A boolean indicating whether the
+   *        character is white space appearing within element content (see [XML],
+   *        2.10 "White Space Handling"). Note that validating XML processors are
+   *        required by XML 1.0 to provide this information. If there is no
+   *        declaration for the containing element, this property has no value for
+   *        white space characters. If no declaration has been read, but the [all
+   *        declarations processed] property of the document information item is
+   *        false (so there may be an unread declaration), then the value of this
+   *        property is unknown for white space characters. It is always false for
+   *        characters that are not white space.
+   *
+   * @param nodeHandle the node ID.
+   * @return <code>true</code> if the character data is whitespace;
+   *         <code>false</code> otherwise.
+   */
+  public boolean isCharacterElementContentWhitespace(int nodeHandle)
+  {
+
+    // %TBD%
+    return false;
+  }
+
+  /**
+   *    10. [all declarations processed] This property is not strictly speaking
+   *        part of the infoset of the document. Rather it is an indication of
+   *        whether the processor has read the complete DTD. Its value is a
+   *        boolean. If it is false, then certain properties (indicated in their
+   *        descriptions below) may be unknown. If it is true, those properties
+   *        are never unknown.
+   *
+   * @param documentHandle A node handle that must identify a document.
+   * @return <code>true</code> if all declarations were processed;
+   *         <code>false</code> otherwise.
+   */
+  public boolean isDocumentAllDeclarationsProcessed(int documentHandle)
+  {
+    return true;
+  }
+
+  /**
+   *     5. [specified] A flag indicating whether this attribute was actually
+   *        specified in the start-tag of its element, or was defaulted from the
+   *        DTD.
+   *
+   * @param attributeHandle The attribute handle in question.
+   *
+   * @return <code>true</code> if the attribute was specified;
+   *         <code>false</code> if it was defaulted.
+   */
+  public abstract boolean isAttributeSpecified(int attributeHandle);
+
+  // ========== Direct SAX Dispatch, for optimization purposes ========
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value). Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   * @param normalize true if the content should be normalized according to
+   * the rules for the XPath
+   * <a href="http://www.w3.org/TR/xpath#function-normalize-space">normalize-space</a>
+   * function.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public abstract void dispatchCharactersEvents(
+    int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize)
+      throws org.xml.sax.SAXException;
+
+  /**
+   * Directly create SAX parser events from a subtree.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public abstract void dispatchToEvents(
+    int nodeHandle, org.xml.sax.ContentHandler ch)
+      throws org.xml.sax.SAXException;
+
+  /**
+   * Return an DOM node for the given node.
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A node representation of the DTM node.
+   */
+  public org.w3c.dom.Node getNode(int nodeHandle)
+  {
+    return new DTMNodeProxy(this, nodeHandle);
+  }
+
+  // ==== Construction methods (may not be supported by some implementations!) =====
+
+  /**
+   * Append a child to the end of the document. Please note that the node
+   * is always cloned if it is owned by another document.
+   *
+   * <p>%REVIEW% "End of the document" needs to be defined more clearly.
+   * Does it become the last child of the Document? Of the root element?</p>
+   *
+   * @param newChild Must be a valid new node handle.
+   * @param clone true if the child should be cloned into the document.
+   * @param cloneDepth if the clone argument is true, specifies that the
+   *                   clone should include all it's children.
+   */
+  public void appendChild(int newChild, boolean clone, boolean cloneDepth)
+  {
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"appendChild not yet supported!");
+  }
+
+  /**
+   * Append a text node child that will be constructed from a string,
+   * to the end of the document.
+   *
+   * <p>%REVIEW% "End of the document" needs to be defined more clearly.
+   * Does it become the last child of the Document? Of the root element?</p>
+   *
+   * @param str Non-null reverence to a string.
+   */
+  public void appendTextChild(String str)
+  {
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"appendTextChild not yet supported!");
+  }
+
+  /**
+   * Simple error for asserts and the like.
+   *
+   * @param msg Error message to report.
+   */
+  protected void error(String msg)
+  {
+    throw new DTMException(msg);
+  }
+
+  /**
+   * Find out whether or not to strip whispace nodes.
+   *
+   *
+   * @return whether or not to strip whispace nodes.
+   */
+  protected boolean getShouldStripWhitespace()
+  {
+    return m_shouldStripWS;
+  }
+
+  /**
+   * Set whether to strip whitespaces and push in current value of
+   * m_shouldStripWS in m_shouldStripWhitespaceStack.
+   *
+   * @param shouldStrip Flag indicating whether to strip whitespace nodes
+   */
+  protected void pushShouldStripWhitespace(boolean shouldStrip)
+  {
+
+    m_shouldStripWS = shouldStrip;
+
+    if (null != m_shouldStripWhitespaceStack)
+      m_shouldStripWhitespaceStack.push(shouldStrip);
+  }
+
+  /**
+   * Set whether to strip whitespaces at this point by popping out
+   * m_shouldStripWhitespaceStack.
+   *
+   */
+  protected void popShouldStripWhitespace()
+  {
+    if (null != m_shouldStripWhitespaceStack)
+      m_shouldStripWS = m_shouldStripWhitespaceStack.popAndTop();
+  }
+
+  /**
+   * Set whether to strip whitespaces and set the top of the stack to
+   * the current value of m_shouldStripWS.
+   *
+   *
+   * @param shouldStrip Flag indicating whether to strip whitespace nodes
+   */
+  protected void setShouldStripWhitespace(boolean shouldStrip)
+  {
+
+    m_shouldStripWS = shouldStrip;
+
+    if (null != m_shouldStripWhitespaceStack)
+      m_shouldStripWhitespaceStack.setTop(shouldStrip);
+  }
+
+  /**
+   * A dummy routine to satisify the abstract interface. If the DTM
+   * implememtation that extends the default base requires notification
+   * of registration, they can override this method.
+   */
+   public void documentRegistration()
+   {
+   }
+
+  /**
+   * A dummy routine to satisify the abstract interface. If the DTM
+   * implememtation that extends the default base requires notification
+   * when the document is being released, they can override this method
+   */
+   public void documentRelease()
+   {
+   }
+
+   /**
+    * Migrate a DTM built with an old DTMManager to a new DTMManager.
+    * After the migration, the new DTMManager will treat the DTM as
+    * one that is built by itself.
+    * This is used to support DTM sharing between multiple transformations.
+    * @param mgr the DTMManager
+    */
+   public void migrateTo(DTMManager mgr)
+   {
+     m_mgr = mgr;
+     if(mgr instanceof DTMManagerDefault)
+       m_mgrDefault=(DTMManagerDefault)mgr;     
+   }      
+
+	 /** Query which DTMManager this DTM is currently being handled by.
+	  * 
+	  * %REVEW% Should this become part of the base DTM API?
+	  * 
+	  * @return a DTMManager, or null if this is a "stand-alone" DTM.
+	  */
+	 public DTMManager getManager()
+	 {
+		 return m_mgr;
+	 }
+
+	 /** Query which DTMIDs this DTM is currently using within the DTMManager.
+	  * 
+	  * %REVEW% Should this become part of the base DTM API?
+	  * 
+	  * @return an IntVector, or null if this is a "stand-alone" DTM.
+	  */
+	 public SuballocatedIntVector getDTMIDs()
+	 {
+		 if(m_mgr==null) return null;
+		 return m_dtmIdent;
+	 }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java
new file mode 100644
index 0000000..d554119
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java
@@ -0,0 +1,2192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMDefaultBaseIterators.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.*;
+
+import javax.xml.transform.Source;
+
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+/**
+ * This class implements the traversers for DTMDefaultBase.
+ */
+public abstract class DTMDefaultBaseIterators extends DTMDefaultBaseTraversers
+{
+
+  /**
+   * Construct a DTMDefaultBaseTraversers object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use 
+   *                   indexing schemes.
+   */
+  public DTMDefaultBaseIterators(DTMManager mgr, Source source,
+                                 int dtmIdentity,
+                                 DTMWSFilter whiteSpaceFilter,
+                                 XMLStringFactory xstringfactory,
+                                 boolean doIndexing)
+  {
+    super(mgr, source, dtmIdentity, whiteSpaceFilter, 
+          xstringfactory, doIndexing);
+  }
+
+  /**
+   * Construct a DTMDefaultBaseTraversers object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use 
+   *                   indexing schemes.
+   * @param blocksize The block size of the DTM.
+   * @param usePrevsib true if we want to build the previous sibling node array.
+   * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
+   */
+  public DTMDefaultBaseIterators(DTMManager mgr, Source source,
+                                 int dtmIdentity,
+                                 DTMWSFilter whiteSpaceFilter,
+                                 XMLStringFactory xstringfactory,
+                                 boolean doIndexing,
+                                 int blocksize,
+                                 boolean usePrevsib,
+                                 boolean newNameTable)
+  {
+    super(mgr, source, dtmIdentity, whiteSpaceFilter, 
+          xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
+  }
+
+  /**
+   * Get an iterator that can navigate over an XPath Axis, predicated by
+   * the extended type ID.
+   * Returns an iterator that must be initialized
+   * with a start node (using iterator.setStartNode()).
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   * @param type An extended type ID.
+   *
+   * @return A DTMAxisIterator, or null if the given axis isn't supported.
+   */
+  public DTMAxisIterator getTypedAxisIterator(int axis, int type)
+  {
+
+    DTMAxisIterator iterator = null;
+
+    /* This causes an error when using patterns for elements that
+       do not exist in the DOM (translet types which do not correspond
+       to a DOM type are mapped to the DOM.ELEMENT type).
+    */
+
+    //        if (type == NO_TYPE) {
+    //            return(EMPTYITERATOR);
+    //        }
+    //        else if (type == ELEMENT) {
+    //            iterator = new FilterIterator(getAxisIterator(axis),
+    //                                          getElementFilter());
+    //        }
+    //        else 
+    {
+      switch (axis)
+      {
+      case Axis.SELF :
+        iterator = new TypedSingletonIterator(type);
+        break;
+      case Axis.CHILD :
+        iterator = new TypedChildrenIterator(type);
+        break;
+      case Axis.PARENT :
+        return (new ParentIterator().setNodeType(type));
+      case Axis.ANCESTOR :
+        return (new TypedAncestorIterator(type));
+      case Axis.ANCESTORORSELF :
+        return ((new TypedAncestorIterator(type)).includeSelf());
+      case Axis.ATTRIBUTE :
+        return (new TypedAttributeIterator(type));
+      case Axis.DESCENDANT :
+        iterator = new TypedDescendantIterator(type);
+        break;
+      case Axis.DESCENDANTORSELF :
+        iterator = (new TypedDescendantIterator(type)).includeSelf();
+        break;
+      case Axis.FOLLOWING :
+        iterator = new TypedFollowingIterator(type);
+        break;
+      case Axis.PRECEDING :
+        iterator = new TypedPrecedingIterator(type);
+        break;
+      case Axis.FOLLOWINGSIBLING :
+        iterator = new TypedFollowingSiblingIterator(type);
+        break;
+      case Axis.PRECEDINGSIBLING :
+        iterator = new TypedPrecedingSiblingIterator(type);
+        break;
+      case Axis.NAMESPACE :
+        iterator = new TypedNamespaceIterator(type);
+        break;
+      case Axis.ROOT :
+        iterator = new TypedRootIterator(type);
+        break;
+      default :
+        throw new DTMException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED, 
+            new Object[]{Axis.getNames(axis)})); 
+            //"Error: typed iterator for axis "
+                               //+ Axis.names[axis] + "not implemented");
+      }
+    }
+
+    return (iterator);
+  }
+
+  /**
+   * This is a shortcut to the iterators that implement the
+   * XPath axes.
+   * Returns a bare-bones iterator that must be initialized
+   * with a start node (using iterator.setStartNode()).
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisIterator, or null if the given axis isn't supported.
+   */
+  public DTMAxisIterator getAxisIterator(final int axis)
+  {
+
+    DTMAxisIterator iterator = null;
+
+    switch (axis)
+    {
+    case Axis.SELF :
+      iterator = new SingletonIterator();
+      break;
+    case Axis.CHILD :
+      iterator = new ChildrenIterator();
+      break;
+    case Axis.PARENT :
+      return (new ParentIterator());
+    case Axis.ANCESTOR :
+      return (new AncestorIterator());
+    case Axis.ANCESTORORSELF :
+      return ((new AncestorIterator()).includeSelf());
+    case Axis.ATTRIBUTE :
+      return (new AttributeIterator());
+    case Axis.DESCENDANT :
+      iterator = new DescendantIterator();
+      break;
+    case Axis.DESCENDANTORSELF :
+      iterator = (new DescendantIterator()).includeSelf();
+      break;
+    case Axis.FOLLOWING :
+      iterator = new FollowingIterator();
+      break;
+    case Axis.PRECEDING :
+      iterator = new PrecedingIterator();
+      break;
+    case Axis.FOLLOWINGSIBLING :
+      iterator = new FollowingSiblingIterator();
+      break;
+    case Axis.PRECEDINGSIBLING :
+      iterator = new PrecedingSiblingIterator();
+      break;
+    case Axis.NAMESPACE :
+      iterator = new NamespaceIterator();
+      break;
+    case Axis.ROOT :
+      iterator = new RootIterator();
+      break;
+    default :
+      throw new DTMException(XMLMessages.createXMLMessage(
+        XMLErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED, 
+        new Object[]{Axis.getNames(axis)})); 
+        //"Error: iterator for axis '" + Axis.names[axis]
+                             //+ "' not implemented");
+    }
+
+    return (iterator);
+  }
+
+  /**
+   * Abstract superclass defining behaviors shared by all DTMDefault's
+   * internal implementations of DTMAxisIterator. Subclass this (and
+   * override, if necessary) to implement the specifics of an
+   * individual axis iterator.
+   *
+   * Currently there isn't a lot here
+   */
+  public abstract class InternalAxisIteratorBase extends DTMAxisIteratorBase
+  {
+
+    // %REVIEW% We could opt to share _nodeType and setNodeType() as
+    // well, and simply ignore them in iterators which don't use them.
+    // But Scott's worried about the overhead involved in cloning
+    // these, and wants them to have as few fields as possible. Note
+    // that we can't create a TypedInternalAxisIteratorBase because
+    // those are often based on the untyped versions and Java doesn't
+    // support multiple inheritance. <sigh/>
+
+    /**
+     * Current iteration location. Usually this is the last location
+     * returned (starting point for the next() search); for single-node
+     * iterators it may instead be initialized to point to that single node.
+     */
+    protected int _currentNode;
+
+    /**
+     * Remembers the current node for the next call to gotoMark().
+     *
+     * %REVIEW% Should this save _position too?
+     */
+    public void setMark()
+    {
+      _markedNode = _currentNode;
+    }
+
+    /**
+     * Restores the current node remembered by setMark().
+     *
+     * %REVEIW% Should this restore _position too?
+     */
+    public void gotoMark()
+    {
+      _currentNode = _markedNode;
+    }
+        
+  }  // end of InternalAxisIteratorBase 
+
+  /**
+   * Iterator that returns all immediate children of a given node
+   */
+  public final class ChildrenIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Setting start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * If the iterator is not restartable, this has no effect.
+     * %REVIEW% Should it return/throw something in that case,
+     * or set current node to END, to indicate request-not-honored?
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = (node == DTM.NULL) ? DTM.NULL
+                                          : _firstch(makeNodeIdentity(node));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END if no more
+     * are available.
+     */
+    public int next()
+    {
+      if (_currentNode != NULL) {
+        int node = _currentNode;
+        _currentNode = _nextsib(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+      return END;
+    }
+  }  // end of ChildrenIterator
+
+  /**
+   * Iterator that returns the parent of a given node. Note that
+   * this delivers only a single node; if you want all the ancestors,
+   * see AncestorIterator.
+   */
+  public final class ParentIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private int _nodeType = -1;
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = getParent(node);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Set the node type of the parent that we're looking for.
+     * Note that this does _not_ mean "find the nearest ancestor of
+     * this type", but "yield the parent if it is of this type".
+     *
+     *
+     * @param type extended type ID.
+     *
+     * @return ParentIterator configured with the type filter set.
+     */
+    public DTMAxisIterator setNodeType(final int type)
+    {
+
+      _nodeType = type;
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration. In this case, we return
+     * only the immediate parent, _if_ it matches the requested nodeType.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int result = _currentNode;
+
+      if (_nodeType >= DTM.NTYPES) {
+        if (_nodeType != getExpandedTypeID(_currentNode)) {
+          result = END;
+        }
+      } else if (_nodeType != NULL) {
+        if (_nodeType != getNodeType(_currentNode)) {
+          result = END;
+        }
+      }
+
+      _currentNode = END;
+
+      return returnNode(result);
+    }
+  }  // end of ParentIterator
+
+  /**
+   * Iterator that returns children of a given type for a given node.
+   * The functionality chould be achieved by putting a filter on top
+   * of a basic child iterator, but a specialised iterator is used
+   * for efficiency (both speed and size of translet).
+   */
+  public final class TypedChildrenIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedChildrenIterator
+     *
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedChildrenIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = (node == DTM.NULL)
+                                   ? DTM.NULL
+                                   : _firstch(makeNodeIdentity(_startNode));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int eType;
+      int node = _currentNode;
+
+      int nodeType = _nodeType;
+
+      if (nodeType >= DTM.NTYPES) {
+        while (node != DTM.NULL && _exptype(node) != nodeType) {
+          node = _nextsib(node);
+        }
+      } else {
+        while (node != DTM.NULL) {
+          eType = _exptype(node);
+          if (eType < DTM.NTYPES) {
+            if (eType == nodeType) {
+              break;
+            }
+          } else if (m_expandedNameTable.getType(eType) == nodeType) {
+            break;
+          }
+          node = _nextsib(node);
+        }
+      }
+
+      if (node == DTM.NULL) {
+        _currentNode = DTM.NULL;
+        return DTM.NULL;
+      } else {
+        _currentNode = _nextsib(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+    }
+  }  // end of TypedChildrenIterator
+
+  /**
+   * Iterator that returns children within a given namespace for a
+   * given node. The functionality chould be achieved by putting a
+   * filter on top of a basic child iterator, but a specialised
+   * iterator is used for efficiency (both speed and size of translet).
+   */
+  public final class NamespaceChildrenIterator
+          extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID being requested. */
+    private final int _nsType;
+
+    /**
+     * Constructor NamespaceChildrenIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public NamespaceChildrenIterator(final int type)
+    {
+      _nsType = type;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if (_currentNode != DTM.NULL) {
+        for (int node = (NOTPROCESSED == _currentNode)
+                                  ? _firstch(makeNodeIdentity(_startNode))
+                                  : _nextsib(_currentNode);
+             node != END;
+             node = _nextsib(node)) {
+          if (m_expandedNameTable.getNamespaceID(_exptype(node)) == _nsType) {
+            _currentNode = node;
+
+            return returnNode(node);
+          }
+        }
+      }
+
+      return END;
+    }
+  }  // end of NamespaceChildrenIterator
+  
+  /**
+   * Iterator that returns the namespace nodes as defined by the XPath data model 
+   * for a given node.
+   */
+  public class NamespaceIterator
+          extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Constructor NamespaceAttributeIterator
+     */
+    public NamespaceIterator()
+    {
+
+      super();
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = getFirstNamespaceNode(node, true);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int node = _currentNode;
+
+      if (DTM.NULL != node)
+        _currentNode = getNextNamespaceNode(_startNode, node, true);
+
+      return returnNode(node);
+    }
+  }  // end of NamespaceIterator
+  
+  /**
+   * Iterator that returns the namespace nodes as defined by the XPath data model 
+   * for a given node, filtered by extended type ID.
+   */
+  public class TypedNamespaceIterator extends NamespaceIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedNamespaceIterator
+     *
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedNamespaceIterator(int nodeType)
+    {
+      super();
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+    	int node;
+
+      for (node = _currentNode;
+           node != END;
+           node = getNextNamespaceNode(_startNode, node, true)) {
+        if (getExpandedTypeID(node) == _nodeType
+            || getNodeType(node) == _nodeType
+            || getNamespaceType(node) == _nodeType) {
+          _currentNode = node;
+
+          return returnNode(node);
+        }
+      }
+
+      return (_currentNode =END);
+    }
+  }  // end of TypedNamespaceIterator
+  
+  /**
+   * Iterator that returns the the root node as defined by the XPath data model 
+   * for a given node.
+   */
+  public class RootIterator
+          extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Constructor RootIterator
+     */
+    public RootIterator()
+    {
+
+      super();
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+
+      if (_isRestartable)
+      {
+        _startNode = getDocumentRoot(node);
+        _currentNode = NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if(_startNode == _currentNode)
+        return NULL;
+
+      _currentNode = _startNode;
+
+      return returnNode(_startNode);
+    }
+  }  // end of RootIterator
+  
+  /**
+   * Iterator that returns the namespace nodes as defined by the XPath data model 
+   * for a given node, filtered by extended type ID.
+   */
+  public class TypedRootIterator extends RootIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedRootIterator
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedRootIterator(int nodeType)
+    {
+      super();
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+    	if(_startNode == _currentNode)
+        return NULL;
+
+      int nodeType = _nodeType;
+      int node = _startNode;
+      int expType = getExpandedTypeID(node);
+
+      _currentNode = node;
+
+      if (nodeType >= DTM.NTYPES) {
+        if (nodeType == expType) {
+          return returnNode(node);
+        }
+      } else {
+        if (expType < DTM.NTYPES) {
+          if (expType == nodeType) {
+            return returnNode(node);
+          }
+        } else {
+          if (m_expandedNameTable.getType(expType) == nodeType) {
+            return returnNode(node);
+          }
+        }
+      }
+
+      return END;
+    }
+  }  // end of TypedRootIterator
+
+  /**
+   * Iterator that returns attributes within a given namespace for a node.
+   */
+  public final class NamespaceAttributeIterator
+          extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID being requested. */
+    private final int _nsType;
+
+    /**
+     * Constructor NamespaceAttributeIterator
+     *
+     *
+     * @param nsType The extended type ID being requested.
+     */
+    public NamespaceAttributeIterator(int nsType)
+    {
+
+      super();
+
+      _nsType = nsType;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = getFirstNamespaceNode(node, false);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int node = _currentNode;
+
+      if (DTM.NULL != node)
+        _currentNode = getNextNamespaceNode(_startNode, node, false);
+
+      return returnNode(node);
+    }
+  }  // end of NamespaceAttributeIterator
+
+  /**
+   * Iterator that returns all siblings of a given node.
+   */
+  public class FollowingSiblingIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = makeNodeIdentity(node);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
+                                                : _nextsib(_currentNode);
+      return returnNode(makeNodeHandle(_currentNode));
+    }
+  }  // end of FollowingSiblingIterator
+
+  /**
+   * Iterator that returns all following siblings of a given node.
+   */
+  public final class TypedFollowingSiblingIterator
+          extends FollowingSiblingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedFollowingSiblingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedFollowingSiblingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if (_currentNode == DTM.NULL) {
+        return DTM.NULL;
+      }
+
+      int node = _currentNode;
+      int eType;
+      int nodeType = _nodeType;
+
+      if (nodeType >= DTM.NTYPES) {
+        do {
+          node = _nextsib(node);
+        } while (node != DTM.NULL && _exptype(node) != nodeType);
+      } else {
+        while ((node = _nextsib(node)) != DTM.NULL) {
+          eType = _exptype(node);
+          if (eType < DTM.NTYPES) {
+            if (eType == nodeType) {
+              break;
+            }
+          } else if (m_expandedNameTable.getType(eType) == nodeType) {
+            break;
+          }
+        }
+      }
+
+      _currentNode = node;
+
+      return (_currentNode == DTM.NULL)
+                      ? DTM.NULL
+                      : returnNode(makeNodeHandle(_currentNode));
+    }
+  }  // end of TypedFollowingSiblingIterator
+
+  /**
+   * Iterator that returns attribute nodes (of what nodes?)
+   */
+  public final class AttributeIterator extends InternalAxisIteratorBase
+  {
+
+    // assumes caller will pass element nodes
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int node = _currentNode;
+
+      if (node != NULL) {
+        _currentNode = getNextAttributeIdentity(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+      return NULL;
+    }
+  }  // end of AttributeIterator
+
+  /**
+   * Iterator that returns attribute nodes of a given type
+   */
+  public final class TypedAttributeIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedAttributeIterator
+     *
+     *
+     * @param nodeType The extended type ID that is requested.
+     */
+    public TypedAttributeIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    // assumes caller will pass element nodes
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+      if (_isRestartable)
+      {
+        _startNode = node;
+
+        _currentNode = getTypedAttribute(node, _nodeType);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int node = _currentNode;
+
+      // singleton iterator, since there can only be one attribute of 
+      // a given type.
+      _currentNode = NULL;
+
+      return returnNode(node);
+    }
+  }  // end of TypedAttributeIterator
+
+  /**
+   * Iterator that returns preceding siblings of a given node
+   */
+  public class PrecedingSiblingIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * The node identity of _startNode for this iterator
+     */
+    protected int _startNodeID;
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true.
+     */
+    public boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        node = _startNodeID = makeNodeIdentity(node);
+
+        if(node == NULL)
+        {
+          _currentNode = node;
+          return resetPosition();
+        }
+
+        int type = m_expandedNameTable.getType(_exptype(node));
+        if(ExpandedNameTable.ATTRIBUTE == type 
+           || ExpandedNameTable.NAMESPACE == type )
+        {
+          _currentNode = node;
+        }
+        else
+        {
+          // Be careful to handle the Document node properly
+          _currentNode = _parent(node);
+          if(NULL!=_currentNode)	
+            _currentNode = _firstch(_currentNode);
+          else
+            _currentNode = node;
+        }
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
+      {
+        return NULL;
+      }
+      else
+      {
+        final int node = _currentNode;
+        _currentNode = _nextsib(node);
+
+        return returnNode(makeNodeHandle(node));
+      }
+    }
+  }  // end of PrecedingSiblingIterator
+
+  /**
+   * Iterator that returns preceding siblings of a given type for
+   * a given node
+   */
+  public final class TypedPrecedingSiblingIterator
+          extends PrecedingSiblingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedPrecedingSiblingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedPrecedingSiblingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node = _currentNode;
+      int expType;
+
+      int nodeType = _nodeType;
+      int startID = _startNodeID;
+
+      if (nodeType >= DTM.NTYPES) {
+        while (node != NULL && node != startID && _exptype(node) != nodeType) {
+          node = _nextsib(node);
+        }
+      } else {
+        while (node != NULL && node != startID) {
+          expType = _exptype(node);
+          if (expType < DTM.NTYPES) {
+            if (expType == nodeType) {
+              break;
+            }
+          } else {
+            if (m_expandedNameTable.getType(expType) == nodeType) {
+              break;
+            }
+          }
+          node = _nextsib(node);
+        }
+      }
+
+      if (node == DTM.NULL || node == _startNodeID) {
+        _currentNode = NULL;
+        return NULL;
+      } else {
+        _currentNode = _nextsib(node);
+        return returnNode(makeNodeHandle(node));
+      }
+    }
+  }  // end of TypedPrecedingSiblingIterator
+
+  /**
+   * Iterator that returns preceding nodes of a given node.
+   * This includes the node set {root+1, start-1}, but excludes
+   * all ancestors, attributes, and namespace nodes.
+   */
+  public class PrecedingIterator extends InternalAxisIteratorBase
+  {
+
+    /** The max ancestors, but it can grow... */
+    private final int _maxAncestors = 8;
+
+    /**
+     * The stack of start node + ancestors up to the root of the tree,
+     *  which we must avoid.
+     */
+    protected int[] _stack = new int[_maxAncestors];
+
+    /** (not sure yet... -sb) */
+    protected int _sp, _oldsp;
+
+    protected int _markedsp, _markedNode, _markedDescendant;
+
+    /* _currentNode precedes candidates.  This is the identity, not the handle! */
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true since this iterator is a reversed axis.
+     */
+    public boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Returns a deep copy of this iterator.   The cloned iterator is not reset.
+     *
+     * @return a deep copy of this iterator.
+     */
+    public DTMAxisIterator cloneIterator()
+    {
+      _isRestartable = false;
+
+      try
+      {
+        final PrecedingIterator clone = (PrecedingIterator) super.clone();
+        final int[] stackCopy = new int[_stack.length];
+        System.arraycopy(_stack, 0, stackCopy, 0, _stack.length);
+
+        clone._stack = stackCopy;
+
+        // return clone.reset();
+        return clone;
+      }
+      catch (CloneNotSupportedException e)
+      {
+        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
+      }
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        node = makeNodeIdentity(node);
+
+        // iterator is not a clone
+        int parent, index;
+
+       if (_type(node) == DTM.ATTRIBUTE_NODE)
+        node = _parent(node);
+
+        _startNode = node;
+        _stack[index = 0] = node;
+        
+       
+
+		parent=node;
+		while ((parent = _parent(parent)) != NULL)
+		{
+			if (++index == _stack.length)
+			{
+				final int[] stack = new int[index + 4];
+				System.arraycopy(_stack, 0, stack, 0, index);
+				_stack = stack;
+			}
+			_stack[index] = parent;
+        }
+        if(index>0)
+	        --index; // Pop actual root node (if not start) back off the stack
+
+        _currentNode=_stack[index]; // Last parent before root node
+
+        _oldsp = _sp = index;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+    	// Bugzilla 8324: We were forgetting to skip Attrs and NS nodes.
+    	// Also recoded the loop controls for clarity and to flatten out
+    	// the tail-recursion.
+   		for(++_currentNode; 
+   			_sp>=0; 
+   			++_currentNode)
+   		{
+   			if(_currentNode < _stack[_sp])
+   			{
+   				if(_type(_currentNode) != ATTRIBUTE_NODE &&
+   					_type(_currentNode) != NAMESPACE_NODE)
+   					return returnNode(makeNodeHandle(_currentNode));
+   			}
+   			else
+   				--_sp;
+   		}
+   		return NULL;
+    }
+
+    // redefine DTMAxisIteratorBase's reset
+
+    /**
+     * Resets the iterator to the last start node.
+     *
+     * @return A DTMAxisIterator, which may or may not be the same as this
+     *         iterator.
+     */
+    public DTMAxisIterator reset()
+    {
+
+      _sp = _oldsp;
+
+      return resetPosition();
+    }
+
+    public void setMark() {
+        _markedsp = _sp;
+        _markedNode = _currentNode;
+        _markedDescendant = _stack[0];
+    }
+
+    public void gotoMark() {
+        _sp = _markedsp;
+        _currentNode = _markedNode;
+    }
+  }  // end of PrecedingIterator
+
+  /**
+   * Iterator that returns preceding nodes of agiven type for a
+   * given node. This includes the node set {root+1, start-1}, but
+   * excludes all ancestors.
+   */
+  public final class TypedPrecedingIterator extends PrecedingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedPrecedingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedPrecedingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node = _currentNode;
+      int nodeType = _nodeType;
+
+      if (nodeType >= DTM.NTYPES) {
+        while (true) {
+          node = node + 1;
+
+          if (_sp < 0) {
+            node = NULL;
+            break;
+          } else if (node >= _stack[_sp]) {
+            if (--_sp < 0) {
+              node = NULL;
+              break;
+            }
+          } else if (_exptype(node) == nodeType) {
+            break;
+          }
+        }
+      } else {
+        int expType;
+
+        while (true) {
+          node = node + 1;
+
+          if (_sp < 0) {
+            node = NULL;
+            break;
+          } else if (node >= _stack[_sp]) {
+            if (--_sp < 0) {
+              node = NULL;
+              break;
+            }
+          } else {
+            expType = _exptype(node);
+            if (expType < DTM.NTYPES) {
+              if (expType == nodeType) {
+                break;
+              }
+            } else {
+              if (m_expandedNameTable.getType(expType) == nodeType) {
+                break;
+              }
+            }
+          }
+        }
+      }
+
+      _currentNode = node;
+             
+      return (node == NULL) ? NULL : returnNode(makeNodeHandle(node));
+    }
+  }  // end of TypedPrecedingIterator
+
+  /**
+   * Iterator that returns following nodes of for a given node.
+   */
+  public class FollowingIterator extends InternalAxisIteratorBase
+  {
+    DTMAxisTraverser m_traverser; // easier for now
+    
+    public FollowingIterator()
+    {
+      m_traverser = getAxisTraverser(Axis.FOLLOWING);
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+
+        // ?? -sb
+        // find rightmost descendant (or self)
+        // int current;
+        // while ((node = getLastChild(current = node)) != NULL){}
+        // _currentNode = current;
+        _currentNode = m_traverser.first(node);
+
+        // _currentNode precedes possible following(node) nodes
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int node = _currentNode;
+
+      _currentNode = m_traverser.next(_startNode, _currentNode);
+
+      return returnNode(node);
+    }
+  }  // end of FollowingIterator
+
+  /**
+   * Iterator that returns following nodes of a given type for a given node.
+   */
+  public final class TypedFollowingIterator extends FollowingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedFollowingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedFollowingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int node;
+
+      do{
+       node = _currentNode;
+
+      _currentNode = m_traverser.next(_startNode, _currentNode);
+
+      } 
+      while (node != DTM.NULL
+             && (getExpandedTypeID(node) != _nodeType && getNodeType(node) != _nodeType));
+
+      return (node == DTM.NULL ? DTM.NULL :returnNode(node));
+    }
+  }  // end of TypedFollowingIterator
+
+  /**
+   * Iterator that returns the ancestors of a given node in document
+   * order.  (NOTE!  This was changed from the XSLTC code!)
+   */
+  public class AncestorIterator extends InternalAxisIteratorBase
+  {
+    org.apache.xml.utils.NodeVector m_ancestors = 
+         new org.apache.xml.utils.NodeVector();
+         
+    int m_ancestorsPos;
+
+    int m_markedPos;
+    
+    /** The real start node for this axes, since _startNode will be adjusted. */
+    int m_realStartNode;
+    
+    /**
+     * Get start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @return The root node of the iteration.
+     */
+    public int getStartNode()
+    {
+      return m_realStartNode;
+    }
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true since this iterator is a reversed axis.
+     */
+    public final boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Returns a deep copy of this iterator.  The cloned iterator is not reset.
+     *
+     * @return a deep copy of this iterator.
+     */
+    public DTMAxisIterator cloneIterator()
+    {
+      _isRestartable = false;  // must set to false for any clone
+
+      try
+      {
+        final AncestorIterator clone = (AncestorIterator) super.clone();
+
+        clone._startNode = _startNode;
+
+        // return clone.reset();
+        return clone;
+      }
+      catch (CloneNotSupportedException e)
+      {
+        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
+      }
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      m_realStartNode = node;
+
+      if (_isRestartable)
+      {
+        int nodeID = makeNodeIdentity(node);
+
+        if (!_includeSelf && node != DTM.NULL) {
+          nodeID = _parent(nodeID);
+          node = makeNodeHandle(nodeID);
+        }
+
+        _startNode = node;
+
+        while (nodeID != END) {
+          m_ancestors.addElement(node);
+          nodeID = _parent(nodeID);
+          node = makeNodeHandle(nodeID);
+        }
+        m_ancestorsPos = m_ancestors.size()-1;
+
+        _currentNode = (m_ancestorsPos>=0)
+                               ? m_ancestors.elementAt(m_ancestorsPos)
+                               : DTM.NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Resets the iterator to the last start node.
+     *
+     * @return A DTMAxisIterator, which may or may not be the same as this
+     *         iterator.
+     */
+    public DTMAxisIterator reset()
+    {
+
+      m_ancestorsPos = m_ancestors.size()-1;
+
+      _currentNode = (m_ancestorsPos>=0) ? m_ancestors.elementAt(m_ancestorsPos)
+                                         : DTM.NULL;
+
+      return resetPosition();
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int next = _currentNode;
+      
+      int pos = --m_ancestorsPos;
+
+      _currentNode = (pos >= 0) ? m_ancestors.elementAt(m_ancestorsPos)
+                                : DTM.NULL;
+      
+      return returnNode(next);
+    }
+
+    public void setMark() {
+        m_markedPos = m_ancestorsPos;
+    }
+
+    public void gotoMark() {
+        m_ancestorsPos = m_markedPos;
+        _currentNode = m_ancestorsPos>=0 ? m_ancestors.elementAt(m_ancestorsPos)
+                                         : DTM.NULL;
+    }
+  }  // end of AncestorIterator
+
+  /**
+   * Typed iterator that returns the ancestors of a given node.
+   */
+  public final class TypedAncestorIterator extends AncestorIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedAncestorIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedAncestorIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      m_realStartNode = node;
+
+      if (_isRestartable)
+      {
+        int nodeID = makeNodeIdentity(node);
+        int nodeType = _nodeType;
+
+        if (!_includeSelf && node != DTM.NULL) {
+          nodeID = _parent(nodeID);
+        }
+
+        _startNode = node;
+
+        if (nodeType >= DTM.NTYPES) {
+          while (nodeID != END) {
+            int eType = _exptype(nodeID);
+
+            if (eType == nodeType) {
+              m_ancestors.addElement(makeNodeHandle(nodeID));
+            }
+            nodeID = _parent(nodeID);
+          }
+        } else {
+          while (nodeID != END) {
+            int eType = _exptype(nodeID);
+
+            if ((eType >= DTM.NTYPES
+                    && m_expandedNameTable.getType(eType) == nodeType)
+                || (eType < DTM.NTYPES && eType == nodeType)) {
+              m_ancestors.addElement(makeNodeHandle(nodeID));
+            }
+            nodeID = _parent(nodeID);
+          }
+        }
+        m_ancestorsPos = m_ancestors.size()-1;
+
+        _currentNode = (m_ancestorsPos>=0)
+                               ? m_ancestors.elementAt(m_ancestorsPos)
+                               : DTM.NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+  }  // end of TypedAncestorIterator
+
+  /**
+   * Iterator that returns the descendants of a given node.
+   */
+  public class DescendantIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        node = makeNodeIdentity(node);
+        _startNode = node;
+
+        if (_includeSelf)
+          node--;
+
+        _currentNode = node;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Tell if this node identity is a descendant.  Assumes that
+     * the node info for the element has already been obtained.
+     *
+     * This one-sided test works only if the parent has been
+     * previously tested and is known to be a descendent. It fails if
+     * the parent is the _startNode's next sibling, or indeed any node
+     * that follows _startNode in document order.  That may suffice
+     * for this iterator, but it's not really an isDescendent() test.
+     * %REVIEW% rename?
+     *
+     * @param identity The index number of the node in question.
+     * @return true if the index is a descendant of _startNode.
+     */
+    protected boolean isDescendant(int identity)
+    {
+      return (_parent(identity) >= _startNode) || (_startNode == identity);
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if (_startNode == NULL) {
+        return NULL;
+      }
+
+      if (_includeSelf && (_currentNode + 1) == _startNode)
+          return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent);
+
+      int node = _currentNode;
+      int type;
+
+      do {
+        node++;
+        type = _type(node);
+
+        if (NULL == type ||!isDescendant(node)) {
+          _currentNode = NULL;
+          return END;
+        }
+      } while(ATTRIBUTE_NODE == type || TEXT_NODE == type
+                 || NAMESPACE_NODE == type);
+
+      _currentNode = node;
+      return returnNode(makeNodeHandle(node));  // make handle.
+    }
+  
+    /**
+     * Reset.
+     *
+     */ 
+  public DTMAxisIterator reset()
+  {
+
+    final boolean temp = _isRestartable;
+
+    _isRestartable = true;
+
+    setStartNode(makeNodeHandle(_startNode));
+
+    _isRestartable = temp;
+
+    return this;
+  }
+    
+  }  // end of DescendantIterator
+
+  /**
+   * Typed iterator that returns the descendants of a given node.
+   */
+  public final class TypedDescendantIterator extends DescendantIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedDescendantIterator
+     *
+     *
+     * @param nodeType Extended type ID being requested.
+     */
+    public TypedDescendantIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node;
+      int type;
+
+      if (_startNode == NULL) {
+        return NULL;
+      }
+
+      node = _currentNode;
+
+      do
+      {
+        node++;
+        type = _type(node);
+
+        if (NULL == type ||!isDescendant(node)) {
+          _currentNode = NULL;
+          return END;
+        }
+      }
+      while (type != _nodeType && _exptype(node) != _nodeType);
+
+      _currentNode = node;
+      return returnNode(makeNodeHandle(node));
+    }
+  }  // end of TypedDescendantIterator
+
+  /**
+   * Iterator that returns the descendants of a given node.
+   * I'm not exactly clear about this one... -sb
+   */
+  public class NthDescendantIterator extends DescendantIterator
+  {
+
+    /** The current nth position. */
+    int _pos;
+
+    /**
+     * Constructor NthDescendantIterator
+     *
+     *
+     * @param pos The nth position being requested.
+     */
+    public NthDescendantIterator(int pos)
+    {
+      _pos = pos;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      // I'm not exactly clear yet what this is doing... -sb
+      int node;
+
+      while ((node = super.next()) != END)
+      {
+        node = makeNodeIdentity(node);
+
+        int parent = _parent(node);
+        int child = _firstch(parent);
+        int pos = 0;
+
+        do
+        {
+          int type = _type(child);
+
+          if (ELEMENT_NODE == type)
+            pos++;
+        }
+        while ((pos < _pos) && (child = _nextsib(child)) != END);
+
+        if (node == child)
+          return node;
+      }
+
+      return (END);
+    }
+  }  // end of NthDescendantIterator
+
+  /**
+   * Class SingletonIterator.
+   */
+  public class SingletonIterator extends InternalAxisIteratorBase
+  {
+
+    /** (not sure yet what this is.  -sb)  (sc & sb remove final to compile in JDK 1.1.8) */
+    private boolean _isConstant;
+
+    /**
+     * Constructor SingletonIterator
+     *
+     */
+    public SingletonIterator()
+    {
+      this(Integer.MIN_VALUE, false);
+    }
+
+    /**
+     * Constructor SingletonIterator
+     *
+     *
+     * @param node The node handle to return.
+     */
+    public SingletonIterator(int node)
+    {
+      this(node, false);
+    }
+
+    /**
+     * Constructor SingletonIterator
+     *
+     *
+     * @param node the node handle to return.
+     * @param constant (Not sure what this is yet.  -sb)
+     */
+    public SingletonIterator(int node, boolean constant)
+    {
+      _currentNode = _startNode = node;
+      _isConstant = constant;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isConstant)
+      {
+        _currentNode = _startNode;
+
+        return resetPosition();
+      }
+      else if (_isRestartable)
+      {
+        _currentNode = _startNode = node;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Resets the iterator to the last start node.
+     *
+     * @return A DTMAxisIterator, which may or may not be the same as this
+     *         iterator.
+     */
+    public DTMAxisIterator reset()
+    {
+
+      if (_isConstant)
+      {
+        _currentNode = _startNode;
+
+        return resetPosition();
+      }
+      else
+      {
+        final boolean temp = _isRestartable;
+
+        _isRestartable = true;
+
+        setStartNode(_startNode);
+
+        _isRestartable = temp;
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int result = _currentNode;
+
+      _currentNode = END;
+
+      return returnNode(result);
+    }
+  }  // end of SingletonIterator
+
+  /**
+   * Iterator that returns a given node only if it is of a given type.
+   */
+  public final class TypedSingletonIterator extends SingletonIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedSingletonIterator
+     *
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedSingletonIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      //final int result = super.next();
+      final int result = _currentNode;
+      int nodeType = _nodeType;
+
+      _currentNode = END;
+
+      if (nodeType >= DTM.NTYPES) {
+        if (getExpandedTypeID(result) == nodeType) {
+          return returnNode(result);
+        }
+      } else {
+        if (getNodeType(result) == nodeType) {
+          return returnNode(result);
+        }
+      }
+
+      return NULL;
+    }
+  }  // end of TypedSingletonIterator
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java
new file mode 100644
index 0000000..0984fec
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java
@@ -0,0 +1,1744 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMDefaultBaseTraversers.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.*;
+
+import javax.xml.transform.Source;
+
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+/**
+ * This class implements the traversers for DTMDefaultBase.
+ *
+ * PLEASE NOTE that the public interface for all traversers should be
+ * in terms of DTM Node Handles... but they may use the internal node
+ * identity indices within their logic, for efficiency's sake. Be very
+ * careful to avoid confusing these when maintaining this code.
+ * */
+public abstract class DTMDefaultBaseTraversers extends DTMDefaultBase
+{
+
+  /**
+   * Construct a DTMDefaultBaseTraversers object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   */
+  public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
+                                  int dtmIdentity,
+                                  DTMWSFilter whiteSpaceFilter,
+                                  XMLStringFactory xstringfactory,
+                                  boolean doIndexing)
+  {
+    super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
+          doIndexing);
+  }
+
+  /**
+   * Construct a DTMDefaultBaseTraversers object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source The object that is used to specify the construction source.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory The factory to use for creating XMLStrings.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   * @param blocksize The block size of the DTM.
+   * @param usePrevsib true if we want to build the previous sibling node array.
+   * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
+   */
+  public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
+                                  int dtmIdentity,
+                                  DTMWSFilter whiteSpaceFilter,
+                                  XMLStringFactory xstringfactory,
+                                  boolean doIndexing,
+                                  int blocksize,
+                                  boolean usePrevsib,
+                                  boolean newNameTable)
+  {
+    super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
+          doIndexing, blocksize, usePrevsib, newNameTable);
+  }
+
+  /**
+   * This returns a stateless "traverser", that can navigate
+   * over an XPath axis, though perhaps not in document order.
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisTraverser, or null if the given axis isn't supported.
+   */
+  public DTMAxisTraverser getAxisTraverser(final int axis)
+  {
+
+    DTMAxisTraverser traverser;
+
+    if (null == m_traversers)  // Cache of stateless traversers for this DTM
+    {
+      m_traversers = new DTMAxisTraverser[Axis.getNamesLength()];
+      traverser = null;
+    }
+    else
+    {
+      traverser = m_traversers[axis];  // Share/reuse existing traverser
+
+      if (traverser != null)
+        return traverser;
+    }
+
+    switch (axis)  // Generate new traverser
+    {
+    case Axis.ANCESTOR :
+      traverser = new AncestorTraverser();
+      break;
+    case Axis.ANCESTORORSELF :
+      traverser = new AncestorOrSelfTraverser();
+      break;
+    case Axis.ATTRIBUTE :
+      traverser = new AttributeTraverser();
+      break;
+    case Axis.CHILD :
+      traverser = new ChildTraverser();
+      break;
+    case Axis.DESCENDANT :
+      traverser = new DescendantTraverser();
+      break;
+    case Axis.DESCENDANTORSELF :
+      traverser = new DescendantOrSelfTraverser();
+      break;
+    case Axis.FOLLOWING :
+      traverser = new FollowingTraverser();
+      break;
+    case Axis.FOLLOWINGSIBLING :
+      traverser = new FollowingSiblingTraverser();
+      break;
+    case Axis.NAMESPACE :
+      traverser = new NamespaceTraverser();
+      break;
+    case Axis.NAMESPACEDECLS :
+      traverser = new NamespaceDeclsTraverser();
+      break;
+    case Axis.PARENT :
+      traverser = new ParentTraverser();
+      break;
+    case Axis.PRECEDING :
+      traverser = new PrecedingTraverser();
+      break;
+    case Axis.PRECEDINGSIBLING :
+      traverser = new PrecedingSiblingTraverser();
+      break;
+    case Axis.SELF :
+      traverser = new SelfTraverser();
+      break;
+    case Axis.ALL :
+      traverser = new AllFromRootTraverser();
+      break;
+    case Axis.ALLFROMNODE :
+      traverser = new AllFromNodeTraverser();
+      break;
+    case Axis.PRECEDINGANDANCESTOR :
+      traverser = new PrecedingAndAncestorTraverser();
+      break;
+    case Axis.DESCENDANTSFROMROOT :
+      traverser = new DescendantFromRootTraverser();
+      break;
+    case Axis.DESCENDANTSORSELFFROMROOT :
+      traverser = new DescendantOrSelfFromRootTraverser();
+      break;
+    case Axis.ROOT :
+      traverser = new RootTraverser();
+      break;
+    case Axis.FILTEREDLIST :
+      return null; // Don't want to throw an exception for this one.
+    default :
+      throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_UNKNOWN_AXIS_TYPE, new Object[]{Integer.toString(axis)})); //"Unknown axis traversal type: "+axis);
+    }
+
+    if (null == traverser)
+      throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_AXIS_TRAVERSER_NOT_SUPPORTED, new Object[]{Axis.getNames(axis)}));
+      // "Axis traverser not supported: "
+      //                       + Axis.names[axis]);
+
+    m_traversers[axis] = traverser;
+
+    return traverser;
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class AncestorTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node if this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+			return getParent(current);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Process using identities
+      current = makeNodeIdentity(current);
+
+      while (DTM.NULL != (current = m_parent.elementAt(current)))
+      {
+        if (m_exptype.elementAt(current) == expandedTypeID)
+          return makeNodeHandle(current);
+      }
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class AncestorOrSelfTraverser extends AncestorTraverser
+  {
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  To see if
+     * the self node should be processed, use this function.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return context;
+    }
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  To see if
+     * the self node should be processed, use this function.  If the context
+     * node does not match the expanded type ID, this function will return
+     * false.
+     *
+     * @param context The context node of this traversal.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+			return (getExpandedTypeID(context) == expandedTypeID)
+             ? context : next(context, context, expandedTypeID);
+    }
+  }
+
+  /**
+   * Implements traversal of the Attribute access
+   */
+  private class AttributeTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+      return (context == current)
+             ? getFirstAttribute(context) : getNextAttribute(current);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      current = (context == current)
+                ? getFirstAttribute(context) : getNextAttribute(current);
+
+      do
+      {
+        if (getExpandedTypeID(current) == expandedTypeID)
+          return current;
+      }
+      while (DTM.NULL != (current = getNextAttribute(current)));
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class ChildTraverser extends DTMAxisTraverser
+  {
+    
+    /**
+     * Get the next indexed node that matches the expanded type ID.  Before 
+     * calling this function, one should first call 
+     * {@link #isIndexed(int) isIndexed} to make sure that the index can 
+     * contain nodes that match the given expanded type ID.
+     *
+     * @param axisRoot The root identity of the axis.
+     * @param nextPotential The node found must match or occur after this node.
+     * @param expandedTypeID The expanded type ID for the request.
+     *
+     * @return The node ID or NULL if not found.
+     */
+    protected int getNextIndexed(int axisRoot, int nextPotential,
+                                 int expandedTypeID)
+    {
+
+      int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
+      int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
+
+      for (; ; ) 
+      {
+        int nextID = findElementFromIndex(nsIndex, lnIndex, nextPotential);
+
+        if (NOTPROCESSED != nextID)
+        {
+          int parentID = m_parent.elementAt(nextID);
+          
+          // Is it a child?
+          if(parentID == axisRoot)
+            return nextID;
+          
+          // If the parent occured before the subtree root, then 
+          // we know it is past the child axis.
+          if(parentID < axisRoot)
+              return NULL;
+          
+          // Otherwise, it could be a descendant below the subtree root 
+          // children, or it could be after the subtree root.  So we have 
+          // to climb up until the parent is less than the subtree root, in 
+          // which case we return NULL, or until it is equal to the subtree 
+          // root, in which case we continue to look.
+          do
+          {
+            parentID = m_parent.elementAt(parentID);
+            if(parentID < axisRoot)
+              return NULL;
+          }
+            while(parentID > axisRoot);
+          
+          // System.out.println("Found node via index: "+first);
+          nextPotential = nextID+1;
+          continue;
+        }
+
+        nextNode();
+        
+        if(!(m_nextsib.elementAt(axisRoot) == NOTPROCESSED))
+          break;
+      }
+
+      return DTM.NULL;
+    }
+        
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse 
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * that the traversal starts from.
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return getFirstChild(context);
+    }
+  
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse 
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      if(true)
+      {
+        int identity = makeNodeIdentity(context);
+        
+        int firstMatch = getNextIndexed(identity, _firstch(identity),
+                                 expandedTypeID);
+       
+        return makeNodeHandle(firstMatch);
+      }
+      else
+      {
+				// %REVIEW% Dead code. Eliminate?
+        for (int current = _firstch(makeNodeIdentity(context)); 
+             DTM.NULL != current; 
+             current = _nextsib(current)) 
+        {
+          if (m_exptype.elementAt(current) == expandedTypeID)
+              return makeNodeHandle(current);
+        }
+        return NULL;
+      }
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+      return getNextSibling(current);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Process in Identifier space
+      for (current = _nextsib(makeNodeIdentity(current)); 
+           DTM.NULL != current; 
+           current = _nextsib(current)) 
+      {
+        if (m_exptype.elementAt(current) == expandedTypeID)
+            return makeNodeHandle(current);
+      }
+      
+      return NULL;
+    }
+  }
+
+  /**
+   * Super class for derived classes that want a convenient way to access 
+   * the indexing mechanism.
+   */
+  private abstract class IndexedDTMAxisTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Tell if the indexing is on and the given expanded type ID matches 
+     * what is in the indexes.  Derived classes should call this before 
+     * calling {@link #getNextIndexed(int, int, int) getNextIndexed} method.
+     *
+     * @param expandedTypeID The expanded type ID being requested.
+     *
+     * @return true if it is OK to call the 
+     *         {@link #getNextIndexed(int, int, int) getNextIndexed} method.
+     */
+    protected final boolean isIndexed(int expandedTypeID)
+    {
+      return (m_indexing
+              && ExpandedNameTable.ELEMENT
+                 == m_expandedNameTable.getType(expandedTypeID)); 
+    }
+
+    /**
+     * Tell if a node is outside the axis being traversed.  This method must be 
+     * implemented by derived classes, and must be robust enough to handle any 
+     * node that occurs after the axis root.
+     *
+     * @param axisRoot The root identity of the axis.
+     * @param identity The node in question.
+     *
+     * @return true if the given node falls outside the axis being traversed.
+     */
+    protected abstract boolean isAfterAxis(int axisRoot, int identity);
+
+    /**
+     * Tell if the axis has been fully processed to tell if a the wait for 
+     * an arriving node should terminate.  This method must be implemented 
+     * be a derived class.
+     *
+     * @param axisRoot The root identity of the axis.
+     *
+     * @return true if the axis has been fully processed.
+     */
+    protected abstract boolean axisHasBeenProcessed(int axisRoot);
+
+    /**
+     * Get the next indexed node that matches the expanded type ID.  Before 
+     * calling this function, one should first call 
+     * {@link #isIndexed(int) isIndexed} to make sure that the index can 
+     * contain nodes that match the given expanded type ID.
+     *
+     * @param axisRoot The root identity of the axis.
+     * @param nextPotential The node found must match or occur after this node.
+     * @param expandedTypeID The expanded type ID for the request.
+     *
+     * @return The node ID or NULL if not found.
+     */
+    protected int getNextIndexed(int axisRoot, int nextPotential,
+                                 int expandedTypeID)
+    {
+
+      int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
+      int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
+
+      while(true)
+      {
+        int next = findElementFromIndex(nsIndex, lnIndex, nextPotential);
+
+        if (NOTPROCESSED != next)
+        {
+          if (isAfterAxis(axisRoot, next))
+            return NULL;
+
+          // System.out.println("Found node via index: "+first);
+          return next;
+        }
+        else if(axisHasBeenProcessed(axisRoot))
+          break;
+
+        nextNode();
+      }
+
+      return DTM.NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class DescendantTraverser extends IndexedDTMAxisTraverser
+  {
+    /**
+     * Get the first potential identity that can be returned.  This should 
+     * be overridded by classes that need to return the self node.
+     *
+     * @param identity The node identity of the root context of the traversal.
+     *
+     * @return The first potential node that can be in the traversal.
+     */
+    protected int getFirstPotential(int identity)
+    {
+      return identity + 1;
+    }
+    
+    /**
+     * Tell if the axis has been fully processed to tell if a the wait for 
+     * an arriving node should terminate.
+     *
+     * @param axisRoot The root identity of the axis.
+     *
+     * @return true if the axis has been fully processed.
+     */
+    protected boolean axisHasBeenProcessed(int axisRoot)
+    {
+      return !(m_nextsib.elementAt(axisRoot) == NOTPROCESSED);
+    }
+    
+    /**
+     * Get the subtree root identity from the handle that was passed in by 
+     * the caller.  Derived classes may override this to change the root 
+     * context of the traversal.
+     * 
+     * @param handle handle to the root context.
+     * @return identity of the root of the subtree.
+     */
+    protected int getSubtreeRoot(int handle)
+    {
+      return makeNodeIdentity(handle);
+    }
+
+    /**
+     * Tell if this node identity is a descendant.  Assumes that
+     * the node info for the element has already been obtained.
+     *
+     * %REVIEW% This is really parentFollowsRootInDocumentOrder ...
+     * which fails if the parent starts after the root ends.
+     * May be sufficient for this class's logic, but misleadingly named!
+     *
+     * @param subtreeRootIdentity The root context of the subtree in question.
+     * @param identity The index number of the node in question.
+     * @return true if the index is a descendant of _startNode.
+     */
+    protected boolean isDescendant(int subtreeRootIdentity, int identity)
+    {
+      return _parent(identity) >= subtreeRootIdentity;
+    }
+
+    /**
+     * Tell if a node is outside the axis being traversed.  This method must be 
+     * implemented by derived classes, and must be robust enough to handle any 
+     * node that occurs after the axis root.
+     *
+     * @param axisRoot The root identity of the axis.
+     * @param identity The node in question.
+     *
+     * @return true if the given node falls outside the axis being traversed.
+     */
+    protected boolean isAfterAxis(int axisRoot, int identity)
+    {   
+      // %REVIEW% Is there *any* cheaper way to do this?
+			// Yes. In ID space, compare to axisRoot's successor
+			// (next-sib or ancestor's-next-sib). Probably shallower search.
+      do
+      {
+        if(identity == axisRoot)
+          return false;
+        identity = m_parent.elementAt(identity);
+      }
+        while(identity >= axisRoot);
+        
+      return true;
+    }
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+
+      if (isIndexed(expandedTypeID))
+      {
+        int identity = getSubtreeRoot(context);
+        int firstPotential = getFirstPotential(identity);
+
+        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
+      }
+
+      return next(context, context, expandedTypeID);
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+
+      int subtreeRootIdent = getSubtreeRoot(context);
+
+      for (current = makeNodeIdentity(current) + 1; ; current++)
+      {
+        int type = _type(current);  // may call nextNode()
+
+        if (!isDescendant(subtreeRootIdent, current))
+          return NULL;
+
+        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      int subtreeRootIdent = getSubtreeRoot(context);
+
+      current = makeNodeIdentity(current) + 1;
+
+      if (isIndexed(expandedTypeID))
+      {
+        return makeNodeHandle(getNextIndexed(subtreeRootIdent, current, expandedTypeID));
+      }
+
+      for (; ; current++)
+      {
+        int exptype = _exptype(current);  // may call nextNode()
+
+        if (!isDescendant(subtreeRootIdent, current))
+          return NULL;
+
+        if (exptype != expandedTypeID)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class DescendantOrSelfTraverser extends DescendantTraverser
+  {
+
+    /**
+     * Get the first potential identity that can be returned, which is the 
+     * axis context, in this case.
+     *
+     * @param identity The node identity of the root context of the traversal.
+     *
+     * @return The axis context.
+     */
+    protected int getFirstPotential(int identity)
+    {
+      return identity;
+    }
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  To see if
+     * the self node should be processed, use this function.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return context;
+    }
+  }
+
+  /**
+   * Implements traversal of the entire subtree, including the root node.
+   */
+  private class AllFromNodeTraverser extends DescendantOrSelfTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) + 1; ; current++)
+      {
+        // Trickological code: _exptype() has the side-effect of
+        // running nextNode until the specified node has been loaded,
+        // and thus can be used to ensure that incremental construction of
+        // the DTM has gotten this far. Using it just for that side-effect
+        // is quite a kluge...
+        _exptype(current);  // make sure it's here.
+
+        if (!isDescendant(subtreeRootIdent, current))
+          return NULL;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+  }
+
+  /**
+   * Implements traversal of the following access, in document order.
+   */
+  private class FollowingTraverser extends DescendantTraverser
+  {
+
+    /**
+     * Get the first of the following.
+     *
+     * @param context The context node of this traversal. This is the point
+     * that the traversal starts from.
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+			// Compute in ID space
+			context=makeNodeIdentity(context);
+
+      int first;
+      int type = _type(context);
+
+      if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
+      {
+        context = _parent(context);
+        first = _firstch(context);
+
+        if (NULL != first)
+          return makeNodeHandle(first);
+      }
+
+      do
+      {
+        first = _nextsib(context);
+
+        if (NULL == first)
+          context = _parent(context);
+      }
+      while (NULL == first && NULL != context);
+
+      return makeNodeHandle(first);
+    }
+
+    /**
+     * Get the first of the following.
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+			// %REVIEW% This looks like it might want shift into identity space
+			// to avoid repeated conversion in the individual functions
+      int first;
+      int type = getNodeType(context);
+
+      if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
+      {
+        context = getParent(context);
+        first = getFirstChild(context);
+
+        if (NULL != first)
+        {
+          if (getExpandedTypeID(first) == expandedTypeID)
+            return first;
+          else
+            return next(context, first, expandedTypeID);
+        }
+      }
+
+      do
+      {
+        first = getNextSibling(context);
+
+        if (NULL == first)
+          context = getParent(context);
+        else
+        {
+          if (getExpandedTypeID(first) == expandedTypeID)
+            return first;
+          else
+            return next(context, first, expandedTypeID);
+        }
+      }
+      while (NULL == first && NULL != context);
+
+      return first;
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+			// Compute in identity space
+			current=makeNodeIdentity(current);
+
+      while (true)
+      {
+        current++; // Only works on IDs, not handles.
+
+				// %REVIEW% Are we using handles or indexes?
+        int type = _type(current);  // may call nextNode()
+
+        if (NULL == type)
+          return NULL;
+
+        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Compute in ID space
+			current=makeNodeIdentity(current);
+
+      while (true)
+      {
+        current++;
+
+        int etype = _exptype(current);  // may call nextNode()
+
+        if (NULL == etype)
+          return NULL;
+
+        if (etype != expandedTypeID)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class FollowingSiblingTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+      return getNextSibling(current);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      while (DTM.NULL != (current = getNextSibling(current)))
+      {
+        if (getExpandedTypeID(current) == expandedTypeID)
+          return current;
+      }
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class NamespaceDeclsTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+
+      return (context == current)
+             ? getFirstNamespaceNode(context, false)
+             : getNextNamespaceNode(context, current, false);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      current = (context == current)
+                ? getFirstNamespaceNode(context, false)
+                : getNextNamespaceNode(context, current, false);
+
+      do
+      {
+        if (getExpandedTypeID(current) == expandedTypeID)
+          return current;
+      }
+      while (DTM.NULL
+             != (current = getNextNamespaceNode(context, current, false)));
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class NamespaceTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+
+      return (context == current)
+             ? getFirstNamespaceNode(context, true)
+             : getNextNamespaceNode(context, current, true);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      current = (context == current)
+                ? getFirstNamespaceNode(context, true)
+                : getNextNamespaceNode(context, current, true);
+
+      do
+      {
+        if (getExpandedTypeID(current) == expandedTypeID)
+          return current;
+      }
+      while (DTM.NULL
+             != (current = getNextNamespaceNode(context, current, true)));
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class ParentTraverser extends DTMAxisTraverser
+  {
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse 
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * that the traversal starts from.
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return getParent(context);
+    }
+  
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse 
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int current, int expandedTypeID)
+    {
+			// Compute in ID space
+      current = makeNodeIdentity(current);
+
+      while (NULL != (current = m_parent.elementAt(current)))
+      {
+        if (m_exptype.elementAt(current) == expandedTypeID)
+          return makeNodeHandle(current);
+      }
+
+      return NULL;
+    }
+
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+
+      return NULL;
+    }
+    
+
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class PrecedingTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Tell if the current identity is an ancestor of the context identity.
+     * This is an expensive operation, made worse by the stateless traversal.
+     * But the preceding axis is used fairly infrequently.
+     *
+     * @param contextIdent The context node of the axis traversal.
+     * @param currentIdent The node in question.
+     * @return true if the currentIdent node is an ancestor of contextIdent.
+     */
+    protected boolean isAncestor(int contextIdent, int currentIdent)
+    {
+			// %REVIEW% See comments in IsAfterAxis; using the "successor" of
+			// contextIdent is probably more efficient.
+      for (contextIdent = m_parent.elementAt(contextIdent); DTM.NULL != contextIdent;
+              contextIdent = m_parent.elementAt(contextIdent))
+      {
+        if (contextIdent == currentIdent)
+          return true;
+      }
+
+      return false;
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+			// compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
+      {
+        short type = _type(current);
+
+        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type
+                || isAncestor(subtreeRootIdent, current))
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+
+      return NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
+      {
+        int exptype = m_exptype.elementAt(current);
+
+        if (exptype != expandedTypeID
+                || isAncestor(subtreeRootIdent, current))
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor and the Preceding axis,
+   * in reverse document order.
+   */
+  private class PrecedingAndAncestorTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+			// Compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context );
+
+      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
+      {
+        short type = _type(current);
+
+        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+
+      return NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
+      {
+        int exptype = m_exptype.elementAt(current);
+
+        if (exptype != expandedTypeID)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class PrecedingSiblingTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+      return getPreviousSibling(current);
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+
+      while (DTM.NULL != (current = getPreviousSibling(current)))
+      {
+        if (getExpandedTypeID(current) == expandedTypeID)
+          return current;
+      }
+
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Self axis.
+   */
+  private class SelfTraverser extends DTMAxisTraverser
+  {
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  To see if
+     * the self node should be processed, use this function.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return context;
+    }
+
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  To see if
+     * the self node should be processed, use this function.  If the context
+     * node does not match the expanded type ID, this function will return
+     * false.
+     *
+     * @param context The context node of this traversal.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      return (getExpandedTypeID(context) == expandedTypeID) ? context : NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return Always return NULL for this axis.
+     */
+    public int next(int context, int current)
+    {
+      return NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+      return NULL;
+    }
+  }
+
+  /**
+   * Implements traversal of the Ancestor access, in reverse document order.
+   */
+  private class AllFromRootTraverser extends AllFromNodeTraverser
+  {
+
+    /**
+     * Return the root.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return getDocumentRoot(context);
+    }
+
+    /**
+     * Return the root if it matches the expanded type ID.
+     *
+     * @param context The context node of this traversal.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      return (getExpandedTypeID(getDocumentRoot(context)) == expandedTypeID)
+             ? context : next(context, context, expandedTypeID);
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current)
+    {
+			// Compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) + 1; ; current++)
+      {
+				// Kluge test: Just make sure +1 yielded a real node
+        int type = _type(current);  // may call nextNode()
+        if (type == NULL)
+          return NULL;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+			// Compute in ID space
+      int subtreeRootIdent = makeNodeIdentity(context);
+
+      for (current = makeNodeIdentity(current) + 1; ; current++)
+      {
+        int exptype = _exptype(current);  // may call nextNode()
+
+        if (exptype == NULL)
+          return NULL;
+
+        if (exptype != expandedTypeID)
+          continue;
+
+        return makeNodeHandle(current);  // make handle.
+      }
+    }
+  }
+
+  /**
+   * Implements traversal of the Self axis.
+   */
+  private class RootTraverser extends AllFromRootTraverser
+  {
+    /**
+     * Return the root if it matches the expanded type ID,
+     * else return null (nothing found)
+     *
+     * @param context The context node of this traversal.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      int root=getDocumentRoot(context);
+      return (getExpandedTypeID(root) == expandedTypeID)
+	? root : NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     *
+     * @return Always return NULL for this axis.
+     */
+    public int next(int context, int current)
+    {
+      return NULL;
+    }
+
+    /**
+     * Traverse to the next node after the current node that is matched
+     * by the expanded type ID.
+     *
+     * @param context The context node of this iteration.
+     * @param current The current node of the iteration.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the next node in the iteration, or DTM.NULL.
+     */
+    public int next(int context, int current, int expandedTypeID)
+    {
+      return NULL;
+    }
+  }
+
+  /**
+   * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
+   * from and including the root.
+   */
+  private class DescendantOrSelfFromRootTraverser extends DescendantTraverser
+  {
+
+    /**
+     * Get the first potential identity that can be returned, which is the axis 
+     * root context in this case.
+     *
+     * @param identity The node identity of the root context of the traversal.
+     *
+     * @return The identity argument.
+     */
+    protected int getFirstPotential(int identity)
+    {
+      return identity;
+    }
+
+    /**
+     * Get the first potential identity that can be returned.
+     * @param handle handle to the root context.
+     * @return identity of the root of the subtree.
+     */
+    protected int getSubtreeRoot(int handle)
+    {
+			// %REVIEW% Shouldn't this always be 0?
+      return makeNodeIdentity(getDocument());
+    }
+
+    /**
+     * Return the root.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return getDocumentRoot(context);
+    }
+    
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      if (isIndexed(expandedTypeID))
+      {
+        int identity = 0;
+        int firstPotential = getFirstPotential(identity);
+
+        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
+      }
+
+      int root = first(context); 
+      return next(root, root, expandedTypeID);
+    }
+  }
+  
+  /**
+   * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
+   * from but not including the root.
+   */
+  private class DescendantFromRootTraverser extends DescendantTraverser
+  {
+
+    /**
+     * Get the first potential identity that can be returned, which is the axis 
+     * root context in this case.
+     *
+     * @param identity The node identity of the root context of the traversal.
+     *
+     * @return The identity argument.
+     */
+    protected int getFirstPotential(int identity)
+    {
+      return _firstch(0);
+    }
+
+    /**
+     * Get the first potential identity that can be returned.
+     * @param handle handle to the root context.
+     * @return identity of the root of the subtree.
+     */
+    protected int getSubtreeRoot(int handle)
+    {
+      return 0;
+    }
+
+    /**
+     * Return the root.
+     *
+     * @param context The context node of this traversal.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context)
+    {
+      return makeNodeHandle(_firstch(0));
+    }
+    
+    /**
+     * By the nature of the stateless traversal, the context node can not be
+     * returned or the iteration will go into an infinate loop.  So to traverse
+     * an axis, the first function must be used to get the first node.
+     *
+     * <p>This method needs to be overloaded only by those axis that process
+     * the self node. <\p>
+     *
+     * @param context The context node of this traversal. This is the point
+     * of origin for the traversal -- its "root node" or starting point.
+     * @param expandedTypeID The expanded type ID that must match.
+     *
+     * @return the first node in the traversal.
+     */
+    public int first(int context, int expandedTypeID)
+    {
+      if (isIndexed(expandedTypeID))
+      {
+        int identity = 0; 
+        int firstPotential = getFirstPotential(identity);
+
+        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
+      }
+
+      int root = getDocumentRoot(context); 
+      return next(root, root, expandedTypeID);
+    }
+    
+  }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMDocumentImpl.java b/src/main/java/org/apache/xml/dtm/ref/DTMDocumentImpl.java
new file mode 100644
index 0000000..a564115
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMDocumentImpl.java
@@ -0,0 +1,2411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMDocumentImpl.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisIterator;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This is the implementation of the DTM document interface.  It receives
+ * requests from an XML content handler similar to that of an XML DOM or SAX parser
+ * to store information from the xml document in an array based
+ * dtm table structure.  This informtion is used later for document navigation,
+ * query, and SAX event dispatch functions. The DTM can also be used directly as a
+ * document composition model for an application.  The requests received are:
+ * <ul>
+ * <li>initiating DTM to set the doc handle</li>
+ * <li>resetting DTM for data structure reuse</li>
+ * <li>hinting the end of document to adjust the end of data structure pointers</li>
+ * <li>createnodes (element, comment, text, attribute, ....)</li>
+ * <li>hinting the end of an element to patch parent and siblings<li>
+ * <li>setting application provided symbol name stringpool data structures</li>
+ * </ul>
+ * <p>State: In progress!!</p>
+ *
+ * %REVIEW% I _think_ the SAX convention is that "no namespace" is expressed
+ * as "" rather than as null (which is the DOM's convention). What should
+ * DTM expect? What should it do with the other?
+ *
+ * <p>Origin: the implemention is a composite logic based on the DTM of XalanJ1 and
+ *     DocImpl, DocumentImpl, ElementImpl, TextImpl, etc. of XalanJ2</p>
+ */
+public class DTMDocumentImpl
+implements DTM, org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler
+{
+
+        // Number of lower bits used to represent node index.
+        protected static final byte DOCHANDLE_SHIFT = 22;
+        // Masks the lower order of node handle.
+        // Same as {@link DTMConstructor.IDENT_NODE_DEFAULT}
+        protected static final int NODEHANDLE_MASK = (1 << (DOCHANDLE_SHIFT + 1)) - 1;
+        // Masks the higher order Document handle
+        // Same as {@link DTMConstructor.IDENT_DOC_DEFAULT}
+        protected static final int DOCHANDLE_MASK = -1 - NODEHANDLE_MASK;
+
+        int m_docHandle = NULL;		 // masked document handle for this dtm document
+        int m_docElement = NULL;	 // nodeHandle to the root of the actual dtm doc content
+
+        // Context for parse-and-append operations
+        int currentParent = 0;			// current parent - default is document root
+        int previousSibling = 0;		// previous sibling - no previous sibling
+        protected int m_currentNode = -1;		// current node
+
+        // The tree under construction can itself be used as
+        // the element stack, so m_elemStack isn't needed.
+        //protected Stack m_elemStack = new Stack();	 // element stack
+
+        private boolean previousSiblingWasParent = false;
+        // Local cache for record-at-a-time fetch
+        int gotslot[] = new int[4];
+
+        // endDocument recieved?
+        private boolean done = false;
+        boolean m_isError = false;
+
+        private final boolean DEBUG = false;
+
+        /** The document base URI. */
+        protected String m_documentBaseURI;
+
+  /** If we're building the model incrementally on demand, we need to
+   * be able to tell the source when to send us more data.
+   *
+   * Note that if this has not been set, and you attempt to read ahead
+   * of the current build point, we'll probably throw a null-pointer
+   * exception. We could try to wait-and-retry instead, as a very poor
+   * fallback, but that has all the known problems with multithreading
+   * on multiprocessors and we Don't Want to Go There.
+   *
+   * @see setIncrementalSAXSource
+   */
+  private IncrementalSAXSource m_incrSAXSource=null;
+
+
+        // ========= DTM data structure declarations. ==============
+
+        // nodes array: integer array blocks to hold the first level reference of the nodes,
+        // each reference slot is addressed by a nodeHandle index value.
+        // Assumes indices are not larger than {@link NODEHANDLE_MASK}
+        // ({@link DOCHANDLE_SHIFT} bits).
+        ChunkedIntArray nodes = new ChunkedIntArray(4);
+
+        // text/comment table: string buffer to hold the text string values of the document,
+        // each of which is addressed by the absolute offset and length in the buffer
+        private FastStringBuffer m_char = new FastStringBuffer();
+        // Start of string currently being accumulated into m_char;
+        // needed because the string may be appended in several chunks.
+        private int m_char_current_start=0;
+
+        // %TBD% INITIALIZATION/STARTUP ISSUES
+        // -- Should we really be creating these, or should they be
+        // passed in from outside? Scott want to be able to share
+        // pools across multiple documents, so setting them here is
+        // probably not the right default.
+        private DTMStringPool m_localNames = new DTMStringPool();
+        private DTMStringPool m_nsNames = new DTMStringPool();
+        private DTMStringPool m_prefixNames = new DTMStringPool();
+
+        // %TBD% If we use the current ExpandedNameTable mapper, it
+        // needs to be bound to the NS and local name pools. Which
+        // means it needs to attach to them AFTER we've resolved their
+        // startup. Or it needs to attach to this document and
+        // retrieve them each time. Or this needs to be
+        // an interface _implemented_ by this class... which might be simplest!
+        private ExpandedNameTable m_expandedNames=
+                new ExpandedNameTable();
+
+        private XMLStringFactory m_xsf;
+
+
+        /**
+         * Construct a DTM.
+         *
+         * @param documentNumber the ID number assigned to this document.
+         * It will be shifted up into the high bits and returned as part of
+         * all node ID numbers, so those IDs indicate which document they
+         * came from as well as a location within the document. It is the
+         * DTMManager's responsibility to assign a unique number to each
+         * document.
+         */
+        public DTMDocumentImpl(DTMManager mgr, int documentNumber,
+                               DTMWSFilter whiteSpaceFilter,
+                               XMLStringFactory xstringfactory){
+                initDocument(documentNumber);	 // clear nodes and document handle
+                m_xsf = xstringfactory;
+        }
+
+  /** Bind a IncrementalSAXSource to this DTM. If we discover we need nodes
+   * that have not yet been built, we will ask this object to send us more
+   * events, and it will manage interactions with its data sources.
+   *
+   * Note that we do not actually build the IncrementalSAXSource, since we don't
+   * know what source it's reading from, what thread that source will run in,
+   * or when it will run.
+   *
+   * @param source The IncrementalSAXSource that we want to recieve events from
+   * on demand.
+   */
+  public void setIncrementalSAXSource(IncrementalSAXSource source)
+  {
+    m_incrSAXSource=source;
+
+    // Establish SAX-stream link so we can receive the requested data
+    source.setContentHandler(this);
+    source.setLexicalHandler(this);
+
+    // Are the following really needed? IncrementalSAXSource doesn't yet
+    // support them, and they're mostly no-ops here...
+    //source.setErrorHandler(this);
+    //source.setDTDHandler(this);
+    //source.setDeclHandler(this);
+  }
+
+        /**
+         * Wrapper for ChunkedIntArray.append, to automatically update the
+         * previous sibling's "next" reference (if necessary) and periodically
+         * wake a reader who may have encountered incomplete data and entered
+         * a wait state.
+         * @param w0 int As in ChunkedIntArray.append
+         * @param w1 int As in ChunkedIntArray.append
+         * @param w2 int As in ChunkedIntArray.append
+         * @param w3 int As in ChunkedIntArray.append
+         * @return int As in ChunkedIntArray.append
+         * @see ChunkedIntArray.append
+         */
+        private final int appendNode(int w0, int w1, int w2, int w3)
+        {
+                // A decent compiler may inline this.
+                int slotnumber = nodes.appendSlot(w0, w1, w2, w3);
+
+                if (DEBUG) System.out.println(slotnumber+": "+w0+" "+w1+" "+w2+" "+w3);
+
+                if (previousSiblingWasParent)
+                        nodes.writeEntry(previousSibling,2,slotnumber);
+
+                previousSiblingWasParent = false;	// Set the default; endElement overrides
+
+                return slotnumber;
+        }
+
+        // ========= DTM Implementation Control Functions. ==============
+
+        /**
+         * Set an implementation dependent feature.
+         * <p>
+         * %REVIEW% Do we really expect to set features on DTMs?
+         *
+         * @param featureId A feature URL.
+         * @param state true if this feature should be on, false otherwise.
+         */
+        public void setFeature(String featureId, boolean state) {};
+
+        /**
+         * Set a reference pointer to the element name symbol table.
+         * %REVIEW% Should this really be Public? Changing it while
+         * DTM is in use would be a disaster.
+         *
+         * @param poolRef DTMStringPool reference to an instance of table.
+         */
+        public void setLocalNameTable(DTMStringPool poolRef) {
+                m_localNames = poolRef;
+        }
+
+        /**
+         * Get a reference pointer to the element name symbol table.
+         *
+         * @return DTMStringPool reference to an instance of table.
+         */
+        public DTMStringPool getLocalNameTable() {
+                 return m_localNames;
+         }
+
+        /**
+         * Set a reference pointer to the namespace URI symbol table.
+         * %REVIEW% Should this really be Public? Changing it while
+         * DTM is in use would be a disaster.
+         *
+         * @param poolRef DTMStringPool reference to an instance of table.
+         */
+        public void setNsNameTable(DTMStringPool poolRef) {
+                m_nsNames = poolRef;
+        }
+
+        /**
+         * Get a reference pointer to the namespace URI symbol table.
+         *
+         * @return DTMStringPool reference to an instance of table.
+         */
+        public DTMStringPool getNsNameTable() {
+                 return m_nsNames;
+         }
+
+        /**
+         * Set a reference pointer to the prefix name symbol table.
+         * %REVIEW% Should this really be Public? Changing it while
+         * DTM is in use would be a disaster.
+         *
+         * @param poolRef DTMStringPool reference to an instance of table.
+         */
+        public void setPrefixNameTable(DTMStringPool poolRef) {
+                m_prefixNames = poolRef;
+        }
+
+        /**
+         * Get a reference pointer to the prefix name symbol table.
+         *
+         * @return DTMStringPool reference to an instance of table.
+         */
+        public DTMStringPool getPrefixNameTable() {
+                return m_prefixNames;
+        }
+
+         /**
+          * Set a reference pointer to the content-text repository
+          *
+          * @param buffer FastStringBuffer reference to an instance of
+          * buffer
+          */
+         void setContentBuffer(FastStringBuffer buffer) {
+                 m_char = buffer;
+         }
+
+         /**
+          * Get a reference pointer to the content-text repository
+          *
+          * @return FastStringBuffer reference to an instance of buffer
+          */
+         FastStringBuffer getContentBuffer() {
+                 return m_char;
+         }
+
+  /** getContentHandler returns "our SAX builder" -- the thing that
+   * someone else should send SAX events to in order to extend this
+   * DTM model.
+   *
+   * @return null if this model doesn't respond to SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrementalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   * */
+  public org.xml.sax.ContentHandler getContentHandler()
+  {
+    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
+      return (ContentHandler) m_incrSAXSource;
+    else
+      return this;
+  }
+
+  /**
+   * Return this DTM's lexical handler.
+   *
+   * %REVIEW% Should this return null if constrution already done/begun?
+   *
+   * @return null if this model doesn't respond to lexical SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrementalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   */
+  public LexicalHandler getLexicalHandler()
+  {
+
+    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
+      return (LexicalHandler) m_incrSAXSource;
+    else
+      return this;
+  }
+
+  /**
+   * Return this DTM's EntityResolver.
+   *
+   * @return null if this model doesn't respond to SAX entity ref events.
+   */
+  public org.xml.sax.EntityResolver getEntityResolver()
+  {
+
+    return null;
+  }
+
+  /**
+   * Return this DTM's DTDHandler.
+   *
+   * @return null if this model doesn't respond to SAX dtd events.
+   */
+  public org.xml.sax.DTDHandler getDTDHandler()
+  {
+
+    return null;
+  }
+
+  /**
+   * Return this DTM's ErrorHandler.
+   *
+   * @return null if this model doesn't respond to SAX error events.
+   */
+  public org.xml.sax.ErrorHandler getErrorHandler()
+  {
+
+    return null;
+  }
+
+  /**
+   * Return this DTM's DeclHandler.
+   *
+   * @return null if this model doesn't respond to SAX Decl events.
+   */
+  public org.xml.sax.ext.DeclHandler getDeclHandler()
+  {
+
+    return null;
+  }
+
+  /** @return true iff we're building this model incrementally (eg
+   * we're partnered with a IncrementalSAXSource) and thus require that the
+   * transformation and the parse run simultaneously. Guidance to the
+   * DTMManager.
+   * */
+  public boolean needsTwoThreads()
+  {
+    return null!=m_incrSAXSource;
+  }
+
+  //================================================================
+  // ========= SAX2 ContentHandler methods =========
+  // Accept SAX events, use them to build/extend the DTM tree.
+  // Replaces the deprecated DocumentHandler interface.
+
+  public void characters(char[] ch, int start, int length)
+       throws org.xml.sax.SAXException
+  {
+    // Actually creating the text node is handled by
+    // processAccumulatedText(); here we just accumulate the
+    // characters into the buffer.
+    m_char.append(ch,start,length);
+  }
+
+  // Flush string accumulation into a text node
+  private void processAccumulatedText()
+  {
+    int len=m_char.length();
+    if(len!=m_char_current_start)
+      {
+        // The FastStringBuffer has been previously agreed upon
+        appendTextChild(m_char_current_start,len-m_char_current_start);
+        m_char_current_start=len;
+      }
+  }
+  public void endDocument()
+       throws org.xml.sax.SAXException
+  {
+    // May need to tell the low-level builder code to pop up a level.
+    // There _should't_ be any significant pending text at this point.
+    appendEndDocument();
+  }
+  public void endElement(java.lang.String namespaceURI, java.lang.String localName,
+      java.lang.String qName)
+       throws org.xml.sax.SAXException
+  {
+    processAccumulatedText();
+    // No args but we do need to tell the low-level builder code to
+    // pop up a level.
+    appendEndElement();
+  }
+  public void endPrefixMapping(java.lang.String prefix)
+       throws org.xml.sax.SAXException
+  {
+    // No-op
+  }
+  public void ignorableWhitespace(char[] ch, int start, int length)
+       throws org.xml.sax.SAXException
+  {
+    // %TBD% I believe ignorable text isn't part of the DTM model...?
+  }
+  public void processingInstruction(java.lang.String target, java.lang.String data)
+       throws org.xml.sax.SAXException
+  {
+    processAccumulatedText();
+    // %TBD% Which pools do target and data go into?
+  }
+  public void setDocumentLocator(Locator locator)
+  {
+    // No-op for DTM
+  }
+  public void skippedEntity(java.lang.String name)
+       throws org.xml.sax.SAXException
+  {
+    processAccumulatedText();
+    //%TBD%
+  }
+  public void startDocument()
+       throws org.xml.sax.SAXException
+  {
+    appendStartDocument();
+  }
+  public void startElement(java.lang.String namespaceURI, java.lang.String localName,
+      java.lang.String qName, Attributes atts)
+       throws org.xml.sax.SAXException
+  {
+    processAccumulatedText();
+
+    // %TBD% Split prefix off qname
+    String prefix=null;
+    int colon=qName.indexOf(':');
+    if(colon>0)
+      prefix=qName.substring(0,colon);
+
+    // %TBD% Where do we pool expandedName, or is it just the union, or...
+    /**/System.out.println("Prefix="+prefix+" index="+m_prefixNames.stringToIndex(prefix));
+    appendStartElement(m_nsNames.stringToIndex(namespaceURI),
+                     m_localNames.stringToIndex(localName),
+                     m_prefixNames.stringToIndex(prefix)); /////// %TBD%
+
+    // %TBD% I'm assuming that DTM will require resequencing of
+    // NS decls before other attrs, hence two passes are taken.
+    // %TBD% Is there an easier way to test for NSDecl?
+    int nAtts=(atts==null) ? 0 : atts.getLength();
+    // %TBD% Countdown is more efficient if nobody cares about sequence.
+    for(int i=nAtts-1;i>=0;--i)
+      {
+        qName=atts.getQName(i);
+        if(qName.startsWith("xmlns:") || "xmlns".equals(qName))
+          {
+            prefix=null;
+            colon=qName.indexOf(':');
+            if(colon>0)
+              {
+                prefix=qName.substring(0,colon);
+              }
+            else
+              {
+                // %REVEIW% Null or ""?
+                prefix=null; // Default prefix
+              }
+
+
+            appendNSDeclaration(
+                                    m_prefixNames.stringToIndex(prefix),
+                                    m_nsNames.stringToIndex(atts.getValue(i)),
+                                    atts.getType(i).equalsIgnoreCase("ID"));
+          }
+      }
+
+    for(int i=nAtts-1;i>=0;--i)
+      {
+        qName=atts.getQName(i);
+        if(!(qName.startsWith("xmlns:") || "xmlns".equals(qName)))
+          {
+            // %TBD% I hate having to extract the prefix into a new
+            // string when we may never use it. Consider pooling whole
+            // qNames, which are already strings?
+            prefix=null;
+            colon=qName.indexOf(':');
+            if(colon>0)
+              {
+                prefix=qName.substring(0,colon);
+                localName=qName.substring(colon+1);
+              }
+            else
+              {
+                prefix=""; // Default prefix
+                localName=qName;
+              }
+
+
+            m_char.append(atts.getValue(i)); // Single-string value
+            int contentEnd=m_char.length();
+
+            if(!("xmlns".equals(prefix) || "xmlns".equals(qName)))
+              appendAttribute(m_nsNames.stringToIndex(atts.getURI(i)),
+                                  m_localNames.stringToIndex(localName),
+                                  m_prefixNames.stringToIndex(prefix),
+                                  atts.getType(i).equalsIgnoreCase("ID"),
+                                  m_char_current_start, contentEnd-m_char_current_start);
+            m_char_current_start=contentEnd;
+          }
+      }
+  }
+  public void startPrefixMapping(java.lang.String prefix, java.lang.String uri)
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM, handled during element/attr processing?
+  }
+
+  //
+  // LexicalHandler support. Not all SAX2 parsers support these events
+  // but we may want to pass them through when they exist...
+  //
+  public void comment(char[] ch, int start, int length)
+       throws org.xml.sax.SAXException
+  {
+    processAccumulatedText();
+
+    m_char.append(ch,start,length); // Single-string value
+    appendComment(m_char_current_start,length);
+    m_char_current_start+=length;
+  }
+  public void endCDATA()
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+  public void endDTD()
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+  public void endEntity(java.lang.String name)
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+  public void startCDATA()
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+  public void startDTD(java.lang.String name, java.lang.String publicId,
+      java.lang.String systemId)
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+  public void startEntity(java.lang.String name)
+       throws org.xml.sax.SAXException
+  {
+    // No-op in DTM
+  }
+
+
+  //================================================================
+  // ========= Document Handler Functions =========
+  // %REVIEW% jjk -- DocumentHandler is  SAX Level 1, and deprecated....
+  // and this wasn't a fully compliant or declared implementation of that API
+  // in any case. Phase out in favor of SAX2 ContentHandler/LexicalHandler
+
+        /**
+         * Reset a dtm document to its initial (empty) state.
+         *
+         * The DTMManager will invoke this method when the dtm is created.
+         *
+         * @param documentNumber the handle for the DTM document.
+         */
+        final void initDocument(int documentNumber)
+        {
+                // save masked DTM document handle
+                m_docHandle = documentNumber<<DOCHANDLE_SHIFT;
+
+                // Initialize the doc -- no parent, no next-sib
+                nodes.writeSlot(0,DOCUMENT_NODE,-1,-1,0);
+                // wait for the first startElement to create the doc root node
+                done = false;
+        }
+
+// 	/**
+// 	 * Receive hint of the end of a document.
+// 	 *
+// 	 * <p>The content handler will invoke this method only once, and it will
+// 	 * be the last method invoked during the parse.  The handler shall not
+// 	 * not invoke this method until it has either abandoned parsing
+// 	 * (because of an unrecoverable error) or reached the end of
+// 	 * input.</p>
+// 	 */
+// 	public void documentEnd()
+// 	{
+// 		done = true;
+// 		// %TBD% may need to notice the last slot number and slot count to avoid
+// 		// residual data from provious use of this DTM
+// 	}
+
+// 	/**
+// 	 * Receive notification of the beginning of a document.
+// 	 *
+// 	 * <p>The SAX parser will invoke this method only once, before any
+// 	 * other methods in this interface.</p>
+// 	 */
+// 	public void reset()
+// 	{
+
+// 		// %TBD% reset slot 0 to indicate ChunkedIntArray reuse or wait for
+// 		//       the next initDocument().
+// 		m_docElement = NULL;	 // reset nodeHandle to the root of the actual dtm doc content
+// 		initDocument(0);
+// 	}
+
+// 	/**
+// 	 * Factory method; creates an Element node in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * <p>The XML content handler will invoke endElement() method after all
+// 	 * of the element's content are processed in order to give DTM the indication
+// 	 * to prepare and patch up parent and sibling node pointers.</p>
+// 	 *
+// 	 * <p>The following interface for createElement will use an index value corresponds
+// 	 * to the symbol entry in the DTMDStringPool based symbol tables.</p>
+// 	 *
+// 	 * @param nsIndex The namespace of the node
+// 	 * @param nameIndex The element name.
+// 	 * @see #endElement
+// 	 * @see org.xml.sax.Attributes
+// 	 * @return nodeHandle int of the element created
+// 	 */
+// 	public int createElement(int nsIndex, int nameIndex, Attributes atts)
+// 	{
+// 		// do document root node creation here on the first element, create nodes for
+// 		// this element and its attributes, store the element, namespace, and attritute
+// 		// name indexes to the nodes array, keep track of the current node and parent
+// 		// element used
+
+// 		// W0  High:  Namespace  Low:  Node Type
+// 		int w0 = (nsIndex << 16) | ELEMENT_NODE;
+// 		// W1: Parent
+// 		int w1 = currentParent;
+// 		// W2: Next  (initialized as 0)
+// 		int w2 = 0;
+// 		// W3: Tagname
+// 		int w3 = nameIndex;
+// 		//int ourslot = nodes.appendSlot(w0, w1, w2, w3);
+// 		int ourslot = appendNode(w0, w1, w2, w3);
+// 		currentParent = ourslot;
+// 		previousSibling = 0;
+// 		setAttributes(atts);
+
+// 		// set the root element pointer when creating the first element node
+// 		if (m_docElement == NULL)
+// 			m_docElement = ourslot;
+// 		return (m_docHandle | ourslot);
+// 	}
+
+// 	// Factory method to create an Element node not associated with a given name space
+// 	// using String value parameters passed in from a content handler or application
+// 	/**
+// 	 * Factory method; creates an Element node not associated with a given name space in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * <p>The XML content handler or application will invoke endElement() method after all
+// 	 * of the element's content are processed in order to give DTM the indication
+// 	 * to prepare and patch up parent and sibling node pointers.</p>
+// 	 *
+// 	 * <p>The following parameters for createElement contains raw string values for name
+// 	 * symbols used in an Element node.</p>
+// 	 *
+// 	 * @param name String the element name, including the prefix if any.
+// 	 * @param atts The attributes attached to the element, if any.
+// 	 * @see #endElement
+// 	 * @see org.xml.sax.Attributes
+// 	 */
+// 	public int createElement(String name, Attributes atts)
+// 	{
+// 		// This method wraps around the index valued interface of the createElement interface.
+// 		// The raw string values are stored into the current DTM name symbol tables.  The method
+// 		// method will then use the index values returned to invoke the other createElement()
+// 		// onverted to index values modified to match a
+// 		// method.
+// 		int nsIndex = NULL;
+// 		int nameIndex = m_localNames.stringToIndex(name);
+// 		// note - there should be no prefix separator in the name because it is not associated
+// 		// with a name space
+
+// 		return createElement(nsIndex, nameIndex, atts);
+// 	}
+
+// 	// Factory method to create an Element node associated with a given name space
+// 	// using String value parameters passed in from a content handler or application
+// 	/**
+// 	 * Factory method; creates an Element node associated with a given name space in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * <p>The XML content handler or application will invoke endElement() method after all
+// 	 * of the element's content are processed in order to give DTM the indication
+// 	 * to prepare and patch up parent and sibling node pointers.</p>
+// 	 *
+// 	 * <p>The following parameters for createElementNS contains raw string values for name
+// 	 * symbols used in an Element node.</p>
+// 	 *
+// 	 * @param ns String the namespace of the node
+// 	 * @param name String the element name, including the prefix if any.
+// 	 * @param atts The attributes attached to the element, if any.
+// 	 * @see #endElement
+// 	 * @see org.xml.sax.Attributes
+// 	 */
+// 	public int createElementNS(String ns, String name, Attributes atts)
+// 	{
+// 		// This method wraps around the index valued interface of the createElement interface.
+// 		// The raw string values are stored into the current DTM name symbol tables.  The method
+// 		// method will then use the index values returned to invoke the other createElement()
+// 		// onverted to index values modified to match a
+// 		// method.
+// 		int nsIndex = m_nsNames.stringToIndex(ns);
+// 		int nameIndex = m_localNames.stringToIndex(name);
+// 		// The prefixIndex is not needed by the indexed interface of the createElement method
+// 		int prefixSep = name.indexOf(":");
+// 		int prefixIndex = m_prefixNames.stringToIndex(name.substring(0, prefixSep));
+// 		return createElement(nsIndex, nameIndex, atts);
+// 	}
+
+// 	/**
+// 	 * Receive an indication for the end of an element.
+// 	 *
+// 	 * <p>The XML content handler will invoke this method at the end of every
+// 	 * element in the XML document to give hint its time to pop up the current
+// 	 * element and parent and patch up parent and sibling pointers if necessary
+// 	 *
+// 	 * <p>%tbd% The following interface may need to be modified to match a
+// 	 * coordinated access to the DTMDStringPool based symbol tables.</p>
+// 		 *
+// 	 * @param ns the namespace of the element
+// 	 * @param name The element name
+// 	 */
+// 	public void endElement(String ns, String name)
+// 	{
+// 		// pop up the stacks
+
+// 		//
+// 		if (previousSiblingWasParent)
+// 			nodes.writeEntry(previousSibling, 2, NULL);
+
+// 		// Pop parentage
+// 		previousSibling = currentParent;
+// 		nodes.readSlot(currentParent, gotslot);
+// 		currentParent = gotslot[1] & 0xFFFF;
+
+// 		// The element just being finished will be
+// 		// the previous sibling for the next operation
+// 		previousSiblingWasParent = true;
+
+// 		// Pop a level of namespace table
+// 		// namespaceTable.removeLastElem();
+// 	}
+
+// 	/**
+// 	 * Creates attributes for the current node.
+// 	 *
+// 	 * @param atts Attributes to be created.
+// 	 */
+// 	void setAttributes(Attributes atts) {
+// 		int atLength = (null == atts) ? 0 : atts.getLength();
+// 		for (int i=0; i < atLength; i++) {
+// 			String qname = atts.getQName(i);
+// 			createAttribute(atts.getQName(i), atts.getValue(i));
+// 		}
+// 	}
+
+// 	/**
+// 	 * Appends an attribute to the document.
+// 	 * @param qname Qualified Name of the attribute
+// 	 * @param value Value of the attribute
+// 	 * @return Handle of node
+// 	 */
+// 	public int createAttribute(String qname, String value) {
+// 		int colonpos = qname.indexOf(":");
+// 		String attName = qname.substring(colonpos+1);
+// 		int w0 = 0;
+// 		if (colonpos > 0) {
+// 			String prefix = qname.substring(0, colonpos);
+// 			if (prefix.equals("xml")) {
+// 				//w0 = ATTRIBUTE_NODE |
+// 				//	(org.apache.xalan.templates.Constants.S_XMLNAMESPACEURI << 16);
+// 			} else {
+// 				//w0 = ATTRIBUTE_NODE |
+// 			}
+// 		} else {
+// 			w0 = ATTRIBUTE_NODE;
+// 		}
+// 		// W1:  Parent
+// 		int w1 = currentParent;
+// 		// W2:  Next (not yet resolved)
+// 		int w2 = 0;
+// 		// W3:  Tag name
+// 		int w3 = m_localNames.stringToIndex(attName);
+// 		// Add node
+// 		int ourslot = appendNode(w0, w1, w2, w3);
+// 		previousSibling = ourslot;	// Should attributes be previous siblings
+
+// 		// W0: Node Type
+// 		w0 = TEXT_NODE;
+// 		// W1: Parent
+// 		w1 = ourslot;
+// 		// W2: Start Position within buffer
+// 		w2 = m_char.length();
+// 		m_char.append(value);
+// 		// W3: Length
+// 		w3 = m_char.length() - w2;
+// 		appendNode(w0, w1, w2, w3);
+// 		charStringStart=m_char.length();
+// 		charStringLength = 0;
+// 		//previousSibling = ourslot;
+// 		// Attrs are Parents
+// 		previousSiblingWasParent = true;
+// 		return (m_docHandle | ourslot);
+// 	}
+
+// 	/**
+// 	 * Factory method; creates a Text node in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * @param text String The characters text string from the XML document.
+// 	 * @return int DTM node-number of the text node created
+// 	 */
+// 	public int createTextNode(String text)
+// 	throws DTMException
+// 	{
+// 		// wraps around the index value based createTextNode method
+// 		return createTextNode(text.toCharArray(), 0, text.length());
+// 	}
+
+// 	/**
+// 	 * Factory method; creates a Text node in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * %REVIEW% for text normalization issues, unless we are willing to
+// 	 * insist that all adjacent text must be merged before this method
+// 	 * is called.
+// 	 *
+// 	 * @param ch The characters from the XML document.
+// 	 * @param start The start position in the array.
+// 	 * @param length The number of characters to read from the array.
+// 	 */
+// 	public int createTextNode(char ch[], int start, int length)
+// 	throws DTMException
+// 	{
+// 		m_char.append(ch, start, length);		// store the chunk to the text/comment string table
+
+// 		// create a Text Node
+// 		// %TBD% may be possible to combine with appendNode()to replace the next chunk of code
+// 		int w0 = TEXT_NODE;
+// 		// W1: Parent
+// 		int w1 = currentParent;
+// 		// W2: Start position within m_char
+// 		int w2 = charStringStart;
+// 		// W3: Length of the full string
+// 		int w3 = length;
+// 		int ourslot = appendNode(w0, w1, w2, w3);
+// 		previousSibling = ourslot;
+
+// 		charStringStart=m_char.length();
+// 		charStringLength = 0;
+// 		return (m_docHandle | ourslot);
+// 	}
+
+// 	/**
+// 	 * Factory method; creates a Comment node in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * @param text String The characters text string from the XML document.
+// 	 * @return int DTM node-number of the text node created
+// 	 */
+// 	public int createComment(String text)
+// 	throws DTMException
+// 	{
+// 		// wraps around the index value based createTextNode method
+// 		return createComment(text.toCharArray(), 0, text.length());
+// 	}
+
+// 	/**
+// 	 * Factory method; creates a Comment node in this document.
+// 	 *
+// 	 * The node created will be chained according to its natural order of request
+// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
+// 	 *
+// 	 * @param ch An array holding the characters in the comment.
+// 	 * @param start The starting position in the array.
+// 	 * @param length The number of characters to use from the array.
+// 	 * @see DTMException
+// 	 */
+// 	public int createComment(char ch[], int start, int length)
+// 	throws DTMException
+// 	{
+// 		m_char.append(ch, start, length);		// store the comment string to the text/comment string table
+
+// 		// create a Comment Node
+// 		// %TBD% may be possible to combine with appendNode()to replace the next chunk of code
+// 		int w0 = COMMENT_NODE;
+// 		// W1: Parent
+// 		int w1 = currentParent;
+// 		// W2: Start position within m_char
+// 		int w2 = charStringStart;
+// 		// W3: Length of the full string
+// 		int w3 = length;
+// 		int ourslot = appendNode(w0, w1, w2, w3);
+// 		previousSibling = ourslot;
+
+// 		charStringStart=m_char.length();
+// 		charStringLength = 0;
+// 		return (m_docHandle | ourslot);
+// 	}
+
+// 	// Counters to keep track of the current text string being accumulated with respect
+// 	// to the text/comment string table: charStringStart should point to the starting
+// 	// offset of the string in the table and charStringLength the acccumulated length when
+// 	// appendAccumulatedText starts, and reset to the end of the table and 0 at the end
+// 	// of appendAccumulatedText for the next set of characters receives
+// 	int charStringStart=0,charStringLength=0;
+
+        // ========= Document Navigation Functions =========
+
+        /** Given a node handle, test if it has child nodes.
+         * <p> %REVIEW% This is obviously useful at the DOM layer, where it
+         * would permit testing this without having to create a proxy
+         * node. It's less useful in the DTM API, where
+         * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and
+         * almost as self-evident. But it's a convenience, and eases porting
+         * of DOM code to DTM.  </p>
+         *
+         * @param nodeHandle int Handle of the node.
+         * @return int true if the given node has child nodes.
+         */
+        public boolean hasChildNodes(int nodeHandle) {
+                return(getFirstChild(nodeHandle) != NULL);
+        }
+
+        /**
+         * Given a node handle, get the handle of the node's first child.
+         * If not yet resolved, waits for more nodes to be added to the document and
+         * tries again.
+         *
+         * @param nodeHandle int Handle of the node.
+         * @return int DTM node-number of first child, or DTM.NULL to indicate none exists.
+         */
+        public int getFirstChild(int nodeHandle) {
+
+                // ###shs worry about tracing/debug later
+                nodeHandle &= NODEHANDLE_MASK;
+                // Read node into variable
+                nodes.readSlot(nodeHandle, gotslot);
+
+                // type is the last half of first slot
+                short type = (short) (gotslot[0] & 0xFFFF);
+
+                // Check to see if Element or Document node
+                if ((type == ELEMENT_NODE) || (type == DOCUMENT_NODE) ||
+                                (type == ENTITY_REFERENCE_NODE)) {
+
+                        // In case when Document root is given
+                        //	if (nodeHandle == 0) nodeHandle = 1;
+                        // %TBD% Probably was a mistake.
+                        // If someone explicitly asks for first child
+                        // of Document, I would expect them to want
+                        // that and only that.
+
+                        int kid = nodeHandle + 1;
+                        nodes.readSlot(kid, gotslot);
+                        while (ATTRIBUTE_NODE == (gotslot[0] & 0xFFFF)) {
+                                // points to next sibling
+                                kid = gotslot[2];
+                                // Return NULL if node has only attributes
+                                if (kid == NULL) return NULL;
+                                nodes.readSlot(kid, gotslot);
+                        }
+                        // If parent slot matches given parent, return kid
+                        if (gotslot[1] == nodeHandle)
+                        {
+                          int firstChild = kid | m_docHandle;
+
+                          return firstChild;
+                        }
+                }
+                // No child found
+
+                return NULL;
+        }
+
+        /**
+        * Given a node handle, advance to its last child.
+        * If not yet resolved, waits for more nodes to be added to the document and
+        * tries again.
+        *
+        * @param nodeHandle int Handle of the node.
+        * @return int Node-number of last child,
+        * or DTM.NULL to indicate none exists.
+        */
+        public int getLastChild(int nodeHandle) {
+                // ###shs put trace/debug later
+                nodeHandle &= NODEHANDLE_MASK;
+                // do not need to test node type since getFirstChild does that
+                int lastChild = NULL;
+                for (int nextkid = getFirstChild(nodeHandle); nextkid != NULL;
+                                nextkid = getNextSibling(nextkid)) {
+                        lastChild = nextkid;
+                }
+                return lastChild | m_docHandle;
+        }
+
+        /**
+         * Retrieves an attribute node by by qualified name and namespace URI.
+         *
+         * @param nodeHandle int Handle of the node upon which to look up this attribute.
+         * @param namespaceURI The namespace URI of the attribute to
+         *   retrieve, or null.
+         * @param name The local name of the attribute to
+         *   retrieve.
+         * @return The attribute node handle with the specified name (
+         *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
+         *   attribute.
+         */
+        public int getAttributeNode(int nodeHandle, String namespaceURI, String name) {
+                int nsIndex = m_nsNames.stringToIndex(namespaceURI),
+                                                                        nameIndex = m_localNames.stringToIndex(name);
+                nodeHandle &= NODEHANDLE_MASK;
+                nodes.readSlot(nodeHandle, gotslot);
+                short type = (short) (gotslot[0] & 0xFFFF);
+                // If nodeHandle points to element next slot would be first attribute
+                if (type == ELEMENT_NODE)
+                        nodeHandle++;
+                // Iterate through Attribute Nodes
+                while (type == ATTRIBUTE_NODE) {
+                        if ((nsIndex == (gotslot[0] << 16)) && (gotslot[3] == nameIndex))
+                                return nodeHandle | m_docHandle;
+                        // Goto next sibling
+                        nodeHandle = gotslot[2];
+                        nodes.readSlot(nodeHandle, gotslot);
+                }
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, get the index of the node's first attribute.
+         *
+         * @param nodeHandle int Handle of the Element node.
+         * @return Handle of first attribute, or DTM.NULL to indicate none exists.
+         */
+        public int getFirstAttribute(int nodeHandle) {
+                nodeHandle &= NODEHANDLE_MASK;
+
+                // %REVIEW% jjk: Just a quick observation: If you're going to
+                // call readEntry repeatedly on the same node, it may be
+                // more efficiently to do a readSlot to get the data locally,
+                // reducing the addressing and call-and-return overhead.
+
+                // Should we check if handle is element (do we want sanity checks?)
+                if (ELEMENT_NODE != (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
+                        return NULL;
+                // First Attribute (if any) should be at next position in table
+                nodeHandle++;
+                return(ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) ?
+                nodeHandle | m_docHandle : NULL;
+        }
+
+        /**
+         * Given a node handle, get the index of the node's first child.
+         * If not yet resolved, waits for more nodes to be added to the document and
+         * tries again
+         *
+         * @param nodeHandle handle to node, which should probably be an element
+         *                   node, but need not be.
+         *
+         * @param inScope    true if all namespaces in scope should be returned,
+         *                   false if only the namespace declarations should be
+         *                   returned.
+         * @return handle of first namespace, or DTM.NULL to indicate none exists.
+         */
+        public int getFirstNamespaceNode(int nodeHandle, boolean inScope) {
+
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, advance to its next sibling.
+         *
+         * %TBD% This currently uses the DTM-internal definition of
+         * sibling; eg, the last attr's next sib is the first
+         * child. In the old DTM, the DOM proxy layer provided the
+         * additional logic for the public view.  If we're rewriting
+         * for XPath emulation, that test must be done here.
+         *
+         * %TBD% CODE INTERACTION WITH INCREMENTAL PARSE - If not yet
+         * resolved, should wait for more nodes to be added to the document
+         * and tries again.
+         *
+         * @param nodeHandle int Handle of the node.
+         * @return int Node-number of next sibling,
+         * or DTM.NULL to indicate none exists.
+         * */
+        public int getNextSibling(int nodeHandle) {
+                nodeHandle &= NODEHANDLE_MASK;
+                // Document root has no next sibling
+                if (nodeHandle == 0)
+                        return NULL;
+
+                short type = (short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
+                if ((type == ELEMENT_NODE) || (type == ATTRIBUTE_NODE) ||
+                                (type == ENTITY_REFERENCE_NODE)) {
+                        int nextSib = nodes.readEntry(nodeHandle, 2);
+                        if (nextSib == NULL)
+                                return NULL;
+                        if (nextSib != 0)
+                                return (m_docHandle | nextSib);
+                        // ###shs should cycle/wait if nextSib is 0? Working on threading next
+                }
+                // Next Sibling is in the next position if it shares the same parent
+                int thisParent = nodes.readEntry(nodeHandle, 1);
+
+                if (nodes.readEntry(++nodeHandle, 1) == thisParent)
+                        return (m_docHandle | nodeHandle);
+
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, find its preceeding sibling.
+         * WARNING: DTM is asymmetric; this operation is resolved by search, and is
+         * relatively expensive.
+         *
+         * @param nodeHandle the id of the node.
+         * @return int Node-number of the previous sib,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getPreviousSibling(int nodeHandle) {
+                nodeHandle &= NODEHANDLE_MASK;
+                // Document root has no previous sibling
+                if (nodeHandle == 0)
+                        return NULL;
+
+                int parent = nodes.readEntry(nodeHandle, 1);
+                int kid = NULL;
+                for (int nextkid = getFirstChild(parent); nextkid != nodeHandle;
+                                nextkid = getNextSibling(nextkid)) {
+                        kid = nextkid;
+                }
+                return kid | m_docHandle;
+        }
+
+        /**
+         * Given a node handle, advance to the next attribute. If an
+         * element, we advance to its first attribute; if an attr, we advance to
+         * the next attr on the same node.
+         *
+         * @param nodeHandle int Handle of the node.
+         * @return int DTM node-number of the resolved attr,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getNextAttribute(int nodeHandle) {
+                nodeHandle &= NODEHANDLE_MASK;
+                nodes.readSlot(nodeHandle, gotslot);
+
+                //%REVIEW% Why are we using short here? There's no storage
+                //reduction for an automatic variable, especially one used
+                //so briefly, and it typically costs more cycles to process
+                //than an int would.
+                short type = (short) (gotslot[0] & 0xFFFF);
+
+                if (type == ELEMENT_NODE) {
+                        return getFirstAttribute(nodeHandle);
+                } else if (type == ATTRIBUTE_NODE) {
+                        if (gotslot[2] != NULL)
+                                return (m_docHandle | gotslot[2]);
+                }
+                return NULL;
+        }
+
+        /**
+         * Given a namespace handle, advance to the next namespace.
+         *
+         * %TBD% THIS METHOD DOES NOT MATCH THE CURRENT SIGNATURE IN
+         * THE DTM INTERFACE.  FIX IT, OR JUSTIFY CHANGING THE DTM
+         * API.
+         *
+         * @param namespaceHandle handle to node which must be of type NAMESPACE_NODE.
+         * @return handle of next namespace, or DTM.NULL to indicate none exists.
+         */
+        public int getNextNamespaceNode(int baseHandle,int namespaceHandle, boolean inScope) {
+                // ###shs need to work on namespace
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, advance to its next descendant.
+         * If not yet resolved, waits for more nodes to be added to the document and
+         * tries again.
+         *
+         * @param subtreeRootHandle
+         * @param nodeHandle int Handle of the node.
+         * @return handle of next descendant,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getNextDescendant(int subtreeRootHandle, int nodeHandle) {
+                subtreeRootHandle &= NODEHANDLE_MASK;
+                nodeHandle &= NODEHANDLE_MASK;
+                // Document root [Document Node? -- jjk] - no next-sib
+                if (nodeHandle == 0)
+                        return NULL;
+                while (!m_isError) {
+                        // Document done and node out of bounds
+                        if (done && (nodeHandle > nodes.slotsUsed()))
+                                break;
+                        if (nodeHandle > subtreeRootHandle) {
+                                nodes.readSlot(nodeHandle+1, gotslot);
+                                if (gotslot[2] != 0) {
+                                        short type = (short) (gotslot[0] & 0xFFFF);
+                                        if (type == ATTRIBUTE_NODE) {
+                                                nodeHandle +=2;
+                                        } else {
+                                                int nextParentPos = gotslot[1];
+                                                if (nextParentPos >= subtreeRootHandle)
+                                                        return (m_docHandle | (nodeHandle+1));
+                                                else
+                                                        break;
+                                        }
+                                } else if (!done) {
+                                        // Add wait logic here
+                                } else
+                                        break;
+                        } else {
+                                nodeHandle++;
+                        }
+                }
+                // Probably should throw error here like original instead of returning
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, advance to the next node on the following axis.
+         *
+         * @param axisContextHandle the start of the axis that is being traversed.
+         * @param nodeHandle
+         * @return handle of next sibling,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getNextFollowing(int axisContextHandle, int nodeHandle) {
+                //###shs still working on
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, advance to the next node on the preceding axis.
+         *
+         * @param axisContextHandle the start of the axis that is being traversed.
+         * @param nodeHandle the id of the node.
+         * @return int Node-number of preceding sibling,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getNextPreceding(int axisContextHandle, int nodeHandle) {
+                // ###shs copied from Xalan 1, what is this suppose to do?
+                nodeHandle &= NODEHANDLE_MASK;
+                while (nodeHandle > 1) {
+                        nodeHandle--;
+                        if (ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
+                                continue;
+
+                        // if nodeHandle is _not_ an ancestor of
+                        // axisContextHandle, specialFind will return it.
+                        // If it _is_ an ancestor, specialFind will return -1
+
+                        // %REVIEW% unconditional return defeats the
+                        // purpose of the while loop -- does this
+                        // logic make any sense?
+
+                        return (m_docHandle | nodes.specialFind(axisContextHandle, nodeHandle));
+                }
+                return NULL;
+        }
+
+        /**
+         * Given a node handle, find its parent node.
+         *
+         * @param nodeHandle the id of the node.
+         * @return int Node-number of parent,
+         * or DTM.NULL to indicate none exists.
+         */
+        public int getParent(int nodeHandle) {
+                // Should check to see within range?
+
+                // Document Root should not have to be handled differently
+                return (m_docHandle | nodes.readEntry(nodeHandle, 1));
+        }
+
+        /**
+         * Returns the root element of the document.
+         * @return nodeHandle to the Document Root.
+         */
+        public int getDocumentRoot() {
+                return (m_docHandle | m_docElement);
+        }
+
+        /**
+         * Given a node handle, find the owning document node.
+         *
+         * @return int Node handle of document, which should always be valid.
+         */
+        public int getDocument() {
+                return m_docHandle;
+        }
+
+        /**
+         * Given a node handle, find the owning document node.  This has the exact
+         * same semantics as the DOM Document method of the same name, in that if
+         * the nodeHandle is a document node, it will return NULL.
+         *
+         * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM
+         * binding layer. Included here as a convenience function and to
+         * aid porting of DOM code to DTM.</p>
+         *
+         * @param nodeHandle the id of the node.
+         * @return int Node handle of owning document, or NULL if the nodeHandle is
+         *             a document.
+         */
+        public int getOwnerDocument(int nodeHandle) {
+                // Assumption that Document Node is always in 0 slot
+                if ((nodeHandle & NODEHANDLE_MASK) == 0)
+                        return NULL;
+                return (nodeHandle & DOCHANDLE_MASK);
+        }
+
+        /**
+         * Given a node handle, find the owning document node.  This has the DTM
+         * semantics; a Document node is its own owner.
+         *
+         * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM
+         * binding layer. Included here as a convenience function and to
+         * aid porting of DOM code to DTM.</p>
+         *
+         * @param nodeHandle the id of the node.
+         * @return int Node handle of owning document, or NULL if the nodeHandle is
+         *             a document.
+         */
+        public int getDocumentRoot(int nodeHandle) {
+                // Assumption that Document Node is always in 0 slot
+                if ((nodeHandle & NODEHANDLE_MASK) == 0)
+                        return NULL;
+                return (nodeHandle & DOCHANDLE_MASK);
+        }
+
+        /**
+         * Get the string-value of a node as a String object
+         * (see http://www.w3.org/TR/xpath#data-model
+         * for the definition of a node's string-value).
+         *
+         * @param nodeHandle The node ID.
+         *
+         * @return A string object that represents the string-value of the given node.
+         */
+        public XMLString getStringValue(int nodeHandle) {
+        // ###zaj - researching
+        nodes.readSlot(nodeHandle, gotslot);
+        int nodetype=gotslot[0] & 0xFF;
+        String value=null;
+
+        switch (nodetype) {
+        case TEXT_NODE:
+        case COMMENT_NODE:
+        case CDATA_SECTION_NODE:
+                value= m_char.getString(gotslot[2], gotslot[3]);
+                break;
+        case PROCESSING_INSTRUCTION_NODE:
+        case ATTRIBUTE_NODE:
+        case ELEMENT_NODE:
+        case ENTITY_REFERENCE_NODE:
+        default:
+                break;
+        }
+        return m_xsf.newstr( value );
+
+        }
+
+        /**
+         * Get number of character array chunks in
+         * the string-value of a node.
+         * (see http://www.w3.org/TR/xpath#data-model
+         * for the definition of a node's string-value).
+         * Note that a single text node may have multiple text chunks.
+         *
+         * EXPLANATION: This method is an artifact of the fact that the
+         * underlying m_chars object may not store characters in a
+         * single contiguous array -- for example,the current
+         * FastStringBuffer may split a single node's text across
+         * multiple allocation units.  This call tells us how many
+         * separate accesses will be required to retrieve the entire
+         * content. PLEASE NOTE that this may not be the same as the
+         * number of SAX characters() events that caused the text node
+         * to be built in the first place, since m_chars buffering may
+         * be on different boundaries than the parser's buffers.
+         *
+         * @param nodeHandle The node ID.
+         *
+         * @return number of character array chunks in
+         *         the string-value of a node.
+         * */
+        //###zaj - tbd
+        public int getStringValueChunkCount(int nodeHandle)
+        {
+                //###zaj    return value
+                return 0;
+        }
+
+        /**
+         * Get a character array chunk in the string-value of a node.
+         * (see http://www.w3.org/TR/xpath#data-model
+         * for the definition of a node's string-value).
+         * Note that a single text node may have multiple text chunks.
+         *
+         * EXPLANATION: This method is an artifact of the fact that
+         * the underlying m_chars object may not store characters in a
+         * single contiguous array -- for example,the current
+         * FastStringBuffer may split a single node's text across
+         * multiple allocation units.  This call retrieves a single
+         * contiguous portion of the text -- as much as m-chars was
+         * able to store in a single allocation unit.  PLEASE NOTE
+         * that this may not be the same granularityas the SAX
+         * characters() events that caused the text node to be built
+         * in the first place, since m_chars buffering may be on
+         * different boundaries than the parser's buffers.
+         *
+         * @param nodeHandle The node ID.
+         * @param chunkIndex Which chunk to get.
+         * @param startAndLen An array of 2 where the start position and length of
+         *                    the chunk will be returned.
+         *
+         * @return The character array reference where the chunk occurs.  */
+        //###zaj - tbd
+        public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
+                                                                                                                                                int[] startAndLen) {return new char[0];}
+
+        /**
+         * Given a node handle, return an ID that represents the node's expanded name.
+         *
+         * @param nodeHandle The handle to the node in question.
+         *
+         * @return the expanded-name id of the node.
+         */
+        public int getExpandedTypeID(int nodeHandle) {
+           nodes.readSlot(nodeHandle, gotslot);
+           String qName = m_localNames.indexToString(gotslot[3]);
+           // Remove prefix from qName
+           // %TBD% jjk This is assuming the elementName is the qName.
+           int colonpos = qName.indexOf(":");
+           String localName = qName.substring(colonpos+1);
+           // Get NS
+           String namespace = m_nsNames.indexToString(gotslot[0] << 16);
+           // Create expanded name
+           String expandedName = namespace + ":" + localName;
+           int expandedNameID = m_nsNames.stringToIndex(expandedName);
+
+        return expandedNameID;
+        }
+
+
+        /**
+         * Given an expanded name, return an ID.  If the expanded-name does not
+         * exist in the internal tables, the entry will be created, and the ID will
+         * be returned.  Any additional nodes that are created that have this
+         * expanded name will use this ID.
+         *
+         * @return the expanded-name id of the node.
+         */
+        public int getExpandedTypeID(String namespace, String localName, int type) {
+           // Create expanded name
+          // %TBD% jjk Expanded name is bitfield-encoded as
+          // typeID[6]nsuriID[10]localID[16]. Switch to that form, and to
+          // accessing the ns/local via their tables rather than confusing
+          // nsnames and expandednames.
+           String expandedName = namespace + ":" + localName;
+           int expandedNameID = m_nsNames.stringToIndex(expandedName);
+
+           return expandedNameID;
+        }
+
+
+        /**
+         * Given an expanded-name ID, return the local name part.
+         *
+         * @param ExpandedNameID an ID that represents an expanded-name.
+         * @return String Local name of this node.
+         */
+        public String getLocalNameFromExpandedNameID(int ExpandedNameID) {
+
+           // Get expanded name
+           String expandedName = m_localNames.indexToString(ExpandedNameID);
+           // Remove prefix from expanded name
+           int colonpos = expandedName.indexOf(":");
+           String localName = expandedName.substring(colonpos+1);
+           return localName;
+        }
+
+
+        /**
+         * Given an expanded-name ID, return the namespace URI part.
+         *
+         * @param ExpandedNameID an ID that represents an expanded-name.
+         * @return String URI value of this node's namespace, or null if no
+         * namespace was resolved.
+        */
+        public String getNamespaceFromExpandedNameID(int ExpandedNameID) {
+
+           String expandedName = m_localNames.indexToString(ExpandedNameID);
+           // Remove local name from expanded name
+           int colonpos = expandedName.indexOf(":");
+           String nsName = expandedName.substring(0, colonpos);
+
+        return nsName;
+        }
+
+
+        /**
+         * fixednames
+        */
+        private static final String[] fixednames=
+        {
+                null,null,							// nothing, Element
+                null,"#text",						// Attr, Text
+                "#cdata_section",null,	// CDATA, EntityReference
+                null,null,							// Entity, PI
+                "#comment","#document",	// Comment, Document
+                null,"#document-fragment", // Doctype, DocumentFragment
+                null};									// Notation
+
+        /**
+         * Given a node handle, return its DOM-style node name. This will
+         * include names such as #text or #document.
+         *
+         * @param nodeHandle the id of the node.
+         * @return String Name of this node, which may be an empty string.
+         * %REVIEW% Document when empty string is possible...
+         */
+        public String getNodeName(int nodeHandle) {
+                nodes.readSlot(nodeHandle, gotslot);
+                short type = (short) (gotslot[0] & 0xFFFF);
+                String name = fixednames[type];
+                if (null == name) {
+                  int i=gotslot[3];
+                  /**/System.out.println("got i="+i+" "+(i>>16)+"/"+(i&0xffff));
+
+                  name=m_localNames.indexToString(i & 0xFFFF);
+                  String prefix=m_prefixNames.indexToString(i >>16);
+                  if(prefix!=null && prefix.length()>0)
+                    name=prefix+":"+name;
+                }
+                return name;
+        }
+
+        /**
+         * Given a node handle, return the XPath node name.  This should be
+         * the name as described by the XPath data model, NOT the DOM-style
+         * name.
+         *
+         * @param nodeHandle the id of the node.
+         * @return String Name of this node.
+         */
+        public String getNodeNameX(int nodeHandle) {return null;}
+
+        /**
+         * Given a node handle, return its DOM-style localname.
+         * (As defined in Namespaces, this is the portion of the name after any
+         * colon character)
+         *
+         * %REVIEW% What's the local name of something other than Element/Attr?
+         * Should this be DOM-style (undefined unless namespaced), or other?
+         *
+         * @param nodeHandle the id of the node.
+         * @return String Local name of this node.
+         */
+        public String getLocalName(int nodeHandle) {
+                nodes.readSlot(nodeHandle, gotslot);
+                short type = (short) (gotslot[0] & 0xFFFF);
+                String name = "";
+                if ((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
+                  int i=gotslot[3];
+                  name=m_localNames.indexToString(i & 0xFFFF);
+                  if(name==null) name="";
+                }
+                return name;
+        }
+
+        /**
+         * Given a namespace handle, return the prefix that the namespace decl is
+         * mapping.
+         * Given a node handle, return the prefix used to map to the namespace.
+         *
+         * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
+         *
+         * %REVIEW%  Should this be DOM-style (undefined unless namespaced),
+         * or other?
+         *
+         * @param nodeHandle the id of the node.
+         * @return String prefix of this node's name, or "" if no explicit
+         * namespace prefix was given.
+         */
+        public String getPrefix(int nodeHandle) {
+                nodes.readSlot(nodeHandle, gotslot);
+                short type = (short) (gotslot[0] & 0xFFFF);
+                String name = "";
+                if((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
+                  int i=gotslot[3];
+                  name=m_prefixNames.indexToString(i >>16);
+                  if(name==null) name="";
+                }
+                return name;
+        }
+
+        /**
+         * Given a node handle, return its DOM-style namespace URI
+         * (As defined in Namespaces, this is the declared URI which this node's
+         * prefix -- or default in lieu thereof -- was mapped to.)
+         *
+         * @param nodeHandle the id of the node.
+         * @return String URI value of this node's namespace, or null if no
+         * namespace was resolved.
+         */
+        public String getNamespaceURI(int nodeHandle) {return null;}
+
+        /**
+         * Given a node handle, return its node value. This is mostly
+         * as defined by the DOM, but may ignore some conveniences.
+         * <p>
+         *
+         * @param nodeHandle The node id.
+         * @return String Value of this node, or null if not
+         * meaningful for this node type.
+         */
+        public String getNodeValue(int nodeHandle)
+        {
+                nodes.readSlot(nodeHandle, gotslot);
+                int nodetype=gotslot[0] & 0xFF;		// ###zaj use mask to get node type
+                String value=null;
+
+                switch (nodetype) {			// ###zaj todo - document nodetypes
+                case ATTRIBUTE_NODE:
+                        nodes.readSlot(nodeHandle+1, gotslot);
+                case TEXT_NODE:
+                case COMMENT_NODE:
+                case CDATA_SECTION_NODE:
+                        value=m_char.getString(gotslot[2], gotslot[3]);		//###zaj
+                        break;
+                case PROCESSING_INSTRUCTION_NODE:
+                case ELEMENT_NODE:
+                case ENTITY_REFERENCE_NODE:
+                default:
+                        break;
+                }
+                return value;
+        }
+
+        /**
+         * Given a node handle, return its DOM-style node type.
+         * <p>
+         * %REVIEW% Generally, returning short is false economy. Return int?
+         *
+         * @param nodeHandle The node id.
+         * @return int Node type, as per the DOM's Node._NODE constants.
+         */
+        public short getNodeType(int nodeHandle) {
+                return(short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
+        }
+
+        /**
+         * Get the depth level of this node in the tree (equals 1 for
+         * a parentless node).
+         *
+         * @param nodeHandle The node id.
+         * @return the number of ancestors, plus one
+         * @xsl.usage internal
+         */
+        public short getLevel(int nodeHandle) {
+                short count = 0;
+                while (nodeHandle != 0) {
+                        count++;
+                        nodeHandle = nodes.readEntry(nodeHandle, 1);
+                }
+                return count;
+        }
+
+        // ============== Document query functions ==============
+
+        /**
+         * Tests whether DTM DOM implementation implements a specific feature and
+         * that feature is supported by this node.
+         *
+         * @param feature The name of the feature to test.
+         * @param version This is the version number of the feature to test.
+         *   If the version is not
+         *   specified, supporting any version of the feature will cause the
+         *   method to return <code>true</code>.
+         * @return Returns <code>true</code> if the specified feature is
+         *   supported on this node, <code>false</code> otherwise.
+         */
+        public boolean isSupported(String feature, String version) {return false;}
+
+        /**
+         * Return the base URI of the document entity. If it is not known
+         * (because the document was parsed from a socket connection or from
+         * standard input, for example), the value of this property is unknown.
+         *
+         * @return the document base URI String object or null if unknown.
+         */
+        public String getDocumentBaseURI()
+        {
+
+          return m_documentBaseURI;
+        }
+
+        /**
+         * Set the base URI of the document entity.
+         *
+         * @param baseURI the document base URI String object or null if unknown.
+         */
+        public void setDocumentBaseURI(String baseURI)
+        {
+
+          m_documentBaseURI = baseURI;
+        }
+
+        /**
+         * Return the system identifier of the document entity. If
+         * it is not known, the value of this property is unknown.
+         *
+         * @param nodeHandle The node id, which can be any valid node handle.
+         * @return the system identifier String object or null if unknown.
+         */
+        public String getDocumentSystemIdentifier(int nodeHandle) {return null;}
+
+        /**
+         * Return the name of the character encoding scheme
+         *        in which the document entity is expressed.
+         *
+         * @param nodeHandle The node id, which can be any valid node handle.
+         * @return the document encoding String object.
+         */
+        public String getDocumentEncoding(int nodeHandle) {return null;}
+
+        /**
+         * Return an indication of the standalone status of the document,
+         *        either "yes" or "no". This property is derived from the optional
+         *        standalone document declaration in the XML declaration at the
+         *        beginning of the document entity, and has no value if there is no
+         *        standalone document declaration.
+         *
+         * @param nodeHandle The node id, which can be any valid node handle.
+         * @return the document standalone String object, either "yes", "no", or null.
+         */
+        public String getDocumentStandalone(int nodeHandle) {return null;}
+
+        /**
+         * Return a string representing the XML version of the document. This
+         * property is derived from the XML declaration optionally present at the
+         * beginning of the document entity, and has no value if there is no XML
+         * declaration.
+         *
+         * @param documentHandle the document handle
+         *
+         * @return the document version String object
+         */
+        public String getDocumentVersion(int documentHandle) {return null;}
+
+        /**
+         * Return an indication of
+         * whether the processor has read the complete DTD. Its value is a
+         * boolean. If it is false, then certain properties (indicated in their
+         * descriptions below) may be unknown. If it is true, those properties
+         * are never unknown.
+         *
+         * @return <code>true</code> if all declarations were processed {};
+         *         <code>false</code> otherwise.
+         */
+        public boolean getDocumentAllDeclarationsProcessed() {return false;}
+
+        /**
+         *   A document type declaration information item has the following properties:
+         *
+         *     1. [system identifier] The system identifier of the external subset, if
+         *        it exists. Otherwise this property has no value.
+         *
+         * @return the system identifier String object, or null if there is none.
+         */
+        public String getDocumentTypeDeclarationSystemIdentifier() {return null;}
+
+        /**
+         * Return the public identifier of the external subset,
+         * normalized as described in 4.2.2 External Entities [XML]. If there is
+         * no external subset or if it has no public identifier, this property
+         * has no value.
+         *
+         * @return the public identifier String object, or null if there is none.
+         */
+        public String getDocumentTypeDeclarationPublicIdentifier() {return null;}
+
+        /**
+         * Returns the <code>Element</code> whose <code>ID</code> is given by
+         * <code>elementId</code>. If no such element exists, returns
+         * <code>DTM.NULL</code>. Behavior is not defined if more than one element
+         * has this <code>ID</code>. Attributes (including those
+         * with the name "ID") are not of type ID unless so defined by DTD/Schema
+         * information available to the DTM implementation.
+         * Implementations that do not know whether attributes are of type ID or
+         * not are expected to return <code>DTM.NULL</code>.
+         *
+         * <p>%REVIEW% Presumably IDs are still scoped to a single document,
+         * and this operation searches only within a single document, right?
+         * Wouldn't want collisions between DTMs in the same process.</p>
+         *
+         * @param elementId The unique <code>id</code> value for an element.
+         * @return The handle of the matching element.
+         */
+        public int getElementById(String elementId) {return 0;}
+
+        /**
+         * The getUnparsedEntityURI function returns the URI of the unparsed
+         * entity with the specified name in the same document as the context
+         * node (see [3.3 Unparsed Entities]). It returns the empty string if
+         * there is no such entity.
+         * <p>
+         * XML processors may choose to use the System Identifier (if one
+         * is provided) to resolve the entity, rather than the URI in the
+         * Public Identifier. The details are dependent on the processor, and
+         * we would have to support some form of plug-in resolver to handle
+         * this properly. Currently, we simply return the System Identifier if
+         * present, and hope that it a usable URI or that our caller can
+         * map it to one.
+         * TODO: Resolve Public Identifiers... or consider changing function name.
+         * <p>
+         * If we find a relative URI
+         * reference, XML expects it to be resolved in terms of the base URI
+         * of the document. The DOM doesn't do that for us, and it isn't
+         * entirely clear whether that should be done here; currently that's
+         * pushed up to a higher level of our application. (Note that DOM Level
+         * 1 didn't store the document's base URI.)
+         * TODO: Consider resolving Relative URIs.
+         * <p>
+         * (The DOM's statement that "An XML processor may choose to
+         * completely expand entities before the structure model is passed
+         * to the DOM" refers only to parsed entities, not unparsed, and hence
+         * doesn't affect this function.)
+         *
+         * @param name A string containing the Entity Name of the unparsed
+         * entity.
+         *
+         * @return String containing the URI of the Unparsed Entity, or an
+         * empty string if no such entity exists.
+         */
+        public String getUnparsedEntityURI(String name) {return null;}
+
+
+        // ============== Boolean methods ================
+
+        /**
+         * Return true if the xsl:strip-space or xsl:preserve-space was processed
+         * during construction of the DTM document.
+         *
+         * <p>%REVEIW% Presumes a 1:1 mapping from DTM to Document, since
+         * we aren't saying which Document to query...?</p>
+         */
+        public boolean supportsPreStripping() {return false;}
+
+        /**
+         * Figure out whether nodeHandle2 should be considered as being later
+         * in the document than nodeHandle1, in Document Order as defined
+         * by the XPath model. This may not agree with the ordering defined
+         * by other XML applications.
+         * <p>
+         * There are some cases where ordering isn't defined, and neither are
+         * the results of this function -- though we'll generally return true.
+         *
+         * TODO: Make sure this does the right thing with attribute nodes!!!
+         *
+         * @param nodeHandle1 DOM Node to perform position comparison on.
+         * @param nodeHandle2 DOM Node to perform position comparison on .
+         *
+         * @return false if node2 comes before node1, otherwise return true.
+         * You can think of this as
+         * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
+         */
+        public boolean isNodeAfter(int nodeHandle1, int nodeHandle2) {return false;}
+
+        /**
+         *     2. [element content whitespace] A boolean indicating whether the
+         *        character is white space appearing within element content (see [XML],
+         *        2.10 "White Space Handling"). Note that validating XML processors are
+         *        required by XML 1.0 to provide this information. If there is no
+         *        declaration for the containing element, this property has no value for
+         *        white space characters. If no declaration has been read, but the [all
+         *        declarations processed] property of the document information item is
+         *        false (so there may be an unread declaration), then the value of this
+         *        property is unknown for white space characters. It is always false for
+         *        characters that are not white space.
+         *
+         * @param nodeHandle the node ID.
+         * @return <code>true</code> if the character data is whitespace;
+         *         <code>false</code> otherwise.
+         */
+        public boolean isCharacterElementContentWhitespace(int nodeHandle) {return false;}
+
+        /**
+         *    10. [all declarations processed] This property is not strictly speaking
+         *        part of the infoset of the document. Rather it is an indication of
+         *        whether the processor has read the complete DTD. Its value is a
+         *        boolean. If it is false, then certain properties (indicated in their
+         *        descriptions below) may be unknown. If it is true, those properties
+         *        are never unknown.
+         *
+         * @param documentHandle A node handle that must identify a document.
+         * @return <code>true</code> if all declarations were processed;
+         *         <code>false</code> otherwise.
+         */
+        public boolean isDocumentAllDeclarationsProcessed(int documentHandle) {return false;}
+
+        /**
+         *     5. [specified] A flag indicating whether this attribute was actually
+         *        specified in the start-tag of its element, or was defaulted from the
+         *        DTD.
+         *
+         * @param attributeHandle the attribute handle
+         * @return <code>true</code> if the attribute was specified;
+         *         <code>false</code> if it was defaulted.
+         */
+        public boolean isAttributeSpecified(int attributeHandle) {return false;}
+
+        // ========== Direct SAX Dispatch, for optimization purposes ========
+
+        /**
+         * Directly call the
+         * characters method on the passed ContentHandler for the
+         * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+         * for the definition of a node's string-value). Multiple calls to the
+         * ContentHandler's characters methods may well occur for a single call to
+         * this method.
+         *
+         * @param nodeHandle The node ID.
+         * @param ch A non-null reference to a ContentHandler.
+         *
+         * @throws org.xml.sax.SAXException
+         */
+        public void dispatchCharactersEvents(
+                                                                                                                                                        int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize)
+        throws org.xml.sax.SAXException {}
+
+        /**
+         * Directly create SAX parser events from a subtree.
+         *
+         * @param nodeHandle The node ID.
+         * @param ch A non-null reference to a ContentHandler.
+         *
+         * @throws org.xml.sax.SAXException
+         */
+
+        public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
+        throws org.xml.sax.SAXException {}
+
+        /**
+         * Return an DOM node for the given node.
+         *
+         * @param nodeHandle The node ID.
+         *
+         * @return A node representation of the DTM node.
+         */
+        public org.w3c.dom.Node getNode(int nodeHandle)
+        {
+          return null;
+        }
+
+        // ==== Construction methods (may not be supported by some implementations!) =====
+        // %REVIEW% jjk: These probably aren't the right API. At the very least
+        // they need to deal with current-insertion-location and end-element
+        // issues.
+
+        /**
+         * Append a child to the end of the child list of the current node. Please note that the node
+         * is always cloned if it is owned by another document.
+         *
+         * <p>%REVIEW% "End of the document" needs to be defined more clearly.
+         * Does it become the last child of the Document? Of the root element?</p>
+         *
+         * @param newChild Must be a valid new node handle.
+         * @param clone true if the child should be cloned into the document.
+         * @param cloneDepth if the clone argument is true, specifies that the
+         *                   clone should include all it's children.
+         */
+        public void appendChild(int newChild, boolean clone, boolean cloneDepth) {
+                boolean sameDoc = ((newChild & DOCHANDLE_MASK) == m_docHandle);
+                if (clone || !sameDoc) {
+
+                } else {
+
+                }
+        }
+
+        /**
+         * Append a text node child that will be constructed from a string,
+         * to the end of the document.
+         *
+         * <p>%REVIEW% "End of the document" needs to be defined more clearly.
+         * Does it become the last child of the Document? Of the root element?</p>
+         *
+         * @param str Non-null reference to a string.
+         */
+        public void appendTextChild(String str) {
+                // ###shs Think more about how this differs from createTextNode
+          //%TBD%
+        }
+
+
+  //================================================================
+  // ==== BUILDER methods ====
+  // %TBD% jjk: SHOULD PROBABLY BE INLINED, unless we want to support
+  // both SAX1 and SAX2 and share this logic between them.
+
+  /** Append a text child at the current insertion point. Assumes that the
+   * actual content of the text has previously been appended to the m_char
+   * buffer (shared with the builder).
+   *
+   * @param m_char_current_start int Starting offset of node's content in m_char.
+   * @param contentLength int Length of node's content in m_char.
+   * */
+  void appendTextChild(int m_char_current_start,int contentLength)
+  {
+    // create a Text Node
+    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
+    int w0 = TEXT_NODE;
+    // W1: Parent
+    int w1 = currentParent;
+    // W2: Start position within m_char
+    int w2 = m_char_current_start;
+    // W3: Length of the full string
+    int w3 = contentLength;
+
+    int ourslot = appendNode(w0, w1, w2, w3);
+    previousSibling = ourslot;
+  }
+
+  /** Append a comment child at the current insertion point. Assumes that the
+   * actual content of the comment has previously been appended to the m_char
+   * buffer (shared with the builder).
+   *
+   * @param m_char_current_start int Starting offset of node's content in m_char.
+   * @param contentLength int Length of node's content in m_char.
+   * */
+  void appendComment(int m_char_current_start,int contentLength)
+  {
+    // create a Comment Node
+    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
+    int w0 = COMMENT_NODE;
+    // W1: Parent
+    int w1 = currentParent;
+    // W2: Start position within m_char
+    int w2 = m_char_current_start;
+    // W3: Length of the full string
+    int w3 = contentLength;
+
+    int ourslot = appendNode(w0, w1, w2, w3);
+    previousSibling = ourslot;
+  }
+
+
+  /** Append an Element child at the current insertion point. This
+   * Element then _becomes_ the insertion point; subsequent appends
+   * become its lastChild until an appendEndElement() call is made.
+   *
+   * Assumes that the symbols (local name, namespace URI and prefix)
+   * have already been added to the pools
+   *
+   * Note that this _only_ handles the Element node itself. Attrs and
+   * namespace nodes are unbundled in the ContentHandler layer
+   * and appended separately.
+   *
+   * @param namespaceIndex: Index within the namespaceURI string pool
+   * @param localNameIndex Index within the local name string pool
+   * @param prefixIndex: Index within the prefix string pool
+   * */
+  void appendStartElement(int namespaceIndex,int localNameIndex, int prefixIndex)
+  {
+                // do document root node creation here on the first element, create nodes for
+                // this element and its attributes, store the element, namespace, and attritute
+                // name indexes to the nodes array, keep track of the current node and parent
+                // element used
+
+                // W0  High:  Namespace  Low:  Node Type
+                int w0 = (namespaceIndex << 16) | ELEMENT_NODE;
+                // W1: Parent
+                int w1 = currentParent;
+                // W2: Next  (initialized as 0)
+                int w2 = 0;
+                // W3: Tagname high: prefix Low: local name
+                int w3 = localNameIndex | prefixIndex<<16;
+                /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));
+
+                //int ourslot = nodes.appendSlot(w0, w1, w2, w3);
+                int ourslot = appendNode(w0, w1, w2, w3);
+                currentParent = ourslot;
+                previousSibling = 0;
+
+                // set the root element pointer when creating the first element node
+                if (m_docElement == NULL)
+                        m_docElement = ourslot;
+  }
+
+  /** Append a Namespace Declaration child at the current insertion point.
+   * Assumes that the symbols (namespace URI and prefix) have already been
+   * added to the pools
+   *
+   * @param prefixIndex: Index within the prefix string pool
+   * @param namespaceIndex: Index within the namespaceURI string pool
+   * @param isID: If someone really insists on writing a bad DTD, it is
+   * theoretically possible for a namespace declaration to also be declared
+   * as being a node ID. I don't really want to support that stupidity,
+   * but I'm not sure we can refuse to accept it.
+   * */
+  void appendNSDeclaration(int prefixIndex, int namespaceIndex,
+                           boolean isID)
+  {
+    // %REVIEW% I'm assigning this node the "namespace for namespaces"
+    // which the DOM defined. It is expected that the Namespace spec will
+    // adopt this as official. It isn't strictly needed since it's implied
+    // by the nodetype, but for now...
+
+    // %REVIEW% Prefix need not be recorded; it's implied too. But
+    // recording it might simplify the design.
+
+    // %TBD% isID is not currently honored.
+
+    final int namespaceForNamespaces=m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/");
+
+    // W0  High:  Namespace  Low:  Node Type
+    int w0 = NAMESPACE_NODE | (m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/")<<16);
+
+    // W1:  Parent
+    int w1 = currentParent;
+    // W2:  CURRENTLY UNUSED -- It's next-sib in attrs, but we have no kids.
+    int w2 = 0;
+    // W3:  namespace name
+    int w3 = namespaceIndex;
+    // Add node
+    int ourslot = appendNode(w0, w1, w2, w3);
+    previousSibling = ourslot;	// Should attributes be previous siblings
+    previousSiblingWasParent = false;
+    return ;//(m_docHandle | ourslot);
+  }
+
+  /** Append an Attribute child at the current insertion
+   * point.  Assumes that the symbols (namespace URI, local name, and
+   * prefix) have already been added to the pools, and that the content has
+   * already been appended to m_char. Note that the attribute's content has
+   * been flattened into a single string; DTM does _NOT_ attempt to model
+   * the details of entity references within attribute values.
+   *
+   * @param namespaceIndex int Index within the namespaceURI string pool
+   * @param localNameIndex int Index within the local name string pool
+   * @param prefixIndex int Index within the prefix string pool
+   * @param isID boolean True if this attribute was declared as an ID
+   * (for use in supporting getElementByID).
+   * @param m_char_current_start int Starting offset of node's content in m_char.
+   * @param contentLength int Length of node's content in m_char.
+   * */
+  void appendAttribute(int namespaceIndex, int localNameIndex, int prefixIndex,
+                       boolean isID,
+                       int m_char_current_start, int contentLength)
+  {
+    // %TBD% isID is not currently honored.
+
+    // W0  High:  Namespace  Low:  Node Type
+    int w0 = ATTRIBUTE_NODE | namespaceIndex<<16;
+
+    // W1:  Parent
+    int w1 = currentParent;
+    // W2:  Next (not yet resolved)
+    int w2 = 0;
+    // W3:  Tagname high: prefix Low: local name
+    int w3 = localNameIndex | prefixIndex<<16;
+    /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));
+    // Add node
+    int ourslot = appendNode(w0, w1, w2, w3);
+    previousSibling = ourslot;	// Should attributes be previous siblings
+
+    // Attribute's content is currently appended as a Text Node
+
+    // W0: Node Type
+    w0 = TEXT_NODE;
+    // W1: Parent
+    w1 = ourslot;
+    // W2: Start Position within buffer
+    w2 = m_char_current_start;
+    // W3: Length
+    w3 = contentLength;
+    appendNode(w0, w1, w2, w3);
+
+    // Attrs are Parents
+    previousSiblingWasParent = true;
+    return ;//(m_docHandle | ourslot);
+  }
+
+  /**
+   * This returns a stateless "traverser", that can navigate over an
+   * XPath axis, though not in document order.
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisIterator, or null if the given axis isn't supported.
+   */
+  public DTMAxisTraverser getAxisTraverser(final int axis)
+  {
+    return null;
+  }
+
+  /**
+   * This is a shortcut to the iterators that implement the
+   * supported XPath axes (only namespace::) is not supported.
+   * Returns a bare-bones iterator that must be initialized
+   * with a start node (using iterator.setStartNode()).
+   *
+   * @param axis One of Axes.ANCESTORORSELF, etc.
+   *
+   * @return A DTMAxisIterator, or null if the given axis isn't supported.
+   */
+  public DTMAxisIterator getAxisIterator(final int axis)
+  {
+    // %TBD%
+    return null;
+  }
+
+  /**
+   * Get an iterator that can navigate over an XPath Axis, predicated by
+   * the extended type ID.
+   *
+   *
+   * @param axis
+   * @param type An extended type ID.
+   *
+   * @return A DTMAxisIterator, or null if the given axis isn't supported.
+   */
+  public DTMAxisIterator getTypedAxisIterator(final int axis, final int type)
+  {
+    // %TBD%
+    return null;
+  }
+
+
+  /** Terminate the element currently acting as an insertion point. Subsequent
+   * insertions will occur as the last child of this element's parent.
+   * */
+  void appendEndElement()
+  {
+    // pop up the stacks
+
+    if (previousSiblingWasParent)
+      nodes.writeEntry(previousSibling, 2, NULL);
+
+    // Pop parentage
+    previousSibling = currentParent;
+    nodes.readSlot(currentParent, gotslot);
+    currentParent = gotslot[1] & 0xFFFF;
+
+    // The element just being finished will be
+    // the previous sibling for the next operation
+    previousSiblingWasParent = true;
+
+    // Pop a level of namespace table
+    // namespaceTable.removeLastElem();
+  }
+
+  /**  Starting a new document. Perform any resets/initialization
+   * not already handled.
+   * */
+  void appendStartDocument()
+  {
+
+    // %TBD% reset slot 0 to indicate ChunkedIntArray reuse or wait for
+    //       the next initDocument().
+    m_docElement = NULL;	 // reset nodeHandle to the root of the actual dtm doc content
+    initDocument(0);
+  }
+
+  /**  All appends to this document have finished; do whatever final
+   * cleanup is needed.
+   * */
+  void appendEndDocument()
+  {
+    done = true;
+    // %TBD% may need to notice the last slot number and slot count to avoid
+    // residual data from provious use of this DTM
+  }
+
+  /**
+   * For the moment all the run time properties are ignored by this
+   * class.
+   *
+   * @param property a <code>String</code> value
+   * @param value an <code>Object</code> value
+   */
+  public void setProperty(String property, Object value)
+  {
+  }
+
+  /**
+   * Source information is not handled yet, so return
+   * <code>null</code> here.
+   *
+   * @param node an <code>int</code> value
+   * @return null
+   */
+  public SourceLocator getSourceLocatorFor(int node)
+  {
+    return null;
+  }
+
+
+  /**
+   * A dummy routine to satisify the abstract interface. If the DTM
+   * implememtation that extends the default base requires notification
+   * of registration, they can override this method.
+   */
+   public void documentRegistration()
+   {
+   }
+
+  /**
+   * A dummy routine to satisify the abstract interface. If the DTM
+   * implememtation that extends the default base requires notification
+   * when the document is being released, they can override this method
+   */
+   public void documentRelease()
+   {
+   }
+
+   /**
+    * Migrate a DTM built with an old DTMManager to a new DTMManager.
+    * After the migration, the new DTMManager will treat the DTM as
+    * one that is built by itself.
+    * This is used to support DTM sharing between multiple transformations.
+    * @param manager the DTMManager
+    */
+   public void migrateTo(DTMManager manager)
+   {
+   }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMManagerDefault.java b/src/main/java/org/apache/xml/dtm/ref/DTMManagerDefault.java
new file mode 100644
index 0000000..5ba4151
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMManagerDefault.java
@@ -0,0 +1,859 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMManagerDefault.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMException;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.dtm.ref.dom2dtm.DOM2DTM;
+import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
+import org.apache.xml.dtm.ref.sax2dtm.SAX2RTFDTM;
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.SystemIDResolver;
+import org.apache.xml.utils.XMLReaderManager;
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * The default implementation for the DTMManager.
+ *
+ * %REVIEW% There is currently a reentrancy issue, since the finalizer
+ * for XRTreeFrag (which runs in the GC thread) wants to call
+ * DTMManager.release(), and may do so at the same time that the main
+ * transformation thread is accessing the manager. Our current solution is
+ * to make most of the manager's methods <code>synchronized</code>.
+ * Early tests suggest that doing so is not causing a significant
+ * performance hit in Xalan. However, it should be noted that there
+ * is a possible alternative solution: rewrite release() so it merely
+ * posts a request for release onto a threadsafe queue, and explicitly
+ * process that queue on an infrequent basis during main-thread
+ * activity (eg, when getDTM() is invoked). The downside of that solution
+ * would be a greater delay before the DTM's storage is actually released
+ * for reuse.
+ * */
+public class DTMManagerDefault extends DTMManager
+{
+  //static final boolean JKESS_XNI_EXPERIMENT=true;
+
+  /** Set this to true if you want a dump of the DTM after creation. */
+  private static final boolean DUMPTREE = false;
+
+  /** Set this to true if you want a basic diagnostics. */
+  private static final boolean DEBUG = false;
+
+  /**
+   * Map from DTM identifier numbers to DTM objects that this manager manages.
+   * One DTM may have several prefix numbers, if extended node indexing
+   * is in use; in that case, m_dtm_offsets[] will used to control which
+   * prefix maps to which section of the DTM.
+   * 
+   * This array grows as necessary; see addDTM().
+   * 
+   * This array grows as necessary; see addDTM(). Growth is uncommon... but
+   * access needs to be blindingly fast since it's used in node addressing.
+   */
+  protected DTM m_dtms[] = new DTM[256];
+	
+  /** Map from DTM identifier numbers to offsets. For small DTMs with a 
+   * single identifier, this will always be 0. In overflow addressing, where
+   * additional identifiers are allocated to access nodes beyond the range of
+   * a single Node Handle, this table is used to map the handle's node field
+   * into the actual node identifier.
+   * 
+   * This array grows as necessary; see addDTM().
+   * 
+   * This array grows as necessary; see addDTM(). Growth is uncommon... but
+   * access needs to be blindingly fast since it's used in node addressing.
+   * (And at the moment, that includes accessing it from DTMDefaultBase,
+   * which is why this is not Protected or Private.)
+   */
+  int m_dtm_offsets[] = new int[256];
+
+  /**
+   * The cache for XMLReader objects to be used if the user did not
+   * supply an XMLReader for a SAXSource or supplied a StreamSource.
+   */
+  protected XMLReaderManager m_readerManager = null;
+  
+  /**
+   * The default implementation of ContentHandler, DTDHandler and ErrorHandler.
+   */
+  protected DefaultHandler m_defaultHandler = new DefaultHandler();
+
+  /**
+   * Add a DTM to the DTM table. This convenience call adds it as the 
+   * "base DTM ID", with offset 0. The other version of addDTM should 
+   * be used if you want to add "extended" DTM IDs with nonzero offsets.
+   *
+   * @param dtm Should be a valid reference to a DTM.
+   * @param id Integer DTM ID to be bound to this DTM
+   */
+  synchronized public void addDTM(DTM dtm, int id) {	addDTM(dtm,id,0); }
+
+	
+  /**
+   * Add a DTM to the DTM table.
+   *
+   * @param dtm Should be a valid reference to a DTM.
+   * @param id Integer DTM ID to be bound to this DTM.
+   * @param offset Integer addressing offset. The internal DTM Node ID is
+   * obtained by adding this offset to the node-number field of the 
+   * public DTM Handle. For the first DTM ID accessing each DTM, this is 0;
+   * for overflow addressing it will be a multiple of 1<<IDENT_DTM_NODE_BITS.
+   */
+  synchronized public void addDTM(DTM dtm, int id, int offset)
+  {
+		if(id>=IDENT_MAX_DTMS)
+		{
+			// TODO: %REVIEW% Not really the right error message.
+	    throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null)); //"No more DTM IDs are available!");			 
+		}
+		
+		// We used to just allocate the array size to IDENT_MAX_DTMS.
+		// But we expect to increase that to 16 bits, and I'm not willing
+		// to allocate that much space unless needed. We could use one of our
+		// handy-dandy Fast*Vectors, but this will do for now.
+		// %REVIEW%
+		int oldlen=m_dtms.length;
+		if(oldlen<=id)
+		{
+			// Various growth strategies are possible. I think we don't want 
+			// to over-allocate excessively, and I'm willing to reallocate
+			// more often to get that. See also Fast*Vector classes.
+			//
+			// %REVIEW% Should throw a more diagnostic error if we go over the max...
+			int newlen=Math.min((id+256),IDENT_MAX_DTMS);
+
+			DTM new_m_dtms[] = new DTM[newlen];
+			System.arraycopy(m_dtms,0,new_m_dtms,0,oldlen);
+			m_dtms=new_m_dtms;
+			int new_m_dtm_offsets[] = new int[newlen];
+			System.arraycopy(m_dtm_offsets,0,new_m_dtm_offsets,0,oldlen);
+			m_dtm_offsets=new_m_dtm_offsets;
+		}
+		
+    m_dtms[id] = dtm;
+		m_dtm_offsets[id]=offset;
+    dtm.documentRegistration();
+		// The DTM should have been told who its manager was when we created it.
+		// Do we need to allow for adopting DTMs _not_ created by this manager?
+  }
+
+  /**
+   * Get the first free DTM ID available. %OPT% Linear search is inefficient!
+   */
+  synchronized public int getFirstFreeDTMID()
+  {
+    int n = m_dtms.length;
+    for (int i = 1; i < n; i++)
+    {
+      if(null == m_dtms[i])
+      {
+        return i;
+      }
+    }
+		return n; // count on addDTM() to throw exception if out of range
+  }
+
+  /**
+   * The default table for exandedNameID lookups.
+   */
+  private ExpandedNameTable m_expandedNameTable =
+    new ExpandedNameTable();
+
+  /**
+   * Constructor DTMManagerDefault
+   *
+   */
+  public DTMManagerDefault(){}
+
+
+  /**
+   * Get an instance of a DTM, loaded with the content from the
+   * specified source.  If the unique flag is true, a new instance will
+   * always be returned.  Otherwise it is up to the DTMManager to return a
+   * new instance or an instance that it already created and may be being used
+   * by someone else.
+   * 
+   * A bit of magic in this implementation: If the source is null, unique is true,
+   * and incremental and doIndexing are both false, we return an instance of
+   * SAX2RTFDTM, which see.
+   * 
+   * (I think more parameters will need to be added for error handling, and entity
+   * resolution, and more explicit control of the RTF situation).
+   *
+   * @param source the specification of the source object.
+   * @param unique true if the returned DTM must be unique, probably because it
+   * is going to be mutated.
+   * @param whiteSpaceFilter Enables filtering of whitespace nodes, and may
+   *                         be null.
+   * @param incremental true if the DTM should be built incrementally, if
+   *                    possible.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   *
+   * @return a non-null DTM reference.
+   */
+  synchronized public DTM getDTM(Source source, boolean unique,
+                                 DTMWSFilter whiteSpaceFilter,
+                                 boolean incremental, boolean doIndexing)
+  {
+
+    if(DEBUG && null != source)
+      System.out.println("Starting "+
+                         (unique ? "UNIQUE" : "shared")+
+                         " source: "+source.getSystemId()
+                         );
+
+    XMLStringFactory xstringFactory = m_xsf;
+    int dtmPos = getFirstFreeDTMID();
+    int documentID = dtmPos << IDENT_DTM_NODE_BITS;
+
+    if ((null != source) && source instanceof DOMSource)
+    {
+      DOM2DTM dtm = new DOM2DTM(this, (DOMSource) source, documentID,
+                                whiteSpaceFilter, xstringFactory, doIndexing);
+
+      addDTM(dtm, dtmPos, 0);
+
+      //      if (DUMPTREE)
+      //      {
+      //        dtm.dumpDTM();
+      //      }
+
+      return dtm;
+    }
+    else
+    {
+      boolean isSAXSource = (null != source)
+        ? (source instanceof SAXSource) : true;
+      boolean isStreamSource = (null != source)
+        ? (source instanceof StreamSource) : false;
+
+      if (isSAXSource || isStreamSource) {
+        XMLReader reader = null;
+        SAX2DTM dtm;
+
+        try {
+          InputSource xmlSource;
+
+          if (null == source) {
+            xmlSource = null;
+          } else {
+            reader = getXMLReader(source);
+            xmlSource = SAXSource.sourceToInputSource(source);
+
+            String urlOfSource = xmlSource.getSystemId();
+
+            if (null != urlOfSource) {
+              try {
+                urlOfSource = SystemIDResolver.getAbsoluteURI(urlOfSource);
+              } catch (Exception e) {
+                // %REVIEW% Is there a better way to send a warning?
+                System.err.println("Can not absolutize URL: " + urlOfSource);
+              }
+
+              xmlSource.setSystemId(urlOfSource);
+            }
+          }
+
+          if (source==null && unique && !incremental && !doIndexing) {
+            // Special case to support RTF construction into shared DTM.
+            // It should actually still work for other uses,
+            // but may be slightly deoptimized relative to the base
+            // to allow it to deal with carrying multiple documents.
+            //
+            // %REVIEW% This is a sloppy way to request this mode;
+            // we need to consider architectural improvements.
+            dtm = new SAX2RTFDTM(this, source, documentID, whiteSpaceFilter,
+                                 xstringFactory, doIndexing);
+          }
+          /**************************************************************
+          // EXPERIMENTAL 3/22/02
+          else if(JKESS_XNI_EXPERIMENT && m_incremental) {        	
+            dtm = new XNI2DTM(this, source, documentID, whiteSpaceFilter,
+                              xstringFactory, doIndexing);
+          }
+          **************************************************************/
+          // Create the basic SAX2DTM.
+          else {
+            dtm = new SAX2DTM(this, source, documentID, whiteSpaceFilter,
+                              xstringFactory, doIndexing);
+          }
+
+          // Go ahead and add the DTM to the lookup table.  This needs to be
+          // done before any parsing occurs. Note offset 0, since we've just
+          // created a new DTM.
+          addDTM(dtm, dtmPos, 0);
+
+
+          boolean haveXercesParser =
+                     (null != reader)
+                     && (reader.getClass()
+                               .getName()
+                               .equals("org.apache.xerces.parsers.SAXParser") );
+        
+          if (haveXercesParser) {
+            incremental = true;  // No matter what.  %REVIEW%
+          }
+        
+          // If the reader is null, but they still requested an incremental
+          // build, then we still want to set up the IncrementalSAXSource stuff.
+          if (m_incremental && incremental
+               /* || ((null == reader) && incremental) */) {
+            IncrementalSAXSource coParser=null;
+
+            if (haveXercesParser) {
+              // IncrementalSAXSource_Xerces to avoid threading.
+              try {
+                coParser =(IncrementalSAXSource)
+                  Class.forName("org.apache.xml.dtm.ref.IncrementalSAXSource_Xerces").newInstance();  
+              }  catch( Exception ex ) {
+                ex.printStackTrace();
+                coParser=null;
+              }
+            }
+
+            if (coParser==null ) {
+              // Create a IncrementalSAXSource to run on the secondary thread.
+              if (null == reader) {
+                coParser = new IncrementalSAXSource_Filter();
+              } else {
+                IncrementalSAXSource_Filter filter =
+                         new IncrementalSAXSource_Filter();
+                filter.setXMLReader(reader);
+                coParser=filter;
+              }
+            }
+
+			
+            /**************************************************************
+            // EXPERIMENTAL 3/22/02
+            if (JKESS_XNI_EXPERIMENT && m_incremental &&
+                  dtm instanceof XNI2DTM && 
+                  coParser instanceof IncrementalSAXSource_Xerces) {
+                org.apache.xerces.xni.parser.XMLPullParserConfiguration xpc=
+                      ((IncrementalSAXSource_Xerces)coParser)
+                                           .getXNIParserConfiguration();
+              if (xpc!=null) {
+                // Bypass SAX; listen to the XNI stream
+                ((XNI2DTM)dtm).setIncrementalXNISource(xpc);
+              } else {
+                  // Listen to the SAX stream (will fail, diagnostically...)
+                dtm.setIncrementalSAXSource(coParser);
+              }
+            } else
+            ***************************************************************/
+          
+            // Have the DTM set itself up as IncrementalSAXSource's listener.
+            dtm.setIncrementalSAXSource(coParser);
+
+            if (null == xmlSource) {
+
+              // Then the user will construct it themselves.
+              return dtm;
+            }
+
+            if (null == reader.getErrorHandler()) {
+              reader.setErrorHandler(dtm);
+            }
+            reader.setDTDHandler(dtm);
+
+            try {
+              // Launch parsing coroutine.  Launches a second thread,
+              // if we're using IncrementalSAXSource.filter().
+
+              coParser.startParse(xmlSource);
+            } catch (RuntimeException re) {
+
+              dtm.clearCoRoutine();
+
+              throw re;
+            } catch (Exception e) {
+
+              dtm.clearCoRoutine();
+
+              throw new org.apache.xml.utils.WrappedRuntimeException(e);
+            }
+          } else {
+            if (null == reader) {
+
+              // Then the user will construct it themselves.
+              return dtm;
+            }
+
+            // not incremental
+            reader.setContentHandler(dtm);
+            reader.setDTDHandler(dtm);
+            if (null == reader.getErrorHandler()) {
+              reader.setErrorHandler(dtm);
+            }
+
+            try {
+              reader.setProperty(
+                               "http://xml.org/sax/properties/lexical-handler",
+                               dtm);
+            } catch (SAXNotRecognizedException e){}
+              catch (SAXNotSupportedException e){}
+
+            try {
+              reader.parse(xmlSource);
+            } catch (RuntimeException re) {
+              dtm.clearCoRoutine();
+
+              throw re;
+            } catch (Exception e) {
+              dtm.clearCoRoutine();
+
+              throw new org.apache.xml.utils.WrappedRuntimeException(e);
+            }
+          }
+
+          if (DUMPTREE) {
+            System.out.println("Dumping SAX2DOM");
+            dtm.dumpDTM(System.err);
+          }
+
+          return dtm;
+        } finally {
+          // Reset the ContentHandler, DTDHandler, ErrorHandler to the DefaultHandler
+          // after creating the DTM.
+          if (reader != null && !(m_incremental && incremental)) {
+            reader.setContentHandler(m_defaultHandler);
+            reader.setDTDHandler(m_defaultHandler);
+            reader.setErrorHandler(m_defaultHandler);
+            
+            // Reset the LexicalHandler to null after creating the DTM.
+            try {
+              reader.setProperty("http://xml.org/sax/properties/lexical-handler", null);
+            }
+            catch (Exception e) {}
+          }
+          releaseXMLReader(reader);
+        }
+      } else {
+
+        // It should have been handled by a derived class or the caller
+        // made a mistake.
+        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NOT_SUPPORTED, new Object[]{source})); //"Not supported: " + source);
+      }
+    }
+  }
+
+  /**
+   * Given a W3C DOM node, try and return a DTM handle.
+   * Note: calling this may be non-optimal, and there is no guarantee that
+   * the node will be found in any particular DTM.
+   *
+   * @param node Non-null reference to a DOM node.
+   *
+   * @return a valid DTM handle.
+   */
+  synchronized public int getDTMHandleFromNode(org.w3c.dom.Node node)
+  {
+    if(null == node)
+      throw new IllegalArgumentException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NODE_NON_NULL, null)); //"node must be non-null for getDTMHandleFromNode!");
+
+    if (node instanceof org.apache.xml.dtm.ref.DTMNodeProxy)
+      return ((org.apache.xml.dtm.ref.DTMNodeProxy) node).getDTMNodeNumber();
+		
+    else
+    {
+      // Find the DOM2DTMs wrapped around this Document (if any)
+      // and check whether they contain the Node in question.
+      //
+      // NOTE that since a DOM2DTM may represent a subtree rather
+      // than a full document, we have to be prepared to check more
+      // than one -- and there is no guarantee that we will find
+      // one that contains ancestors or siblings of the node we're
+      // seeking.
+      //
+      // %REVIEW% We could search for the one which contains this
+      // node at the deepest level, and thus covers the widest
+      // subtree, but that's going to entail additional work
+      // checking more DTMs... and getHandleOfNode is not a
+      // cheap operation in most implementations.
+			//
+			// TODO: %REVIEW% If overflow addressing, we may recheck a DTM
+			// already examined. Ouch. But with the increased number of DTMs,
+			// scanning back to check this is painful. 
+			// POSSIBLE SOLUTIONS: 
+			//   Generate a list of _unique_ DTM objects?
+			//   Have each DTM cache last DOM node search?
+			int max = m_dtms.length;
+      for(int i = 0; i < max; i++)
+        {
+          DTM thisDTM=m_dtms[i];
+          if((null != thisDTM) && thisDTM instanceof DOM2DTM)
+          {
+            int handle=((DOM2DTM)thisDTM).getHandleOfNode(node);
+            if(handle!=DTM.NULL) return handle;
+          }
+         }
+
+			// Not found; generate a new DTM.
+			//
+			// %REVIEW% Is this really desirable, or should we return null
+			// and make folks explicitly instantiate from a DOMSource? The
+			// latter is more work but gives the caller the opportunity to
+			// explicitly add the DTM to a DTMManager... and thus to know when
+			// it can be discarded again, which is something we need to pay much
+			// more attention to. (Especially since only DTMs which are assigned
+			// to a manager can use the overflow addressing scheme.)
+			//
+			// %BUG% If the source node was a DOM2DTM$defaultNamespaceDeclarationNode
+			// and the DTM wasn't registered with this DTMManager, we will create
+			// a new DTM and _still_ not be able to find the node (since it will
+			// be resynthesized). Another reason to push hard on making all DTMs
+			// be managed DTMs.
+
+			// Since the real root of our tree may be a DocumentFragment, we need to
+      // use getParent to find the root, instead of getOwnerDocument.  Otherwise
+      // DOM2DTM#getHandleOfNode will be very unhappy.
+      Node root = node;
+      Node p = (root.getNodeType() == Node.ATTRIBUTE_NODE) ? ((org.w3c.dom.Attr)root).getOwnerElement() : root.getParentNode();
+      for (; p != null; p = p.getParentNode())
+      {
+        root = p;
+      }
+
+      DOM2DTM dtm = (DOM2DTM) getDTM(new javax.xml.transform.dom.DOMSource(root),
+																		 false, null, true, true);
+
+      int handle;
+      
+      if(node instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode)
+      {
+				// Can't return the same node since it's unique to a specific DTM, 
+				// but can return the equivalent node -- find the corresponding 
+				// Document Element, then ask it for the xml: namespace decl.
+				handle=dtm.getHandleOfNode(((org.w3c.dom.Attr)node).getOwnerElement());
+				handle=dtm.getAttributeNode(handle,node.getNamespaceURI(),node.getLocalName());
+      }
+      else
+				handle = ((DOM2DTM)dtm).getHandleOfNode(node);
+
+      if(DTM.NULL == handle)
+        throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COULD_NOT_RESOLVE_NODE, null)); //"Could not resolve the node to a handle!");
+
+      return handle;
+    }
+  }
+
+  /**
+   * This method returns the SAX2 parser to use with the InputSource
+   * obtained from this URI.
+   * It may return null if any SAX2-conformant XML parser can be used,
+   * or if getInputSource() will also return null. The parser must
+   * be free for use (i.e., not currently in use for another parse().
+   * After use of the parser is completed, the releaseXMLReader(XMLReader)
+   * must be called.
+   *
+   * @param inputSource The value returned from the URIResolver.
+   * @return  a SAX2 XMLReader to use to resolve the inputSource argument.
+   *
+   * @return non-null XMLReader reference ready to parse.
+   */
+  synchronized public XMLReader getXMLReader(Source inputSource)
+  {
+
+    try
+    {
+      XMLReader reader = (inputSource instanceof SAXSource)
+                         ? ((SAXSource) inputSource).getXMLReader() : null;
+
+      // If user did not supply a reader, ask for one from the reader manager
+      if (null == reader) {
+        if (m_readerManager == null) {
+            m_readerManager = XMLReaderManager.getInstance();
+        }
+
+        reader = m_readerManager.getXMLReader();
+      }
+
+      return reader;
+
+    } catch (SAXException se) {
+      throw new DTMException(se.getMessage(), se);
+    }
+  }
+
+  /**
+   * Indicates that the XMLReader object is no longer in use for the transform.
+   *
+   * Note that the getXMLReader method may return an XMLReader that was
+   * specified on the SAXSource object by the application code.  Such a
+   * reader should still be passed to releaseXMLReader, but the reader manager
+   * will only re-use XMLReaders that it created.
+   *
+   * @param reader The XMLReader to be released.
+   */
+  synchronized public void releaseXMLReader(XMLReader reader) {
+    if (m_readerManager != null) {
+      m_readerManager.releaseXMLReader(reader);
+    }
+  }
+
+  /**
+   * Return the DTM object containing a representation of this node.
+   *
+   * @param nodeHandle DTM Handle indicating which node to retrieve
+   *
+   * @return a reference to the DTM object containing this node.
+   */
+  synchronized public DTM getDTM(int nodeHandle)
+  {
+    try
+    {
+      // Performance critical function.
+      return m_dtms[nodeHandle >>> IDENT_DTM_NODE_BITS];
+    }
+    catch(java.lang.ArrayIndexOutOfBoundsException e)
+    {
+      if(nodeHandle==DTM.NULL)
+				return null;		// Accept as a special case.
+      else
+				throw e;		// Programming error; want to know about it.
+    }    
+  }
+
+  /**
+   * Given a DTM, find the ID number in the DTM tables which addresses
+   * the start of the document. If overflow addressing is in use, other
+   * DTM IDs may also be assigned to this DTM.
+   *
+   * @param dtm The DTM which (hopefully) contains this node.
+   *
+   * @return The DTM ID (as the high bits of a NodeHandle, not as our
+   * internal index), or -1 if the DTM doesn't belong to this manager.
+   */
+  synchronized public int getDTMIdentity(DTM dtm)
+  {
+	// Shortcut using DTMDefaultBase's extension hooks
+	// %REVIEW% Should the lookup be part of the basic DTM API?
+	if(dtm instanceof DTMDefaultBase)
+	{
+		DTMDefaultBase dtmdb=(DTMDefaultBase)dtm;
+		if(dtmdb.getManager()==this)
+			return dtmdb.getDTMIDs().elementAt(0);
+		else
+			return -1;
+	}
+				
+    int n = m_dtms.length;
+
+    for (int i = 0; i < n; i++)
+    {
+      DTM tdtm = m_dtms[i];
+
+      if (tdtm == dtm && m_dtm_offsets[i]==0)
+        return i << IDENT_DTM_NODE_BITS;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Release the DTMManager's reference(s) to a DTM, making it unmanaged.
+   * This is typically done as part of returning the DTM to the heap after
+   * we're done with it.
+   *
+   * @param dtm the DTM to be released.
+   * 
+   * @param shouldHardDelete If false, this call is a suggestion rather than an
+   * order, and we may not actually release the DTM. This is intended to 
+   * support intelligent caching of documents... which is not implemented
+   * in this version of the DTM manager.
+   *
+   * @return true if the DTM was released, false if shouldHardDelete was set
+   * and we decided not to.
+   */
+  synchronized public boolean release(DTM dtm, boolean shouldHardDelete)
+  {
+    if(DEBUG)
+    {
+      System.out.println("Releasing "+
+			 (shouldHardDelete ? "HARD" : "soft")+
+			 " dtm="+
+			 // Following shouldn't need a nodeHandle, but does...
+			 // and doesn't seem to report the intended value
+			 dtm.getDocumentBaseURI()
+			 );
+    }
+
+    if (dtm instanceof SAX2DTM)
+    {
+      ((SAX2DTM) dtm).clearCoRoutine();
+    }
+
+		// Multiple DTM IDs may be assigned to a single DTM. 
+		// The Right Answer is to ask which (if it supports
+		// extension, the DTM will need a list anyway). The 
+		// Wrong Answer, applied if the DTM can't help us,
+		// is to linearly search them all; this may be very
+		// painful.
+		//
+		// %REVIEW% Should the lookup move up into the basic DTM API?
+		if(dtm instanceof DTMDefaultBase)
+		{
+			org.apache.xml.utils.SuballocatedIntVector ids=((DTMDefaultBase)dtm).getDTMIDs();
+			for(int i=ids.size()-1;i>=0;--i)
+				m_dtms[ids.elementAt(i)>>>DTMManager.IDENT_DTM_NODE_BITS]=null;
+		}
+		else
+		{
+			int i = getDTMIdentity(dtm);
+		    if (i >= 0)
+			{
+				m_dtms[i >>> DTMManager.IDENT_DTM_NODE_BITS] = null;
+			}
+		}
+
+    dtm.documentRelease();
+    return true;
+  }
+
+  /**
+   * Method createDocumentFragment
+   *
+   *
+   * NEEDSDOC (createDocumentFragment) @return
+   */
+  synchronized public DTM createDocumentFragment()
+  {
+
+    try
+    {
+      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+      dbf.setNamespaceAware(true);
+
+      DocumentBuilder db = dbf.newDocumentBuilder();
+      Document doc = db.newDocument();
+      Node df = doc.createDocumentFragment();
+
+      return getDTM(new DOMSource(df), true, null, false, false);
+    }
+    catch (Exception e)
+    {
+      throw new DTMException(e);
+    }
+  }
+
+  /**
+   * NEEDSDOC Method createDTMIterator
+   *
+   *
+   * NEEDSDOC @param whatToShow
+   * NEEDSDOC @param filter
+   * NEEDSDOC @param entityReferenceExpansion
+   *
+   * NEEDSDOC (createDTMIterator) @return
+   */
+  synchronized public DTMIterator createDTMIterator(int whatToShow, DTMFilter filter,
+                                       boolean entityReferenceExpansion)
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
+    return null;
+  }
+
+  /**
+   * NEEDSDOC Method createDTMIterator
+   *
+   *
+   * NEEDSDOC @param xpathString
+   * NEEDSDOC @param presolver
+   *
+   * NEEDSDOC (createDTMIterator) @return
+   */
+  synchronized public DTMIterator createDTMIterator(String xpathString,
+                                       PrefixResolver presolver)
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
+    return null;
+  }
+
+  /**
+   * NEEDSDOC Method createDTMIterator
+   *
+   *
+   * NEEDSDOC @param node
+   *
+   * NEEDSDOC (createDTMIterator) @return
+   */
+  synchronized public DTMIterator createDTMIterator(int node)
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
+    return null;
+  }
+
+  /**
+   * NEEDSDOC Method createDTMIterator
+   *
+   *
+   * NEEDSDOC @param xpathCompiler
+   * NEEDSDOC @param pos
+   *
+   * NEEDSDOC (createDTMIterator) @return
+   */
+  synchronized public DTMIterator createDTMIterator(Object xpathCompiler, int pos)
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
+    return null;
+  }
+
+  /**
+   * return the expanded name table.
+   *
+   * NEEDSDOC @param dtm
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public ExpandedNameTable getExpandedNameTable(DTM dtm)
+  {
+    return m_expandedNameTable;
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMNamedNodeMap.java b/src/main/java/org/apache/xml/dtm/ref/DTMNamedNodeMap.java
new file mode 100644
index 0000000..4bb1322
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMNamedNodeMap.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMNamedNodeMap.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * DTMNamedNodeMap is a quickie (as opposed to quick) implementation of the DOM's
+ * NamedNodeMap interface, intended to support DTMProxy's getAttributes()
+ * call.
+ * <p>
+ * ***** Note: this does _not_ current attempt to cache any of the data;
+ * if you ask for attribute 27 and then 28, you'll have to rescan the first
+ * 27. It should probably at least keep track of the last one retrieved,
+ * and possibly buffer the whole array.
+ * <p>
+ * ***** Also note that there's no fastpath for the by-name query; we search
+ * linearly until we find it or fail to find it. Again, that could be
+ * optimized at some cost in object creation/storage.
+ * @xsl.usage internal
+ */
+public class DTMNamedNodeMap implements NamedNodeMap
+{
+
+  /** The DTM for this node. */
+  DTM dtm;
+
+  /** The DTM element handle. */
+  int element;
+
+  /** The number of nodes in this map. */
+  short m_count = -1;
+
+  /**
+   * Create a getAttributes NamedNodeMap for a given DTM element node
+   *
+   * @param dtm The DTM Reference, must be non-null.
+   * @param element The DTM element handle.
+   */
+  public DTMNamedNodeMap(DTM dtm, int element)
+  {
+    this.dtm = dtm;
+    this.element = element;
+  }
+
+  /**
+   * Return the number of Attributes on this Element
+   *
+   * @return The number of nodes in this map.
+   */
+  public int getLength()
+  {
+
+    if (m_count == -1)
+    {
+      short count = 0;
+
+      for (int n = dtm.getFirstAttribute(element); n != -1;
+              n = dtm.getNextAttribute(n))
+      {
+        ++count;
+      }
+
+      m_count = count;
+    }
+
+    return (int) m_count;
+  }
+
+  /**
+   * Retrieves a node specified by name.
+   * @param name The <code>nodeName</code> of a node to retrieve.
+   * @return A <code>Node</code> (of any type) with the specified
+   *   <code>nodeName</code>, or <code>null</code> if it does not identify
+   *   any node in this map.
+   */
+  public Node getNamedItem(String name)
+  {
+
+    for (int n = dtm.getFirstAttribute(element); n != DTM.NULL;
+            n = dtm.getNextAttribute(n))
+    {
+      if (dtm.getNodeName(n).equals(name))
+        return dtm.getNode(n);
+    }
+
+    return null;
+  }
+
+  /**
+   * Returns the <code>index</code>th item in the map. If <code>index</code>
+   * is greater than or equal to the number of nodes in this map, this
+   * returns <code>null</code>.
+   * @param i The index of the requested item.
+   * @return The node at the <code>index</code>th position in the map, or
+   *   <code>null</code> if that is not a valid index.
+   */
+  public Node item(int i)
+  {
+
+    int count = 0;
+
+    for (int n = dtm.getFirstAttribute(element); n != -1;
+            n = dtm.getNextAttribute(n))
+    {
+      if (count == i)
+        return dtm.getNode(n);
+      else
+        ++count;
+    }
+
+    return null;
+  }
+
+  /**
+   * Adds a node using its <code>nodeName</code> attribute. If a node with
+   * that name is already present in this map, it is replaced by the new
+   * one.
+   * <br>As the <code>nodeName</code> attribute is used to derive the name
+   * which the node must be stored under, multiple nodes of certain types
+   * (those that have a "special" string value) cannot be stored as the
+   * names would clash. This is seen as preferable to allowing nodes to be
+   * aliased.
+   * @param newNode node to store in this map. The node will later be
+   *   accessible using the value of its <code>nodeName</code> attribute.
+   *
+   * @return If the new <code>Node</code> replaces an existing node the
+   *   replaced <code>Node</code> is returned, otherwise <code>null</code>
+   *   is returned.
+   * @exception DOMException
+   *   WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a
+   *   different document than the one that created this map.
+   *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+   *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an
+   *   <code>Attr</code> that is already an attribute of another
+   *   <code>Element</code> object. The DOM user must explicitly clone
+   *   <code>Attr</code> nodes to re-use them in other elements.
+   */
+  public Node setNamedItem(Node newNode)
+  {
+    throw new DTMException(DTMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   * Removes a node specified by name. When this map contains the attributes
+   * attached to an element, if the removed attribute is known to have a
+   * default value, an attribute immediately appears containing the
+   * default value as well as the corresponding namespace URI, local name,
+   * and prefix when applicable.
+   * @param name The <code>nodeName</code> of the node to remove.
+   *
+   * @return The node removed from this map if a node with such a name
+   *   exists.
+   * @exception DOMException
+   *   NOT_FOUND_ERR: Raised if there is no node named <code>name</code> in
+   *   this map.
+   *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+   */
+  public Node removeNamedItem(String name)
+  {
+    throw new DTMException(DTMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   * Retrieves a node specified by local name and namespace URI. HTML-only
+   * DOM implementations do not need to implement this method.
+   * @param namespaceURI The namespace URI of the node to retrieve.
+   * @param localName The local name of the node to retrieve.
+   *
+   * @return A <code>Node</code> (of any type) with the specified local
+   *   name and namespace URI, or <code>null</code> if they do not
+   *   identify any node in this map.
+   * @since DOM Level 2
+   */
+  public Node getNamedItemNS(String namespaceURI, String localName)
+  {
+       Node retNode = null;
+       for (int n = dtm.getFirstAttribute(element); n != DTM.NULL;
+                       n = dtm.getNextAttribute(n))
+       {
+         if (localName.equals(dtm.getLocalName(n)))
+         {
+           String nsURI = dtm.getNamespaceURI(n); 
+           if ((namespaceURI == null && nsURI == null)
+                  || (namespaceURI != null && namespaceURI.equals(nsURI)))
+           {
+             retNode = dtm.getNode(n);
+             break;
+           }
+         }
+       }
+       return retNode;
+  }
+
+  /**
+   * Adds a node using its <code>namespaceURI</code> and
+   * <code>localName</code>. If a node with that namespace URI and that
+   * local name is already present in this map, it is replaced by the new
+   * one.
+   * <br>HTML-only DOM implementations do not need to implement this method.
+   * @param arg A node to store in this map. The node will later be
+   *   accessible using the value of its <code>namespaceURI</code> and
+   *   <code>localName</code> attributes.
+   *
+   * @return If the new <code>Node</code> replaces an existing node the
+   *   replaced <code>Node</code> is returned, otherwise <code>null</code>
+   *   is returned.
+   * @exception DOMException
+   *   WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a
+   *   different document than the one that created this map.
+   *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+   *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an
+   *   <code>Attr</code> that is already an attribute of another
+   *   <code>Element</code> object. The DOM user must explicitly clone
+   *   <code>Attr</code> nodes to re-use them in other elements.
+   * @since DOM Level 2
+   */
+  public Node setNamedItemNS(Node arg) throws DOMException
+  {
+    throw new DTMException(DTMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   * Removes a node specified by local name and namespace URI. A removed
+   * attribute may be known to have a default value when this map contains
+   * the attributes attached to an element, as returned by the attributes
+   * attribute of the <code>Node</code> interface. If so, an attribute
+   * immediately appears containing the default value as well as the
+   * corresponding namespace URI, local name, and prefix when applicable.
+   * <br>HTML-only DOM implementations do not need to implement this method.
+   * 
+   * @param namespaceURI The namespace URI of the node to remove.
+   * @param localName The local name of the node to remove.
+   *
+   * @return The node removed from this map if a node with such a local
+   *   name and namespace URI exists.
+   * @exception DOMException
+   *   NOT_FOUND_ERR: Raised if there is no node with the specified
+   *   <code>namespaceURI</code> and <code>localName</code> in this map.
+   *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+   * @since DOM Level 2
+   */
+  public Node removeNamedItemNS(String namespaceURI, String localName)
+          throws DOMException
+  {
+    throw new DTMException(DTMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   * Simple implementation of DOMException.
+   * @xsl.usage internal
+   */
+  public class DTMException extends org.w3c.dom.DOMException
+  {
+          static final long serialVersionUID = -8290238117162437678L;
+    /**
+     * Constructs a DOM/DTM exception.
+     *
+     * @param code
+     * @param message
+     */
+    public DTMException(short code, String message)
+    {
+      super(code, message);
+    }
+
+    /**
+     * Constructor DTMException
+     *
+     *
+     * @param code
+     */
+    public DTMException(short code)
+    {
+      super(code, "");
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMNodeIterator.java b/src/main/java/org/apache/xml/dtm/ref/DTMNodeIterator.java
new file mode 100644
index 0000000..a482757
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMNodeIterator.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMNodeIterator.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMDOMException;
+import org.apache.xml.dtm.DTMIterator;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeFilter;
+
+/**
+ * <code>DTMNodeIterator</code> gives us an implementation of the 
+ * DTMNodeIterator which returns DOM nodes.
+ *
+ * Please note that this is not necessarily equivlaent to a DOM
+ * NodeIterator operating over the same document. In particular:
+ * <ul>
+ *
+ * <li>If there are several Text nodes in logical succession (ie,
+ * across CDATASection and EntityReference boundaries), we will return
+ * only the first; the caller is responsible for stepping through
+ * them.
+ * (%REVIEW% Provide a convenience routine here to assist, pending
+ * proposed DOM Level 3 getAdjacentText() operation?) </li>
+ *
+ * <li>Since the whole XPath/XSLT architecture assumes that the source
+ * document is not altered while we're working with it, we do not
+ * promise to implement the DOM NodeIterator's "maintain current
+ * position" response to document mutation. </li>
+ *
+ * <li>Since our design for XPath NodeIterators builds a stateful
+ * filter directly into the traversal object, getNodeFilter() is not
+ * supported.</li>
+ *
+ * </ul>
+ *
+ * <p>State: In progress!!</p>
+ * */
+public class DTMNodeIterator implements org.w3c.dom.traversal.NodeIterator
+{
+  private DTMIterator dtm_iter;
+  private boolean valid=true;
+
+  //================================================================
+  // Methods unique to this class
+
+  /** Public constructor: Wrap a DTMNodeIterator around an existing
+   * and preconfigured DTMIterator
+   * */
+  public DTMNodeIterator(DTMIterator dtmIterator)
+    {
+      try
+      {
+        dtm_iter=(DTMIterator)dtmIterator.clone();
+      }
+      catch(CloneNotSupportedException cnse)
+      {
+        throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
+      }
+    }
+
+  /** Access the wrapped DTMIterator. I'm not sure whether anyone will
+   * need this or not, but let's write it and think about it.
+   * */
+  public DTMIterator getDTMIterator()
+    {
+      return dtm_iter;
+    }
+  
+
+  //================================================================
+  // org.w3c.dom.traversal.NodeFilter API follows
+
+  /** Detaches the NodeIterator from the set which it iterated over,
+   * releasing any computational resources and placing the iterator in
+   * the INVALID state.
+   * */
+  public void detach() 
+    {
+      // Theoretically, we could release dtm_iter at this point. But
+      // some of the operations may still want to consult it even though
+      // navigation is now invalid.
+      valid=false;
+    }
+
+  /** The value of this flag determines whether the children
+   * of entity reference nodes are visible to the iterator.
+   *
+   * @return false, always (the DTM model flattens entity references)
+   * */
+  public boolean getExpandEntityReferences()
+    {
+      return false;
+    }
+  
+  /** Return a handle to the filter used to screen nodes.
+   *
+   * This is ill-defined in Xalan's usage of Nodeiterator, where we have
+   * built stateful XPath-based filtering directly into the traversal
+   * object. We could return something which supports the NodeFilter interface
+   * and allows querying whether a given node would be permitted if it appeared
+   * as our next node, but in the current implementation that would be very
+   * complex -- and just isn't all that useful.
+   * 
+   * @throws DOMException -- NOT_SUPPORTED_ERROR because I can't think
+   * of anything more useful to do in this case
+   * */
+  public NodeFilter getFilter() 
+    {
+      throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+    }
+  
+
+  /** @return The root node of the NodeIterator, as specified
+   * when it was created.
+   * */
+  public Node getRoot()
+    {
+      int handle=dtm_iter.getRoot();
+      return dtm_iter.getDTM(handle).getNode(handle);
+    }
+  
+
+  /** Return a mask describing which node types are presented via the
+   * iterator.
+   **/
+  public int getWhatToShow()
+    {
+      return dtm_iter.getWhatToShow();
+    }
+
+  /** @return the next node in the set and advance the position of the
+   * iterator in the set.
+   *
+   * @throws DOMException - INVALID_STATE_ERR Raised if this method is
+   * called after the detach method was invoked.
+   *  */
+  public Node nextNode() throws DOMException
+    {
+      if(!valid)
+        throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
+      
+      int handle=dtm_iter.nextNode();
+      if (handle==DTM.NULL)
+        return null;
+      return dtm_iter.getDTM(handle).getNode(handle);
+    }
+  
+
+  /** @return the next previous in the set and advance the position of the
+   * iterator in the set.
+   *
+   * @throws DOMException - INVALID_STATE_ERR Raised if this method is
+   * called after the detach method was invoked.
+   *  */
+  public Node previousNode() 
+    {
+      if(!valid)
+        throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
+      
+      int handle=dtm_iter.previousNode();
+      if (handle==DTM.NULL)
+        return null;      
+      return dtm_iter.getDTM(handle).getNode(handle);
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMNodeList.java b/src/main/java/org/apache/xml/dtm/ref/DTMNodeList.java
new file mode 100644
index 0000000..f265080
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMNodeList.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMNodeList.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.w3c.dom.Node;
+
+/**
+ * <code>DTMNodeList</code> gives us an implementation of the DOM's
+ * NodeList interface wrapped around a DTM Iterator. The author
+ * considers this something of an abominations, since NodeList was not
+ * intended to be a general purpose "list of nodes" API and is
+ * generally considered by the DOM WG to have be a mistake... but I'm
+ * told that some of the XPath/XSLT folks say they must have this
+ * solution.
+ *
+ * Please note that this is not necessarily equivlaent to a DOM
+ * NodeList operating over the same document. In particular:
+ * <ul>
+ *
+ * <li>If there are several Text nodes in logical succession (ie,
+ * across CDATASection and EntityReference boundaries), we will return
+ * only the first; the caller is responsible for stepping through
+ * them.
+ * (%REVIEW% Provide a convenience routine here to assist, pending
+ * proposed DOM Level 3 getAdjacentText() operation?) </li>
+ *
+ * <li>Since the whole XPath/XSLT architecture assumes that the source
+ * document is not altered while we're working with it, we do not
+ * promise to implement the DOM NodeList's "live view" response to
+ * document mutation. </li>
+ *
+ * </ul>
+ *
+ * <p>State: In progress!!</p>
+ * */
+public class DTMNodeList extends DTMNodeListBase {
+    private DTMIterator m_iter;
+
+    //================================================================
+    // Methods unique to this class
+    private DTMNodeList() {
+    }
+
+    /**
+     * Public constructor: Wrap a DTMNodeList around an existing
+     * and preconfigured DTMIterator
+     *
+     * WARNING: THIS HAS THE SIDE EFFECT OF ISSUING setShouldCacheNodes(true)
+     * AGAINST THE DTMIterator.
+     *
+     */
+    public DTMNodeList(DTMIterator dtmIterator) {
+        if (dtmIterator != null) {
+            int pos = dtmIterator.getCurrentPos();
+            try {
+                m_iter=(DTMIterator)dtmIterator.cloneWithReset();
+            } catch(CloneNotSupportedException cnse) {
+                m_iter = dtmIterator;
+            }
+            m_iter.setShouldCacheNodes(true);
+            m_iter.runTo(-1);
+            m_iter.setCurrentPos(pos);
+        }
+    }
+
+    /**
+     * Access the wrapped DTMIterator. I'm not sure whether anyone will
+     * need this or not, but let's write it and think about it.
+     *
+     */
+    public DTMIterator getDTMIterator() {
+        return m_iter;
+    }
+
+    //================================================================
+    // org.w3c.dom.NodeList API follows
+
+    /**
+     * Returns the <code>index</code>th item in the collection. If 
+     * <code>index</code> is greater than or equal to the number of nodes in 
+     * the list, this returns <code>null</code>.
+     * @param index Index into the collection.
+     * @return The node at the <code>index</code>th position in the 
+     *   <code>NodeList</code>, or <code>null</code> if that is not a valid 
+     *   index.
+     */
+    public Node item(int index)
+    {
+        if (m_iter != null) {
+            int handle=m_iter.item(index);
+            if (handle == DTM.NULL) {
+                return null;
+            }
+            return m_iter.getDTM(handle).getNode(handle);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * The number of nodes in the list. The range of valid child node indices 
+     * is 0 to <code>length-1</code> inclusive. 
+     */
+    public int getLength() {
+        return (m_iter != null) ? m_iter.getLength() : 0;
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMNodeListBase.java b/src/main/java/org/apache/xml/dtm/ref/DTMNodeListBase.java
new file mode 100644
index 0000000..60bac3d
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMNodeListBase.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMNodeListBase.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+import org.w3c.dom.Node;
+
+/**
+ * <code>DTMNodeList</code> gives us an implementation of the DOM's
+ * NodeList interface wrapped around a DTM Iterator. The author
+ * considers this something of an abominations, since NodeList was not
+ * intended to be a general purpose "list of nodes" API and is
+ * generally considered by the DOM WG to have be a mistake... but I'm
+ * told that some of the XPath/XSLT folks say they must have this
+ * solution.
+ *
+ * Please note that this is not necessarily equivlaent to a DOM
+ * NodeList operating over the same document. In particular:
+ * <ul>
+ *
+ * <li>If there are several Text nodes in logical succession (ie,
+ * across CDATASection and EntityReference boundaries), we will return
+ * only the first; the caller is responsible for stepping through
+ * them.
+ * (%REVIEW% Provide a convenience routine here to assist, pending
+ * proposed DOM Level 3 getAdjacentText() operation?) </li>
+ *
+ * <li>Since the whole XPath/XSLT architecture assumes that the source
+ * document is not altered while we're working with it, we do not
+ * promise to implement the DOM NodeList's "live view" response to
+ * document mutation. </li>
+ *
+ * </ul>
+ *
+ * <p>State: In progress!!</p>
+ *
+ */
+public class DTMNodeListBase implements org.w3c.dom.NodeList {
+    public DTMNodeListBase() {
+    }
+
+    //================================================================
+    // org.w3c.dom.NodeList API follows
+
+    /**
+     * Returns the <code>index</code>th item in the collection. If 
+     * <code>index</code> is greater than or equal to the number of nodes in 
+     * the list, this returns <code>null</code>.
+     * @param index Index into the collection.
+     * @return The node at the <code>index</code>th position in the 
+     *   <code>NodeList</code>, or <code>null</code> if that is not a valid 
+     *   index.
+     */
+    public Node item(int index) {
+        return null;
+    }
+
+    /**
+     * The number of nodes in the list. The range of valid child node indices 
+     * is 0 to <code>length-1</code> inclusive. 
+     */
+    public int getLength() {
+        return 0;
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMNodeProxy.java b/src/main/java/org/apache/xml/dtm/ref/DTMNodeProxy.java
new file mode 100644
index 0000000..ebd578c
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMNodeProxy.java
@@ -0,0 +1,2218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMNodeProxy.java 889881 2009-12-12 03:47:15Z zongaro $
+ */
+package org.apache.xml.dtm.ref;
+
+import java.util.Vector;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMDOMException;
+import org.apache.xpath.NodeSet;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+import org.w3c.dom.UserDataHandler;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.TypeInfo;
+
+/**
+ * <code>DTMNodeProxy</code> presents a DOM Node API front-end to the DTM model.
+ * <p>
+ * It does _not_ attempt to address the "node identity" question; no effort
+ * is made to prevent the creation of multiple proxies referring to a single
+ * DTM node. Users can create a mechanism for managing this, or relinquish the
+ * use of "==" and use the .sameNodeAs() mechanism, which is under
+ * consideration for future versions of the DOM.
+ * <p>
+ * DTMNodeProxy may be subclassed further to present specific DOM node types.
+ *
+ * @see org.w3c.dom
+ * @xsl.usage internal
+ */
+public class DTMNodeProxy
+  implements Node, Document, Text, Element, Attr,
+                   ProcessingInstruction, Comment, DocumentFragment
+{
+
+  /** The DTM for this node. */
+  public DTM dtm;
+
+  /** The DTM node handle. */
+  int node;
+  
+  /** The return value as Empty String. */
+  private static final String EMPTYSTRING = "";
+          
+  /** The DOMImplementation object */
+  static final DOMImplementation implementation=new DTMNodeProxyImplementation();
+
+  /**
+   * Create a DTMNodeProxy Node representing a specific Node in a DTM
+   *
+   * @param dtm The DTM Reference, must be non-null.
+   * @param node The DTM node handle.
+   */
+  public DTMNodeProxy(DTM dtm, int node)
+  {
+    this.dtm = dtm;
+    this.node = node;
+  }
+
+  /**
+   * NON-DOM: Return the DTM model
+   *
+   * @return The DTM that this proxy is a representative for.
+   */
+  public final DTM getDTM()
+  {
+    return dtm;
+  }
+
+  /**
+   * NON-DOM: Return the DTM node number
+   *
+   * @return The DTM node handle.
+   */
+  public final int getDTMNodeNumber()
+  {
+    return node;
+  }
+
+  /**
+   * Test for equality based on node number.
+   *
+   * @param node A DTM node proxy reference.
+   *
+   * @return true if the given node has the same handle as this node.
+   */
+  public final boolean equals(Node node)
+  {
+
+    try
+    {
+      DTMNodeProxy dtmp = (DTMNodeProxy) node;
+
+      // return (dtmp.node == this.node);
+      // Patch attributed to Gary L Peskin <garyp@firstech.com>
+      return (dtmp.node == this.node) && (dtmp.dtm == this.dtm);
+    }
+    catch (ClassCastException cce)
+    {
+      return false;
+    }
+  }
+
+  /**
+   * Test for equality based on node number.
+   *
+   * @param node A DTM node proxy reference.
+   *
+   * @return true if the given node has the same handle as this node.
+   */
+  public final boolean equals(Object node)
+  {
+
+    try
+    {
+
+      // DTMNodeProxy dtmp = (DTMNodeProxy)node;
+      // return (dtmp.node == this.node);
+      // Patch attributed to Gary L Peskin <garyp@firstech.com>
+      return equals((Node) node);
+    }
+    catch (ClassCastException cce)
+    {
+      return false;
+    }
+  }
+
+  /**
+   * FUTURE DOM: Test node identity, in lieu of Node==Node
+   *
+   * @param other
+   *
+   * @return true if the given node has the same handle as this node.
+   */
+  public final boolean sameNodeAs(Node other)
+  {
+
+    if (!(other instanceof DTMNodeProxy))
+      return false;
+
+    DTMNodeProxy that = (DTMNodeProxy) other;
+
+    return this.dtm == that.dtm && this.node == that.node;
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final String getNodeName()
+  {
+    return dtm.getNodeName(node);
+  }
+
+  /**
+   * A PI's "target" states what processor channel the PI's data
+   * should be directed to. It is defined differently in HTML and XML.
+   * <p>
+   * In XML, a PI's "target" is the first (whitespace-delimited) token
+   * following the "<?" token that begins the PI.
+   * <p>
+   * In HTML, target is always null.
+   * <p>
+   * Note that getNodeName is aliased to getTarget.
+   *
+   *
+   */
+  public final String getTarget()
+  {
+    return dtm.getNodeName(node);
+  }  // getTarget():String
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node as of DOM Level 2
+   */
+  public final String getLocalName()
+  {
+    return dtm.getLocalName(node);
+  }
+
+  /**
+   * @return The prefix for this node.
+   * @see org.w3c.dom.Node as of DOM Level 2
+   */
+  public final String getPrefix()
+  {
+    return dtm.getPrefix(node);
+  }
+
+  /**
+   *
+   * @param prefix
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only
+   */
+  public final void setPrefix(String prefix) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node as of DOM Level 2
+   */
+  public final String getNamespaceURI()
+  {
+    return dtm.getNamespaceURI(node);
+  }
+
+  /** Ask whether we support a given DOM feature.
+   * In fact, we do not _fully_ support any DOM feature -- we're a
+   * read-only subset -- so arguably we should always return false.
+   * Or we could say that we support DOM Core Level 2 but all nodes
+   * are read-only. Unclear which answer is least misleading.
+   * 
+   * NON-DOM method. This was present in early drafts of DOM Level 2,
+   * but was renamed isSupported. It's present here only because it's
+   * cheap, harmless, and might help some poor fool who is still trying
+   * to use an early Working Draft of the DOM.
+   *
+   * @param feature
+   * @param version
+   *
+   * @return false
+   */
+  public final boolean supports(String feature, String version)
+  {
+    return implementation.hasFeature(feature,version);
+    //throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /** Ask whether we support a given DOM feature.
+   * In fact, we do not _fully_ support any DOM feature -- we're a
+   * read-only subset -- so arguably we should always return false.
+   *
+   * @param feature
+   * @param version
+   *
+   * @return false
+   * @see org.w3c.dom.Node as of DOM Level 2
+   */
+  public final boolean isSupported(String feature, String version)
+  {
+    return implementation.hasFeature(feature,version);
+    // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node
+   */
+  public final String getNodeValue() throws DOMException
+  {
+    return dtm.getNodeValue(node);
+  }
+  
+  /**
+   * @return The string value of the node
+   * 
+   * @throws DOMException
+   */
+  public final String getStringValue() throws DOMException
+  {
+  	return dtm.getStringValue(node).toString();
+  }
+
+  /**
+   *
+   * @param nodeValue
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final void setNodeValue(String nodeValue) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final short getNodeType()
+  {
+    return (short) dtm.getNodeType(node);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getParentNode()
+  {
+
+    if (getNodeType() == Node.ATTRIBUTE_NODE)
+      return null;
+
+    int newnode = dtm.getParent(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getOwnerNode()
+  {
+
+    int newnode = dtm.getParent(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final NodeList getChildNodes()
+  {
+                
+    // Annoyingly, AxisIterators do not currently implement DTMIterator, so
+    // we can't just wap DTMNodeList around an Axis.CHILD iterator.
+    // Instead, we've created a special-case operating mode for that object.
+    return new DTMChildIterNodeList(dtm,node);
+
+    // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getFirstChild()
+  {
+
+    int newnode = dtm.getFirstChild(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getLastChild()
+  {
+
+    int newnode = dtm.getLastChild(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getPreviousSibling()
+  {
+
+    int newnode = dtm.getPreviousSibling(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Node getNextSibling()
+  {
+
+    // Attr's Next is defined at DTM level, but not at DOM level.
+    if (dtm.getNodeType(node) == Node.ATTRIBUTE_NODE)
+      return null;
+
+    int newnode = dtm.getNextSibling(node);
+
+    return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
+  }
+
+  // DTMNamedNodeMap m_attrs;
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final NamedNodeMap getAttributes()
+  {
+
+    return new DTMNamedNodeMap(dtm, node);
+  }
+
+  /**
+   * Method hasAttribute
+   *
+   *
+   * @param name
+   *
+   *
+   */
+  public boolean hasAttribute(String name)
+  {
+    return DTM.NULL != dtm.getAttributeNode(node,null,name);
+  }
+
+  /**
+   * Method hasAttributeNS
+   *
+   *
+   * @param namespaceURI
+   * @param localName
+   *
+   *
+   */
+  public boolean hasAttributeNS(String namespaceURI, String localName)
+  {
+    return DTM.NULL != dtm.getAttributeNode(node,namespaceURI,localName);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final Document getOwnerDocument()
+  {
+  	// Note that this uses the DOM-compatable version of the call
+	return (Document)(dtm.getNode(dtm.getOwnerDocument(node)));
+  }
+
+  /**
+   *
+   * @param newChild
+   * @param refChild
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final Node insertBefore(Node newChild, Node refChild)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   * @param newChild
+   * @param oldChild
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final Node replaceChild(Node newChild, Node oldChild)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   * @param oldChild
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final Node removeChild(Node oldChild) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   * @param newChild
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final Node appendChild(Node newChild) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Node
+   */
+  public final boolean hasChildNodes()
+  {
+    return (DTM.NULL != dtm.getFirstChild(node));
+  }
+
+  /**
+   *
+   * @param deep
+   *
+   *
+   * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
+   */
+  public final Node cloneNode(boolean deep)
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final DocumentType getDoctype()
+  {
+    return null;
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final DOMImplementation getImplementation()
+  {
+    return implementation;
+  }
+
+  /** This is a bit of a problem in DTM, since a DTM may be a Document
+   * Fragment and hence not have a clear-cut Document Element. We can
+   * make it work in the well-formed cases but would that be confusing for others?
+   * 
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final Element getDocumentElement()
+  {
+		int dochandle=dtm.getDocument();
+		int elementhandle=DTM.NULL;
+		for(int kidhandle=dtm.getFirstChild(dochandle);
+				kidhandle!=DTM.NULL;
+				kidhandle=dtm.getNextSibling(kidhandle))
+		{
+			switch(dtm.getNodeType(kidhandle))
+			{
+			case Node.ELEMENT_NODE:
+				if(elementhandle!=DTM.NULL) 
+				{
+					elementhandle=DTM.NULL; // More than one; ill-formed.
+					kidhandle=dtm.getLastChild(dochandle); // End loop
+				}
+				else
+					elementhandle=kidhandle;
+				break;
+				
+			// These are harmless; document is still wellformed
+			case Node.COMMENT_NODE:
+			case Node.PROCESSING_INSTRUCTION_NODE:
+			case Node.DOCUMENT_TYPE_NODE:
+				break;
+					
+			default:
+				elementhandle=DTM.NULL; // ill-formed
+				kidhandle=dtm.getLastChild(dochandle); // End loop
+				break;
+			}
+		}
+		if(elementhandle==DTM.NULL)
+			throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+		else
+			return (Element)(dtm.getNode(elementhandle));
+  }
+
+  /**
+   *
+   * @param tagName
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document
+   */
+  public final Element createElement(String tagName) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final DocumentFragment createDocumentFragment()
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param data
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final Text createTextNode(String data)
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param data
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final Comment createComment(String data)
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param data
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document
+   */
+  public final CDATASection createCDATASection(String data)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param target
+   * @param data
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document
+   */
+  public final ProcessingInstruction createProcessingInstruction(
+                                                                 String target, String data) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param name
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document
+   */
+  public final Attr createAttribute(String name) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param name
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document
+   */
+  public final EntityReference createEntityReference(String name)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param tagname
+   *
+   *
+   * @see org.w3c.dom.Document
+   */
+  public final NodeList getElementsByTagName(String tagname) 
+  {
+       Vector listVector = new Vector();
+       Node retNode = dtm.getNode(node);
+       if (retNode != null) 
+       {
+         boolean isTagNameWildCard = "*".equals(tagname);
+         if (DTM.ELEMENT_NODE == retNode.getNodeType()) 
+         {
+           NodeList nodeList = retNode.getChildNodes();
+           for (int i = 0; i < nodeList.getLength(); i++) 
+           {
+             traverseChildren(listVector, nodeList.item(i), tagname,
+                              isTagNameWildCard);
+           }
+         } else if (DTM.DOCUMENT_NODE == retNode.getNodeType()) {
+           traverseChildren(listVector, dtm.getNode(node), tagname,
+                            isTagNameWildCard);
+         }
+       }
+       int size = listVector.size();
+       NodeSet nodeSet = new NodeSet(size);
+       for (int i = 0; i < size; i++) 
+       {
+         nodeSet.addNode((Node) listVector.elementAt(i));
+       }
+       return (NodeList) nodeSet;
+  }
+  /**
+   * 
+   * @param listVector
+   * @param tempNode
+   * @param tagname
+   * @param isTagNameWildCard
+   * 
+   * 
+   * Private method to be used for recursive iterations to obtain elements by tag name.
+   */
+  private final void traverseChildren
+  (
+    Vector listVector,
+    Node tempNode,
+    String tagname,
+    boolean isTagNameWildCard) {
+    if (tempNode == null) 
+    {
+      return;
+    } 
+    else
+    { 
+      if (tempNode.getNodeType() == DTM.ELEMENT_NODE
+            && (isTagNameWildCard || tempNode.getNodeName().equals(tagname)))
+      {
+        listVector.add(tempNode);
+      }
+      if(tempNode.hasChildNodes())
+      {
+        NodeList nodeList = tempNode.getChildNodes();
+        for (int i = 0; i < nodeList.getLength(); i++)
+        {
+          traverseChildren(listVector, nodeList.item(i), tagname,
+                           isTagNameWildCard);
+        }
+      }
+    }
+  }
+
+  /**
+   *
+   * @param importedNode
+   * @param deep
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
+   */
+  public final Node importNode(Node importedNode, boolean deep)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param qualifiedName
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document as of DOM Level 2
+   */
+  public final Element createElementNS(
+                                       String namespaceURI, String qualifiedName) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param qualifiedName
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Document as of DOM Level 2
+   */
+  public final Attr createAttributeNS(
+                                      String namespaceURI, String qualifiedName) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param localName
+   *
+   *
+   * @see org.w3c.dom.Document as of DOM Level 2
+   */
+  public final NodeList getElementsByTagNameNS(String namespaceURI,
+                                               String localName)
+  {
+    Vector listVector = new Vector();
+    Node retNode = dtm.getNode(node);
+    if (retNode != null)
+    {               
+      boolean isNamespaceURIWildCard = "*".equals(namespaceURI);
+      boolean isLocalNameWildCard    = "*".equals(localName);
+      if (DTM.ELEMENT_NODE == retNode.getNodeType())
+      {
+        NodeList nodeList = retNode.getChildNodes();                    
+        for(int i = 0; i < nodeList.getLength(); i++)
+        {
+          traverseChildren(listVector, nodeList.item(i), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
+        }
+      }
+      else if(DTM.DOCUMENT_NODE == retNode.getNodeType())
+      {
+        traverseChildren(listVector, dtm.getNode(node), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
+      }
+    }
+    int size = listVector.size();
+    NodeSet nodeSet = new NodeSet(size);
+    for (int i = 0; i < size; i++)
+    {
+      nodeSet.addNode((Node)listVector.elementAt(i));
+    }
+    return (NodeList) nodeSet;
+  }
+  /**
+   * 
+   * @param listVector
+   * @param tempNode
+   * @param namespaceURI
+   * @param localname
+   * @param isNamespaceURIWildCard
+   * @param isLocalNameWildCard
+   * 
+   * Private method to be used for recursive iterations to obtain elements by tag name 
+   * and namespaceURI.
+   */
+  private final void traverseChildren
+  (
+   Vector listVector, 
+   Node tempNode, 
+   String namespaceURI, 
+   String localname,
+   boolean isNamespaceURIWildCard,
+   boolean isLocalNameWildCard) 
+   {
+    if (tempNode == null)
+    {
+      return;
+    }
+    else 
+    {
+      if (tempNode.getNodeType() == DTM.ELEMENT_NODE
+              && (isLocalNameWildCard
+                      || tempNode.getLocalName().equals(localname)))
+      {         
+        String nsURI = tempNode.getNamespaceURI();
+        if ((namespaceURI == null && nsURI == null)
+               || isNamespaceURIWildCard
+               || (namespaceURI != null && namespaceURI.equals(nsURI)))
+        {     
+          listVector.add(tempNode); 
+        } 
+      }
+      if(tempNode.hasChildNodes())
+      {
+        NodeList nl = tempNode.getChildNodes();                 
+        for(int i = 0; i < nl.getLength(); i++)
+        {
+          traverseChildren(listVector, nl.item(i), namespaceURI, localname,
+                           isNamespaceURIWildCard, isLocalNameWildCard);
+        }
+      }
+    }
+  }
+  /**
+   *
+   * @param elementId
+   *
+   *
+   * @see org.w3c.dom.Document as of DOM Level 2
+   */
+  public final Element getElementById(String elementId)
+  {
+       return (Element) dtm.getNode(dtm.getElementById(elementId));
+  }
+
+  /**
+   *
+   * @param offset
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Text
+   */
+  public final Text splitText(int offset) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final String getData() throws DOMException
+  {
+    return dtm.getNodeValue(node);
+  }
+
+  /**
+   *
+   * @param data
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final void setData(String data) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.CharacterData
+   */
+  public final int getLength()
+  {
+    // %OPT% This should do something smarter?
+    return dtm.getNodeValue(node).length();
+  }
+
+  /**
+   *
+   * @param offset
+   * @param count
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final String substringData(int offset, int count) throws DOMException
+  {
+    return getData().substring(offset,offset+count);
+  }
+
+  /**
+   *
+   * @param arg
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final void appendData(String arg) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param offset
+   * @param arg
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final void insertData(int offset, String arg) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param offset
+   * @param count
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final void deleteData(int offset, int count) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param offset
+   * @param count
+   * @param arg
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.CharacterData
+   */
+  public final void replaceData(int offset, int count, String arg)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Element
+   */
+  public final String getTagName()
+  {
+    return dtm.getNodeName(node);
+  }
+
+  /**
+   *
+   * @param name
+   *
+   *
+   * @see org.w3c.dom.Element
+   */
+  public final String getAttribute(String name)
+  {
+
+    DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
+    Node node = map.getNamedItem(name);
+    return (null == node) ? EMPTYSTRING : node.getNodeValue();
+  }
+
+  /**
+   *
+   * @param name
+   * @param value
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final void setAttribute(String name, String value)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param name
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final void removeAttribute(String name) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param name
+   *
+   *
+   * @see org.w3c.dom.Element
+   */
+  public final Attr getAttributeNode(String name)
+  {
+
+    DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
+    return (Attr)map.getNamedItem(name);
+  }
+
+  /**
+   *
+   * @param newAttr
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final Attr setAttributeNode(Attr newAttr) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param oldAttr
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final Attr removeAttributeNode(Attr oldAttr) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   * Introduced in DOM Level 2.
+   *
+   *
+   */
+  public boolean hasAttributes()
+  {
+    return DTM.NULL != dtm.getFirstAttribute(node);
+  }
+
+  /** @see org.w3c.dom.Element */
+  public final void normalize()
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param localName
+   *
+   *
+   * @see org.w3c.dom.Element
+   */
+  public final String getAttributeNS(String namespaceURI, String localName)
+  {
+       Node retNode = null;
+       int n = dtm.getAttributeNode(node,namespaceURI,localName);
+       if(n != DTM.NULL)
+               retNode = dtm.getNode(n);
+       return (null == retNode) ? EMPTYSTRING : retNode.getNodeValue();
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param qualifiedName
+   * @param value
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final void setAttributeNS(
+                                   String namespaceURI, String qualifiedName, String value)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param localName
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final void removeAttributeNS(String namespaceURI, String localName)
+    throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   * @param namespaceURI
+   * @param localName
+   *
+   *
+   * @see org.w3c.dom.Element
+   */
+  public final Attr getAttributeNodeNS(String namespaceURI, String localName)
+  {
+       Attr retAttr = null;
+       int n = dtm.getAttributeNode(node,namespaceURI,localName);
+       if(n != DTM.NULL)
+               retAttr = (Attr) dtm.getNode(n);
+       return retAttr;
+  }
+
+  /**
+   *
+   * @param newAttr
+   *
+   *
+   *
+   * @throws DOMException
+   * @see org.w3c.dom.Element
+   */
+  public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Attr
+   */
+  public final String getName()
+  {
+    return dtm.getNodeName(node);
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Attr
+   */
+  public final boolean getSpecified()
+  {
+    // We really don't know which attributes might have come from the
+    // source document versus from the DTD. Treat them all as having
+    // been provided by the user.
+    // %REVIEW% if/when we become aware of DTDs/schemae.
+    return true;
+  }
+
+  /**
+   *
+   *
+   * @see org.w3c.dom.Attr
+   */
+  public final String getValue()
+  {
+    return dtm.getNodeValue(node);
+  }
+
+  /**
+   *
+   * @param value
+   * @see org.w3c.dom.Attr
+   */
+  public final void setValue(String value)
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   * Get the owner element of an attribute.
+   *
+   *
+   * @see org.w3c.dom.Attr as of DOM Level 2
+   */
+  public final Element getOwnerElement()
+  {
+    if (getNodeType() != Node.ATTRIBUTE_NODE)
+      return null;
+    // In XPath and DTM data models, unlike DOM, an Attr's parent is its
+    // owner element.
+    int newnode = dtm.getParent(node);
+    return (newnode == DTM.NULL) ? null : (Element)(dtm.getNode(newnode));
+  }
+
+  /**
+   * NEEDSDOC Method adoptNode 
+   *
+   *
+   * NEEDSDOC @param source
+   *
+   *
+   *
+   * @throws DOMException
+   */
+  public Node adoptNode(Node source) throws DOMException
+  {
+
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying, as part of the XML declaration, the encoding
+   * of this document. This is <code>null</code> when unspecified.
+   * @since DOM Level 3
+   *
+   *
+   */
+  public String getInputEncoding()
+  {
+
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying whether errors checking is enforced or not.
+   * When set to <code>false</code>, the implementation is free to not
+   * test every possible error case normally defined on DOM operations,
+   * and not raise any <code>DOMException</code>. In case of error, the
+   * behavior is undefined. This attribute is <code>true</code> by
+   * defaults.
+   * @since DOM Level 3
+   *
+   *
+   */
+  public boolean getStrictErrorChecking()
+  {
+
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying whether errors checking is enforced or not.
+   * When set to <code>false</code>, the implementation is free to not
+   * test every possible error case normally defined on DOM operations,
+   * and not raise any <code>DOMException</code>. In case of error, the
+   * behavior is undefined. This attribute is <code>true</code> by
+   * defaults.
+   * @since DOM Level 3
+   *
+   * NEEDSDOC @param strictErrorChecking
+   */
+  public void setStrictErrorChecking(boolean strictErrorChecking)
+  {
+    throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+  }        
+        
+  /** Inner class to support getDOMImplementation.
+   */
+  static class DTMNodeProxyImplementation implements DOMImplementation
+  {
+    public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId)
+    {
+      throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
+    }
+    public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)                        
+    {
+      // Could create a DTM... but why, when it'd have to be permanantly empty?
+      throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);        
+    }
+    /** Ask whether we support a given DOM feature.
+     * 
+     * In fact, we do not _fully_ support any DOM feature -- we're a
+     * read-only subset -- so arguably we should always return false.
+     * On the other hand, it may be more practically useful to return
+     * true and simply treat the whole DOM as read-only, failing on the
+     * methods we can't support. I'm not sure which would be more useful
+     * to the caller.
+     */
+    public boolean hasFeature(String feature,String version)
+    {
+      if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase())) 
+					&& 
+          ("1.0".equals(version) || "2.0".equals(version))
+          )
+        return true;
+      return false;
+    }
+
+    /**
+     *  This method returns a specialized object which implements the
+     * specialized APIs of the specified feature and version. The
+     * specialized object may also be obtained by using binding-specific
+     * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations
+.
+     * @param feature The name of the feature requested (case-insensitive).
+     * @param version  This is the version number of the feature to test. If
+     *   the version is <code>null</code> or the empty string, supporting
+     *   any version of the feature will cause the method to return an
+     *   object that supports at least one version of the feature.
+     * @return  Returns an object which implements the specialized APIs of
+     *   the specified feature and version, if any, or <code>null</code> if
+     *   there is no object which implements interfaces associated with that
+     *   feature. If the <code>DOMObject</code> returned by this method
+     *   implements the <code>Node</code> interface, it must delegate to the
+     *   primary core <code>Node</code> and not return results inconsistent
+     *   with the primary core <code>Node</code> such as attributes,
+     *   childNodes, etc.
+     * @since DOM Level 3
+     */
+    public Object getFeature(String feature, String version) {
+        // we don't have any alternate node, either this node does the job
+        // or we don't have anything that does
+        //return hasFeature(feature, version) ? this : null;
+        return null; //PENDING
+    }
+
+  }
+
+
+    //RAMESH : Pending proper implementation of DOM Level 3
+    
+    public Object setUserData(String key,
+                              Object data,
+                              UserDataHandler handler) {
+        return getOwnerDocument().setUserData( key, data, handler);
+    }
+
+    /**
+     * Retrieves the object associated to a key on a this node. The object
+     * must first have been set to this node by calling
+     * <code>setUserData</code> with the same key.
+     * @param key The key the object is associated to.
+     * @return Returns the <code>DOMObject</code> associated to the given key
+     *   on this node, or <code>null</code> if there was none.
+     * @since DOM Level 3
+     */
+    public Object getUserData(String key) {
+        return getOwnerDocument().getUserData( key);
+    } 
+
+    /**
+     *  This method returns a specialized object which implements the
+     * specialized APIs of the specified feature and version. The
+     * specialized object may also be obtained by using binding-specific
+     * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
+     * @param feature The name of the feature requested (case-insensitive).
+     * @param version  This is the version number of the feature to test. If
+     *   the version is <code>null</code> or the empty string, supporting
+     *   any version of the feature will cause the method to return an
+     *   object that supports at least one version of the feature.
+     * @return  Returns an object which implements the specialized APIs of
+     *   the specified feature and version, if any, or <code>null</code> if
+     *   there is no object which implements interfaces associated with that
+     *   feature. If the <code>DOMObject</code> returned by this method
+     *   implements the <code>Node</code> interface, it must delegate to the
+     *   primary core <code>Node</code> and not return results inconsistent
+     *   with the primary core <code>Node</code> such as attributes,
+     *   childNodes, etc.
+     * @since DOM Level 3
+     */
+    public Object getFeature(String feature, String version) {
+        // we don't have any alternate node, either this node does the job
+        // or we don't have anything that does
+        return isSupported(feature, version) ? this : null;
+    }
+
+    /**
+     * Tests whether two nodes are equal.
+     * <br>This method tests for equality of nodes, not sameness (i.e.,
+     * whether the two nodes are references to the same object) which can be
+     * tested with <code>Node.isSameNode</code>. All nodes that are the same
+     * will also be equal, though the reverse may not be true.
+     * <br>Two nodes are equal if and only if the following conditions are
+     * satisfied: The two nodes are of the same type.The following string
+     * attributes are equal: <code>nodeName</code>, <code>localName</code>,
+     * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
+     * , <code>baseURI</code>. This is: they are both <code>null</code>, or
+     * they have the same length and are character for character identical.
+     * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
+     * This is: they are both <code>null</code>, or they have the same
+     * length and for each node that exists in one map there is a node that
+     * exists in the other map and is equal, although not necessarily at the
+     * same index.The <code>childNodes</code> <code>NodeLists</code> are
+     * equal. This is: they are both <code>null</code>, or they have the
+     * same length and contain equal nodes at the same index. This is true
+     * for <code>Attr</code> nodes as for any other type of node. Note that
+     * normalization can affect equality; to avoid this, nodes should be
+     * normalized before being compared.
+     * <br>For two <code>DocumentType</code> nodes to be equal, the following
+     * conditions must also be satisfied: The following string attributes
+     * are equal: <code>publicId</code>, <code>systemId</code>,
+     * <code>internalSubset</code>.The <code>entities</code>
+     * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
+     * <code>NamedNodeMaps</code> are equal.
+     * <br>On the other hand, the following do not affect equality: the
+     * <code>ownerDocument</code> attribute, the <code>specified</code>
+     * attribute for <code>Attr</code> nodes, the
+     * <code>isWhitespaceInElementContent</code> attribute for
+     * <code>Text</code> nodes, as well as any user data or event listeners
+     * registered on the nodes.
+     * @param arg The node to compare equality with.
+     * @param deep If <code>true</code>, recursively compare the subtrees; if
+     *   <code>false</code>, compare only the nodes themselves (and its
+     *   attributes, if it is an <code>Element</code>).
+     * @return If the nodes, and possibly subtrees are equal,
+     *   <code>true</code> otherwise <code>false</code>.
+     * @since DOM Level 3
+     */
+    public boolean isEqualNode(Node arg) {
+        if (arg == this) {
+            return true;
+        }
+        if (arg.getNodeType() != getNodeType()) {
+            return false;
+        }
+        // in theory nodeName can't be null but better be careful
+        // who knows what other implementations may be doing?...
+        if (getNodeName() == null) {
+            if (arg.getNodeName() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeName().equals(arg.getNodeName())) {
+            return false;
+        }
+
+        if (getLocalName() == null) {
+            if (arg.getLocalName() != null) {
+                return false;
+            }
+        }
+        else if (!getLocalName().equals(arg.getLocalName())) {
+            return false;
+        }
+
+        if (getNamespaceURI() == null) {
+            if (arg.getNamespaceURI() != null) {
+                return false;
+            }
+        }
+        else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
+            return false;
+        }
+
+        if (getPrefix() == null) {
+            if (arg.getPrefix() != null) {
+                return false;
+            }
+        }
+        else if (!getPrefix().equals(arg.getPrefix())) {
+            return false;
+        }
+
+        if (getNodeValue() == null) {
+            if (arg.getNodeValue() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeValue().equals(arg.getNodeValue())) {
+            return false;
+        }
+    /*
+        if (getBaseURI() == null) {
+            if (((NodeImpl) arg).getBaseURI() != null) {
+                return false;
+            }
+        }
+        else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
+            return false;
+        }
+*/
+        return true;
+    }
+
+    /**
+     * DOM Level 3:
+     * Look up the namespace URI associated to the given prefix, starting from this node.
+     * Use lookupNamespaceURI(null) to lookup the default namespace
+     *
+     * @param namespaceURI
+     * @return th URI for the namespace
+     * @since DOM Level 3
+     */
+    public String lookupNamespaceURI(String specifiedPrefix) {
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE : {
+
+                String namespace = this.getNamespaceURI();
+                String prefix = this.getPrefix();
+                if (namespace !=null) {
+                    // REVISIT: is it possible that prefix is empty string?
+                    if (specifiedPrefix== null && prefix==specifiedPrefix) {
+                        // looking for default namespace
+                        return namespace;
+                    } else if (prefix != null && prefix.equals(specifiedPrefix)) {
+                        // non default namespace
+                        return namespace;
+                    }
+                }
+                if (this.hasAttributes()) {
+                    NamedNodeMap map = this.getAttributes();
+                    int length = map.getLength();
+                    for (int i=0;i<length;i++) {
+                        Node attr = map.item(i);
+                        String attrPrefix = attr.getPrefix();
+                        String value = attr.getNodeValue();
+                        namespace = attr.getNamespaceURI();
+                        if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
+                            // at this point we are dealing with DOM Level 2 nodes only
+                            if (specifiedPrefix == null &&
+                                attr.getNodeName().equals("xmlns")) {
+                                // default namespace
+                                return value;
+                            } else if (attrPrefix !=null &&
+                                       attrPrefix.equals("xmlns") &&
+                                       attr.getLocalName().equals(specifiedPrefix)) {
+                 // non default namespace
+                                return value;
+                            }
+                        }
+                    }
+                }
+		/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+		*/
+                return null;
+            }
+/*
+        case Node.DOCUMENT_NODE : {
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
+                }
+                return null;
+            }
+        default:{
+	   /*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+             */
+                return null;
+            }
+
+        }
+    }
+    
+    /**
+     *  DOM Level 3:
+     *  This method checks if the specified <code>namespaceURI</code> is the
+     *  default namespace or not.
+     *  @param namespaceURI The namespace URI to look for.
+     *  @return  <code>true</code> if the specified <code>namespaceURI</code>
+     *   is the default namespace, <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isDefaultNamespace(String namespaceURI){
+       /*
+        // REVISIT: remove casts when DOM L3 becomes REC.
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE: {
+            String namespace = this.getNamespaceURI();
+            String prefix = this.getPrefix();
+
+            // REVISIT: is it possible that prefix is empty string?
+            if (prefix == null || prefix.length() == 0) {
+                if (namespaceURI == null) {
+                    return (namespace == namespaceURI);
+                }
+                return namespaceURI.equals(namespace);
+            }
+            if (this.hasAttributes()) {
+                ElementImpl elem = (ElementImpl)this;
+                NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
+                if (attr != null) {
+                    String value = attr.getNodeValue();
+                    if (namespaceURI == null) {
+                        return (namespace == value);
+                    }
+                    return namespaceURI.equals(value);
+                }
+            }
+
+            NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+            if (ancestor != null) {
+                return ancestor.isDefaultNamespace(namespaceURI);
+            }
+            return false;
+        }
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
+            }
+
+        case Node.ENTITY_NODE :
+          case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return false;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
+                    return ownerNode.isDefaultNamespace(namespaceURI);
+
+                }
+                return false;
+            }
+        default:{  
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.isDefaultNamespace(namespaceURI);
+                }
+                return false;
+            }
+
+        }
+*/
+        return false;
+    }
+
+    /**
+     * DOM Level 3:
+     * Look up the prefix associated to the given namespace URI, starting from this node.
+     *
+     * @param namespaceURI
+     * @return the prefix for the namespace
+     */
+    public String lookupPrefix(String namespaceURI){
+
+        // REVISIT: When Namespaces 1.1 comes out this may not be true
+        // Prefix can't be bound to null namespace
+        if (namespaceURI == null) {
+            return null;
+        }
+
+        short type = this.getNodeType();
+
+        switch (type) {
+/*
+        case Node.ELEMENT_NODE: {
+
+                String namespace = this.getNamespaceURI(); // to flip out children
+                return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
+            }
+
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupPrefix(namespaceURI);
+
+                }
+                return null;
+            }
+        default:{ 
+/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupPrefix(namespaceURI);
+                }
+*/
+                return null;
+            }
+         }
+    }
+
+    /**
+     * Returns whether this node is the same node as the given one.
+     * <br>This method provides a way to determine whether two
+     * <code>Node</code> references returned by the implementation reference
+     * the same object. When two <code>Node</code> references are references
+     * to the same object, even if through a proxy, the references may be
+     * used completely interchangably, such that all attributes have the
+     * same values and calling the same DOM method on either reference
+     * always has exactly the same effect.
+     * @param other The node to test against.
+     * @return Returns <code>true</code> if the nodes are the same,
+     *   <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isSameNode(Node other) {
+        // we do not use any wrapper so the answer is obvious
+        return this == other;
+    }
+
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public void setTextContent(String textContent)
+        throws DOMException {
+        setNodeValue(textContent);
+    }
+    
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public String getTextContent() throws DOMException {
+        return dtm.getStringValue(node).toString();
+    }
+
+    /**
+     * Compares a node with this node with regard to their position in the
+     * document.
+     * @param other The node to compare against this node.
+     * @return Returns how the given node is positioned relatively to this
+     *   node.
+     * @since DOM Level 3
+     */
+    public short compareDocumentPosition(Node other) throws DOMException {
+        return 0;
+    }
+
+    /**
+     * The absolute base URI of this node or <code>null</code> if undefined.
+     * This value is computed according to . However, when the
+     * <code>Document</code> supports the feature "HTML" , the base URI is
+     * computed using first the value of the href attribute of the HTML BASE
+     * element if any, and the value of the <code>documentURI</code>
+     * attribute from the <code>Document</code> interface otherwise.
+     * <br> When the node is an <code>Element</code>, a <code>Document</code>
+     * or a a <code>ProcessingInstruction</code>, this attribute represents
+     * the properties [base URI] defined in . When the node is a
+     * <code>Notation</code>, an <code>Entity</code>, or an
+     * <code>EntityReference</code>, this attribute represents the
+     * properties [declaration base URI] in the . How will this be affected
+     * by resolution of relative namespace URIs issue?It's not.Should this
+     * only be on Document, Element, ProcessingInstruction, Entity, and
+     * Notation nodes, according to the infoset? If not, what is it equal to
+     * on other nodes? Null? An empty string? I think it should be the
+     * parent's.No.Should this be read-only and computed or and actual
+     * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
+     * teleconference 30 May 2001).If the base HTML element is not yet
+     * attached to a document, does the insert change the Document.baseURI?
+     * Yes. (F2F 26 Sep 2001)
+     * @since DOM Level 3
+     */
+    public String getBaseURI() {
+        return null;
+    }
+
+    /**
+     * DOM Level 3
+     * Renaming node
+     */
+    public Node renameNode(Node n,
+                           String namespaceURI,
+                           String name)
+                           throws DOMException{
+        return n;
+    }
+    
+    /**
+     *  DOM Level 3
+     *  Normalize document.
+     */
+    public void normalizeDocument(){   
+
+    }
+    
+    /**
+     *  The configuration used when <code>Document.normalizeDocument</code> is
+     * invoked.
+     * @since DOM Level 3
+     */
+    public DOMConfiguration getDomConfig(){
+       return null;
+    }
+    
+    /** DOM Level 3 feature: documentURI */
+    protected String fDocumentURI;
+
+    /**
+     * DOM Level 3
+     */
+    public void setDocumentURI(String documentURI){
+        
+        fDocumentURI= documentURI;
+    }
+
+    /**
+     * DOM Level 3
+     * The location of the document or <code>null</code> if undefined.
+     * <br>Beware that when the <code>Document</code> supports the feature
+     * "HTML" , the href attribute of the HTML BASE element takes precedence
+     * over this attribute.
+     * @since DOM Level 3
+     */
+    public String getDocumentURI(){
+        return fDocumentURI;
+    }
+
+    /** DOM Level 3 feature: Document actualEncoding */
+    protected String actualEncoding;
+
+    /**
+     * DOM Level 3
+     * An attribute specifying the actual encoding of this document. This is
+     * <code>null</code> otherwise.
+     * <br> This attribute represents the property [character encoding scheme]
+     * defined in .
+     * @since DOM Level 3
+     */
+    public String getActualEncoding() {
+        return actualEncoding;
+    }
+
+    /**
+     * DOM Level 3
+     * An attribute specifying the actual encoding of this document. This is
+     * <code>null</code> otherwise.
+     * <br> This attribute represents the property [character encoding scheme]
+     * defined in .
+     * @since DOM Level 3
+     */
+    public void setActualEncoding(String value) {
+        actualEncoding = value;
+    }
+
+   /**
+    * DOM Level 3
+    */
+    public Text replaceWholeText(String content)
+                                 throws DOMException{
+/*
+
+        if (needsSyncData()) {
+            synchronizeData();
+        }
+
+        // make sure we can make the replacement
+        if (!canModify(nextSibling)) {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
+        }
+
+        Node parent = this.getParentNode();
+        if (content == null || content.length() == 0) {
+            // remove current node
+            if (parent !=null) { // check if node in the tree
+                parent.removeChild(this);
+                return null;
+            }
+        }
+        Text currentNode = null;
+        if (isReadOnly()){
+            Text newNode = this.ownerDocument().createTextNode(content);
+            if (parent !=null) { // check if node in the tree
+                parent.insertBefore(newNode, this);
+                parent.removeChild(this);
+                currentNode = newNode;
+            } else {
+                return newNode;
+            }
+        }  else {
+            this.setData(content);
+            currentNode = this;
+        }
+        Node sibling =  currentNode.getNextSibling();
+        while ( sibling !=null) {
+            parent.removeChild(sibling);
+            sibling = currentNode.getNextSibling();
+        }
+
+        return currentNode;
+*/
+        return null; //Pending
+    }
+
+    /**
+     * DOM Level 3
+     * Returns all text of <code>Text</code> nodes logically-adjacent text
+     * nodes to this node, concatenated in document order.
+     * @since DOM Level 3
+     */
+    public String getWholeText(){
+
+/*
+        if (needsSyncData()) {
+            synchronizeData();
+        }
+        if (nextSibling == null) {
+            return data;
+        }
+        StringBuffer buffer = new StringBuffer();
+        if (data != null && data.length() != 0) {
+            buffer.append(data);
+        }
+        getWholeText(nextSibling, buffer);
+        return buffer.toString();
+*/
+        return null; // PENDING
+    }
+
+    /**
+     * DOM Level 3
+     * Returns whether this text node contains whitespace in element content,
+     * often abusively called "ignorable whitespace".
+     */
+    public boolean isElementContentWhitespace(){
+        return false;
+    }
+
+    /**
+     * NON-DOM: set the type of this attribute to be ID type.
+     *
+     * @param id
+     */
+    public void setIdAttribute(boolean id){
+        //PENDING
+    }
+
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttribute(String name, boolean makeId) {
+        //PENDING
+    }
+
+       
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttributeNode(Attr at, boolean makeId) {
+        //PENDING
+    }
+
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttributeNS(String namespaceURI, String localName,
+                                    boolean makeId) {
+        //PENDING
+    }
+
+    public TypeInfo getSchemaTypeInfo(){
+      return null; //PENDING
+    }
+
+    public boolean isId() {
+        return false; //PENDING
+    }
+
+
+    private String xmlEncoding;
+    
+    public String getXmlEncoding( ) {
+        return xmlEncoding;
+    }
+    
+    public void setXmlEncoding( String xmlEncoding ) {
+        this.xmlEncoding = xmlEncoding;
+    }
+
+    private boolean xmlStandalone;
+    
+    public boolean getXmlStandalone() {
+        return xmlStandalone;
+    }
+
+    public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
+        this.xmlStandalone = xmlStandalone;
+    }
+
+    private String xmlVersion;
+    
+    public String getXmlVersion() {
+        return xmlVersion;
+    }
+
+    public void setXmlVersion(String xmlVersion) throws DOMException {
+        this.xmlVersion = xmlVersion;
+    }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMStringPool.java b/src/main/java/org/apache/xml/dtm/ref/DTMStringPool.java
new file mode 100644
index 0000000..a47e7bf
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMStringPool.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMStringPool.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.util.Vector;
+
+import org.apache.xml.utils.IntVector;
+
+/** <p>DTMStringPool is an "interning" mechanism for strings. It will
+ * create a stable 1:1 mapping between a set of string values and a set of
+ * integer index values, so the integers can be used to reliably and
+ * uniquely identify (and when necessary retrieve) the strings.</p>
+ *
+ * <p>Design Priorities:
+ * <ul>
+ * <li>String-to-index lookup speed is critical.</li>
+ * <li>Index-to-String lookup speed is slightly less so.</li>
+ * <li>Threadsafety is not guaranteed at this level.
+ * Enforce that in the application if needed.</li>
+ * <li>Storage efficiency is an issue but not a huge one.
+ * It is expected that string pools won't exceed about 2000 entries.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>Implementation detail: A standard Hashtable is relatively
+ * inefficient when looking up primitive int values, especially when
+ * we're already maintaining an int-to-string vector.  So I'm
+ * maintaining a simple hash chain within this class.</p>
+ *
+ * <p>NOTE: There is nothing in the code that has a real dependency upon
+ * String. It would work with any object type that implements reliable
+ * .hashCode() and .equals() operations. The API enforces Strings because
+ * it's safer that way, but this could trivially be turned into a general
+ * ObjectPool if one was needed.</p>
+ *
+ * <p>Status: Passed basic test in main().</p>
+ * */
+public class DTMStringPool
+{
+  Vector m_intToString;
+  static final int HASHPRIME=101;
+  int[] m_hashStart=new int[HASHPRIME];
+  IntVector m_hashChain;
+  public static final int NULL=-1;
+
+  /**
+   * Create a DTMStringPool using the given chain size
+   * 
+   * @param chainSize The size of the hash chain vector
+   */
+  public DTMStringPool(int chainSize)
+    {
+      m_intToString=new Vector();
+      m_hashChain=new IntVector(chainSize);
+      removeAllElements();
+      
+      // -sb Add this to force empty strings to be index 0.
+      stringToIndex("");
+    }
+  
+  public DTMStringPool()
+    {
+      this(512);	
+    }
+    
+  public void removeAllElements()
+    {
+      m_intToString.removeAllElements();
+      for(int i=0;i<HASHPRIME;++i)
+        m_hashStart[i]=NULL;
+      m_hashChain.removeAllElements();
+    }
+
+  /** @return string whose value is uniquely identified by this integer index.
+   * @throws java.lang.ArrayIndexOutOfBoundsException
+   *  if index doesn't map to a string.
+   * */ 
+  public String indexToString(int i)
+    throws java.lang.ArrayIndexOutOfBoundsException
+    {
+      if(i==NULL) return null;
+      return (String) m_intToString.elementAt(i);
+    }
+
+  /** @return integer index uniquely identifying the value of this string. */ 
+  public int stringToIndex(String s)
+    {
+      if(s==null) return NULL;
+      
+      int hashslot=s.hashCode()%HASHPRIME;
+      if(hashslot<0) hashslot=-hashslot;
+
+      // Is it one we already know?
+      int hashlast=m_hashStart[hashslot];
+      int hashcandidate=hashlast;
+      while(hashcandidate!=NULL)
+        {
+          if(m_intToString.elementAt(hashcandidate).equals(s))
+            return hashcandidate;
+
+          hashlast=hashcandidate;
+          hashcandidate=m_hashChain.elementAt(hashcandidate);
+        }
+      
+      // New value. Add to tables.
+      int newIndex=m_intToString.size();
+      m_intToString.addElement(s);
+
+      m_hashChain.addElement(NULL);	// Initialize to no-following-same-hash
+      if(hashlast==NULL)  // First for this hash
+        m_hashStart[hashslot]=newIndex;
+      else // Link from previous with same hash
+        m_hashChain.setElementAt(newIndex,hashlast);
+
+      return newIndex;
+    }
+
+  /** Command-line unit test driver. This test relies on the fact that
+   * this version of the pool assigns indices consecutively, starting
+   * from zero, as new unique strings are encountered.
+   */
+  public static void main(String[] args)
+  {
+    String[] word={
+      "Zero","One","Two","Three","Four","Five",
+      "Six","Seven","Eight","Nine","Ten",
+      "Eleven","Twelve","Thirteen","Fourteen","Fifteen",
+      "Sixteen","Seventeen","Eighteen","Nineteen","Twenty",
+      "Twenty-One","Twenty-Two","Twenty-Three","Twenty-Four",
+      "Twenty-Five","Twenty-Six","Twenty-Seven","Twenty-Eight",
+      "Twenty-Nine","Thirty","Thirty-One","Thirty-Two",
+      "Thirty-Three","Thirty-Four","Thirty-Five","Thirty-Six",
+      "Thirty-Seven","Thirty-Eight","Thirty-Nine"};
+
+    DTMStringPool pool=new DTMStringPool();
+
+    System.out.println("If no complaints are printed below, we passed initial test.");
+
+    for(int pass=0;pass<=1;++pass)
+      {
+        int i;
+
+        for(i=0;i<word.length;++i)
+          {
+            int j=pool.stringToIndex(word[i]);
+            if(j!=i)
+              System.out.println("\tMismatch populating pool: assigned "+
+                                 j+" for create "+i);
+          }
+
+        for(i=0;i<word.length;++i)
+          {
+            int j=pool.stringToIndex(word[i]);
+            if(j!=i)
+              System.out.println("\tMismatch in stringToIndex: returned "+
+                                 j+" for lookup "+i);
+          }
+
+        for(i=0;i<word.length;++i)
+          {
+            String w=pool.indexToString(i);
+            if(!word[i].equals(w))
+              System.out.println("\tMismatch in indexToString: returned"+
+                                 w+" for lookup "+i);
+          }
+        
+        pool.removeAllElements();
+        
+        System.out.println("\nPass "+pass+" complete\n");
+      } // end pass loop
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/DTMTreeWalker.java b/src/main/java/org/apache/xml/dtm/ref/DTMTreeWalker.java
new file mode 100644
index 0000000..73d2fc0
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/DTMTreeWalker.java
@@ -0,0 +1,404 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DTMTreeWalker.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.NodeConsumer;
+import org.apache.xml.utils.XMLString;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class does a pre-order walk of the DTM tree, calling a ContentHandler
+ * interface as it goes. As such, it's more like the Visitor design pattern
+ * than like the DOM's TreeWalker.
+ *
+ * I think normally this class should not be needed, because 
+ * of DTM#dispatchToEvents.
+ * @xsl.usage advanced
+ */
+public class DTMTreeWalker
+{
+
+  /** Local reference to a ContentHandler          */
+  private ContentHandler m_contentHandler = null;
+
+  /** DomHelper for this TreeWalker          */
+  protected DTM m_dtm;
+  
+  /**
+   * Set the DTM to be traversed.
+   * 
+   * @param dtm The Document Table Model to be used.
+   */
+  public void setDTM(DTM dtm)
+  {
+    m_dtm = dtm;
+  }
+
+  /**
+   * Get the ContentHandler used for the tree walk.
+   *
+   * @return the ContentHandler used for the tree walk
+   */
+  public ContentHandler getcontentHandler()
+  {
+    return m_contentHandler;
+  }
+  
+  /**
+   * Set the ContentHandler used for the tree walk.
+   *
+   * @param ch the ContentHandler to be the result of the tree walk.
+   */
+  public void setcontentHandler(ContentHandler ch)
+  {
+    m_contentHandler = ch;
+  }
+
+  
+  /**
+   * Constructor.
+   */
+  public DTMTreeWalker()
+  {
+  }
+  
+  /**
+   * Constructor.
+   * @param   contentHandler The implemention of the
+   * contentHandler operation (toXMLString, digest, ...)
+   */
+  public DTMTreeWalker(ContentHandler contentHandler, DTM dtm)
+  {
+    this.m_contentHandler = contentHandler;
+    m_dtm = dtm;
+  }
+  
+  /** Perform a non-recursive pre-order/post-order traversal,
+   * operating as a Visitor. startNode (preorder) and endNode
+   * (postorder) are invoked for each node as we traverse over them,
+   * with the result that the node is written out to m_contentHandler.
+   *
+   * @param pos Node in the tree at which to start (and end) traversal --
+   * in other words, the root of the subtree to traverse over.
+   *
+   * @throws TransformerException */
+  public void traverse(int pos) throws org.xml.sax.SAXException
+  {
+    // %REVIEW% Why isn't this just traverse(pos,pos)?
+
+    int top = pos;		// Remember the root of this subtree
+
+    while (DTM.NULL != pos)
+    {
+      startNode(pos);
+      int nextNode = m_dtm.getFirstChild(pos);
+      while (DTM.NULL == nextNode)
+      {
+        endNode(pos);
+
+        if (top == pos)
+          break;
+
+        nextNode = m_dtm.getNextSibling(pos);
+
+        if (DTM.NULL == nextNode)
+        {
+          pos = m_dtm.getParent(pos);
+
+          if ((DTM.NULL == pos) || (top == pos))
+          {
+            // %REVIEW% This condition isn't tested in traverse(pos,top)
+            // -- bug?
+            if (DTM.NULL != pos)
+              endNode(pos);
+
+            nextNode = DTM.NULL;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+  }
+
+  /** Perform a non-recursive pre-order/post-order traversal,
+   * operating as a Visitor. startNode (preorder) and endNode
+   * (postorder) are invoked for each node as we traverse over them,
+   * with the result that the node is written out to m_contentHandler.
+   *
+   * @param pos Node in the tree where to start traversal
+   * @param top Node in the tree where to end traversal.
+   * If top==DTM.NULL, run through end of document.
+   *
+   * @throws TransformerException
+   */
+  public void traverse(int pos, int top) throws org.xml.sax.SAXException
+  {
+    // %OPT% Can we simplify the loop conditionals by adding:
+    //		if(top==DTM.NULL) top=0
+    // -- or by simply ignoring this case and relying on the fact that
+    // pos will never equal DTM.NULL until we're ready to exit?
+
+    while (DTM.NULL != pos)
+    {
+      startNode(pos);
+      int nextNode = m_dtm.getFirstChild(pos);
+      while (DTM.NULL == nextNode)
+      {
+        endNode(pos);
+
+        if ((DTM.NULL != top) && top == pos)
+          break;
+
+        nextNode = m_dtm.getNextSibling(pos);
+
+        if (DTM.NULL == nextNode)
+        {
+          pos = m_dtm.getParent(pos);
+
+          if ((DTM.NULL == pos) || ((DTM.NULL != top) && (top == pos)))
+          {
+            nextNode = DTM.NULL;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+  }
+
+  /** Flag indicating whether following text to be processed is raw text          */
+  boolean nextIsRaw = false;
+  
+  /**
+   * Optimized dispatch of characters.
+   */
+  private final void dispatachChars(int node)
+     throws org.xml.sax.SAXException
+  {
+    m_dtm.dispatchCharactersEvents(node, m_contentHandler, false);
+  }
+
+  /**
+   * Start processing given node
+   *
+   *
+   * @param node Node to process
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void startNode(int node) throws org.xml.sax.SAXException
+  {
+
+    if (m_contentHandler instanceof NodeConsumer)
+    {
+      // %TBD%
+//      ((NodeConsumer) m_contentHandler).setOriginatingNode(node);
+    }
+
+    switch (m_dtm.getNodeType(node))
+    {
+    case DTM.COMMENT_NODE :
+    {
+      XMLString data = m_dtm.getStringValue(node);
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+        data.dispatchAsComment(lh);
+      }
+    }
+    break;
+    case DTM.DOCUMENT_FRAGMENT_NODE :
+
+      // ??;
+      break;
+    case DTM.DOCUMENT_NODE :
+      this.m_contentHandler.startDocument();
+      break;
+    case DTM.ELEMENT_NODE :
+      DTM dtm = m_dtm;           
+
+      for (int nsn = dtm.getFirstNamespaceNode(node, true); DTM.NULL != nsn;
+           nsn = dtm.getNextNamespaceNode(node, nsn, true))
+      {
+        // String prefix = dtm.getPrefix(nsn);
+        String prefix = dtm.getNodeNameX(nsn);
+
+        this.m_contentHandler.startPrefixMapping(prefix, dtm.getNodeValue(nsn));
+        
+      }
+
+      // System.out.println("m_dh.getNamespaceOfNode(node): "+m_dh.getNamespaceOfNode(node));
+      // System.out.println("m_dh.getLocalNameOfNode(node): "+m_dh.getLocalNameOfNode(node));
+      String ns = dtm.getNamespaceURI(node);
+      if(null == ns)
+        ns = "";
+        
+      // %OPT% !!
+      org.xml.sax.helpers.AttributesImpl attrs = 
+                            new org.xml.sax.helpers.AttributesImpl();
+              
+      for (int i = dtm.getFirstAttribute(node); 
+           i != DTM.NULL; 
+           i = dtm.getNextAttribute(i)) 
+      {
+        attrs.addAttribute(dtm.getNamespaceURI(i), 
+                           dtm.getLocalName(i), 
+                           dtm.getNodeName(i), 
+                           "CDATA", 
+                           dtm.getNodeValue(i));
+      }
+      
+        
+      this.m_contentHandler.startElement(ns,
+                                         m_dtm.getLocalName(node),
+                                         m_dtm.getNodeName(node),
+                                         attrs);
+      break;
+    case DTM.PROCESSING_INSTRUCTION_NODE :
+    {
+      String name = m_dtm.getNodeName(node);
+
+      // String data = pi.getData();
+      if (name.equals("xslt-next-is-raw"))
+      {
+        nextIsRaw = true;
+      }
+      else
+      {
+        this.m_contentHandler.processingInstruction(name,
+                                                    m_dtm.getNodeValue(node));
+      }
+    }
+    break;
+    case DTM.CDATA_SECTION_NODE :
+    {
+      boolean isLexH = (m_contentHandler instanceof LexicalHandler);
+      LexicalHandler lh = isLexH
+                          ? ((LexicalHandler) this.m_contentHandler) : null;
+
+      if (isLexH)
+      {
+        lh.startCDATA();
+      }
+      
+      dispatachChars(node);
+
+      {
+        if (isLexH)
+        {
+          lh.endCDATA();
+        }
+      }
+    }
+    break;
+    case DTM.TEXT_NODE :
+    {
+      if (nextIsRaw)
+      {
+        nextIsRaw = false;
+
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+        dispatachChars(node);
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+      }
+      else
+      {
+        dispatachChars(node);
+      }
+    }
+    break;
+    case DTM.ENTITY_REFERENCE_NODE :
+    {
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        ((LexicalHandler) this.m_contentHandler).startEntity(
+          m_dtm.getNodeName(node));
+      }
+      else
+      {
+
+        // warning("Can not output entity to a pure SAX ContentHandler");
+      }
+    }
+    break;
+    default :
+    }
+  }
+
+  /**
+   * End processing of given node 
+   *
+   *
+   * @param node Node we just finished processing
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void endNode(int node) throws org.xml.sax.SAXException
+  {
+
+    switch (m_dtm.getNodeType(node))
+    {
+    case DTM.DOCUMENT_NODE :
+      this.m_contentHandler.endDocument();
+      break;
+    case DTM.ELEMENT_NODE :
+      String ns = m_dtm.getNamespaceURI(node);
+      if(null == ns)
+        ns = "";
+      this.m_contentHandler.endElement(ns,
+                                         m_dtm.getLocalName(node),
+                                         m_dtm.getNodeName(node));
+
+      for (int nsn = m_dtm.getFirstNamespaceNode(node, true); DTM.NULL != nsn;
+           nsn = m_dtm.getNextNamespaceNode(node, nsn, true))
+      {
+        // String prefix = m_dtm.getPrefix(nsn);
+        String prefix = m_dtm.getNodeNameX(nsn);
+
+        this.m_contentHandler.endPrefixMapping(prefix);
+      }
+      break;
+    case DTM.CDATA_SECTION_NODE :
+      break;
+    case DTM.ENTITY_REFERENCE_NODE :
+    {
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+
+        lh.endEntity(m_dtm.getNodeName(node));
+      }
+    }
+    break;
+    default :
+    }
+  }
+}  //TreeWalker
+
diff --git a/src/main/java/org/apache/xml/dtm/ref/ExpandedNameTable.java b/src/main/java/org/apache/xml/dtm/ref/ExpandedNameTable.java
new file mode 100644
index 0000000..9fcdbd6
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/ExpandedNameTable.java
@@ -0,0 +1,391 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExpandedNameTable.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+import org.apache.xml.dtm.DTM;
+
+/**
+ * This is a default implementation of a table that manages mappings from
+ * expanded names to expandedNameIDs.
+ *
+ * %OPT% The performance of the getExpandedTypeID() method is very important 
+ * to DTM building. To get the best performance out of this class, we implement
+ * a simple hash algorithm directly into this class, instead of using the
+ * inefficient java.util.Hashtable. The code for the get and put operations
+ * are combined in getExpandedTypeID() method to share the same hash calculation
+ * code. We only need to implement the rehash() interface which is used to
+ * expand the hash table.
+ */
+public class ExpandedNameTable
+{
+
+  /** Array of extended types for this document   */
+  private ExtendedType[] m_extendedTypes;
+
+  /** The initial size of the m_extendedTypes array */
+  private static int m_initialSize = 128;
+  
+  /** Next available extended type   */
+  // %REVIEW% Since this is (should be) always equal 
+  // to the length of m_extendedTypes, do we need this? 
+  private int m_nextType;
+
+  // These are all the types prerotated, for caller convenience.
+  public static final int ELEMENT = ((int)DTM.ELEMENT_NODE) ;
+  public static final int ATTRIBUTE = ((int)DTM.ATTRIBUTE_NODE) ;
+  public static final int TEXT = ((int)DTM.TEXT_NODE) ;
+  public static final int CDATA_SECTION = ((int)DTM.CDATA_SECTION_NODE) ;
+  public static final int ENTITY_REFERENCE = ((int)DTM.ENTITY_REFERENCE_NODE) ;
+  public static final int ENTITY = ((int)DTM.ENTITY_NODE) ;
+  public static final int PROCESSING_INSTRUCTION = ((int)DTM.PROCESSING_INSTRUCTION_NODE) ;
+  public static final int COMMENT = ((int)DTM.COMMENT_NODE) ;
+  public static final int DOCUMENT = ((int)DTM.DOCUMENT_NODE) ;
+  public static final int DOCUMENT_TYPE = ((int)DTM.DOCUMENT_TYPE_NODE) ;
+  public static final int DOCUMENT_FRAGMENT =((int)DTM.DOCUMENT_FRAGMENT_NODE) ;
+  public static final int NOTATION = ((int)DTM.NOTATION_NODE) ;
+  public static final int NAMESPACE = ((int)DTM.NAMESPACE_NODE) ;
+
+  /** Workspace for lookup. NOT THREAD SAFE!
+   * */
+  ExtendedType hashET = new ExtendedType(-1, "", "");
+
+  /** The array to store the default extended types. */
+  private static ExtendedType[] m_defaultExtendedTypes;
+
+  /**
+   * The default load factor of the Hashtable.
+   * This is used to calcualte the threshold.
+   */
+  private static float m_loadFactor = 0.75f;
+    
+  /**
+   * The initial capacity of the hash table. Use a bigger number
+   * to avoid the cost of expanding the table.
+   */ 
+  private static int m_initialCapacity = 203;
+  
+  /**
+   * The capacity of the hash table, i.e. the size of the
+   * internal HashEntry array.
+   */ 
+  private int m_capacity;
+  
+  /** 
+   * The threshold of the hash table, which is equal to capacity * loadFactor.
+   * If the number of entries in the hash table is bigger than the threshold,
+   * the hash table needs to be expanded.
+   */
+  private int m_threshold;
+  
+  /**
+   * The internal array to store the hash entries.
+   * Each array member is a slot for a hash bucket.
+   */
+  private HashEntry[] m_table;
+
+  /**
+   * Init default values
+   */
+  static {
+    m_defaultExtendedTypes = new ExtendedType[DTM.NTYPES];
+
+    for (int i = 0; i < DTM.NTYPES; i++)
+    {
+      m_defaultExtendedTypes[i] = new ExtendedType(i, "", "");
+    }
+  }
+
+  /**
+   * Create an expanded name table.
+   */
+  public ExpandedNameTable()
+  {
+    m_capacity = m_initialCapacity;
+    m_threshold = (int)(m_capacity * m_loadFactor);
+    m_table = new HashEntry[m_capacity];
+    
+    initExtendedTypes();
+  }
+
+
+  /**
+   *  Initialize the vector of extended types with the
+   *  basic DOM node types.
+   */
+  private void initExtendedTypes()
+  {    
+    m_extendedTypes = new ExtendedType[m_initialSize];
+    for (int i = 0; i < DTM.NTYPES; i++) {
+        m_extendedTypes[i] = m_defaultExtendedTypes[i];
+        m_table[i] = new HashEntry(m_defaultExtendedTypes[i], i, i, null);
+    }
+    
+    m_nextType = DTM.NTYPES;
+  }
+
+  /**
+   * Given an expanded name represented by namespace, local name and node type,
+   * return an ID.  If the expanded-name does not exist in the internal tables,
+   * the entry will be created, and the ID will be returned.  Any additional 
+   * nodes that are created that have this expanded name will use this ID.
+   *
+   * @param namespace The namespace
+   * @param localName The local name
+   * @param type The node type
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(String namespace, String localName, int type)
+  {
+    return getExpandedTypeID(namespace, localName, type, false);
+  }
+  
+  /**
+   * Given an expanded name represented by namespace, local name and node type,
+   * return an ID.  If the expanded-name does not exist in the internal tables,
+   * the entry will be created, and the ID will be returned.  Any additional 
+   * nodes that are created that have this expanded name will use this ID.
+   * <p>
+   * If searchOnly is true, we will return -1 if the name is not found in the 
+   * table, otherwise the name is added to the table and the expanded name id
+   * of the new entry is returned.
+   *
+   * @param namespace The namespace
+   * @param localName The local name
+   * @param type The node type
+   * @param searchOnly If it is true, we will only search for the expanded name.
+   * -1 is return is the name is not found.
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(String namespace, String localName, int type, boolean searchOnly)
+  {
+    if (null == namespace)
+      namespace = "";
+    if (null == localName)
+      localName = "";
+    
+    // Calculate the hash code
+    int hash = type + namespace.hashCode() + localName.hashCode();
+    
+    // Redefine the hashET object to represent the new expanded name.
+    hashET.redefine(type, namespace, localName, hash);
+    
+    // Calculate the index into the HashEntry table.
+    int index = hash % m_capacity;
+    if (index < 0)
+      index = -index;
+
+    // Look up the expanded name in the hash table. Return the id if
+    // the expanded name is already in the hash table.
+    for (HashEntry e = m_table[index]; e != null; e = e.next)
+    {
+      if (e.hash == hash && e.key.equals(hashET))
+        return e.value;
+    }
+    
+    if (searchOnly)
+    {
+      return DTM.NULL;
+    }
+
+    // Expand the internal HashEntry array if necessary.
+    if (m_nextType > m_threshold) {
+      rehash();
+      index = hash % m_capacity;
+      if (index < 0)
+        index = -index;
+    }
+    
+    // Create a new ExtendedType object
+    ExtendedType newET = new ExtendedType(type, namespace, localName, hash);
+    
+    // Expand the m_extendedTypes array if necessary.
+    if (m_extendedTypes.length == m_nextType) {
+        ExtendedType[] newArray = new ExtendedType[m_extendedTypes.length * 2];
+        System.arraycopy(m_extendedTypes, 0, newArray, 0,
+                         m_extendedTypes.length);
+        m_extendedTypes = newArray;
+    }
+    
+    m_extendedTypes[m_nextType] = newET;
+    
+    // Create a new hash entry for the new ExtendedType and put it into 
+    // the table.
+    HashEntry entry = new HashEntry(newET, m_nextType, hash, m_table[index]);
+    m_table[index] = entry;
+
+    return m_nextType++;
+  }
+
+  /**
+   * Increases the capacity of and internally reorganizes the hashtable, 
+   * in order to accommodate and access its entries more efficiently. 
+   * This method is called when the number of keys in the hashtable exceeds
+   * this hashtable's capacity and load factor.
+   */
+  private void rehash()
+  {
+    int oldCapacity = m_capacity;
+    HashEntry[] oldTable = m_table;
+      
+    int newCapacity = 2 * oldCapacity + 1;
+    m_capacity = newCapacity;
+    m_threshold = (int)(newCapacity * m_loadFactor);
+      
+    m_table = new HashEntry[newCapacity];
+    for (int i = oldCapacity-1; i >=0 ; i--)
+    {
+      for (HashEntry old = oldTable[i]; old != null; )
+      {
+        HashEntry e = old;
+        old = old.next;
+          
+        int newIndex = e.hash % newCapacity;
+        if (newIndex < 0)
+          newIndex = -newIndex;
+          
+        e.next = m_table[newIndex];
+        m_table[newIndex] = e;
+      }
+    }
+  }
+
+  /**
+   * Given a type, return an expanded name ID.Any additional nodes that are
+   * created that have this expanded name will use this ID.
+   *
+   * @return the expanded-name id of the node.
+   */
+  public int getExpandedTypeID(int type)
+  {
+    return type;
+  }
+
+  /**
+   * Given an expanded-name ID, return the local name part.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return String Local name of this node, or null if the node has no name.
+   */
+  public String getLocalName(int ExpandedNameID)
+  {
+    return m_extendedTypes[ExpandedNameID].getLocalName();
+  }
+
+  /**
+   * Given an expanded-name ID, return the local name ID.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return The id of this local name.
+   */
+  public final int getLocalNameID(int ExpandedNameID)
+  {
+    // ExtendedType etype = m_extendedTypes[ExpandedNameID];
+    if (m_extendedTypes[ExpandedNameID].getLocalName().equals(""))
+      return 0;
+    else
+    return ExpandedNameID;
+  }
+
+
+  /**
+   * Given an expanded-name ID, return the namespace URI part.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespace(int ExpandedNameID)
+  {
+    String namespace = m_extendedTypes[ExpandedNameID].getNamespace();
+    return (namespace.equals("") ? null : namespace);
+  }
+
+  /**
+   * Given an expanded-name ID, return the namespace URI ID.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return The id of this namespace.
+   */
+  public final int getNamespaceID(int ExpandedNameID)
+  {
+    //ExtendedType etype = m_extendedTypes[ExpandedNameID];
+    if (m_extendedTypes[ExpandedNameID].getNamespace().equals(""))
+      return 0;
+    else
+    return ExpandedNameID;
+  }
+
+  /**
+   * Given an expanded-name ID, return the local name ID.
+   *
+   * @param ExpandedNameID an ID that represents an expanded-name.
+   * @return The id of this local name.
+   */
+  public final short getType(int ExpandedNameID)
+  {
+    //ExtendedType etype = m_extendedTypes[ExpandedNameID];
+    return (short)m_extendedTypes[ExpandedNameID].getNodeType();
+  }
+  
+  /**
+   * Return the size of the ExpandedNameTable
+   *
+   * @return The size of the ExpandedNameTable
+   */
+  public int getSize()
+  {
+    return m_nextType;
+  }
+  
+  /**
+   * Return the array of extended types
+   *
+   * @return The array of extended types
+   */
+  public ExtendedType[] getExtendedTypes()
+  {
+    return m_extendedTypes;
+  }
+
+  /**
+   * Inner class which represents a hash table entry.
+   * The field next points to the next entry which is hashed into
+   * the same bucket in the case of "hash collision".
+   */
+  private static final class HashEntry
+  {
+    ExtendedType key;
+    int value;
+    int hash;
+    HashEntry next;
+      
+    protected HashEntry(ExtendedType key, int value, int hash, HashEntry next)
+    {
+      this.key = key;
+      this.value = value;
+      this.hash = hash;
+      this.next = next;
+    }
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/ExtendedType.java b/src/main/java/org/apache/xml/dtm/ref/ExtendedType.java
new file mode 100644
index 0000000..fd4e1d0
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/ExtendedType.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtendedType.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref;
+
+/**
+ * The class ExtendedType represents an extended type object used by
+ * ExpandedNameTable.
+ */
+public final class ExtendedType
+{
+    private int nodetype;
+    private String namespace;
+    private String localName;
+    private int hash;
+
+    /**
+     * Create an ExtendedType object from node type, namespace and local name.
+     * The hash code is calculated from the node type, namespace and local name.
+     * 
+     * @param nodetype Type of the node
+     * @param namespace Namespace of the node
+     * @param localName Local name of the node
+     */
+    public ExtendedType (int nodetype, String namespace, String localName)
+    {
+      this.nodetype = nodetype;
+      this.namespace = namespace;
+      this.localName = localName;
+      this.hash = nodetype + namespace.hashCode() + localName.hashCode();
+    }
+
+    /**
+     * Create an ExtendedType object from node type, namespace, local name
+     * and a given hash code.
+     * 
+     * @param nodetype Type of the node
+     * @param namespace Namespace of the node
+     * @param localName Local name of the node
+     * @param hash The given hash code
+     */
+    public ExtendedType (int nodetype, String namespace, String localName, int hash)
+    {
+      this.nodetype = nodetype;
+      this.namespace = namespace;
+      this.localName = localName;
+      this.hash = hash;
+    }
+
+    /** 
+     * Redefine this ExtendedType object to represent a different extended type.
+     * This is intended to be used ONLY on the hashET object. Using it elsewhere
+     * will mess up existing hashtable entries!
+     */
+    protected void redefine(int nodetype, String namespace, String localName)
+    {
+      this.nodetype = nodetype;
+      this.namespace = namespace;
+      this.localName = localName;
+      this.hash = nodetype + namespace.hashCode() + localName.hashCode();
+    }
+
+    /** 
+     * Redefine this ExtendedType object to represent a different extended type.
+     * This is intended to be used ONLY on the hashET object. Using it elsewhere
+     * will mess up existing hashtable entries!
+     */
+    protected void redefine(int nodetype, String namespace, String localName, int hash)
+    {
+      this.nodetype = nodetype;
+      this.namespace = namespace;
+      this.localName = localName;
+      this.hash = hash;
+    }
+
+    /**
+     * Override the hashCode() method in the Object class
+     */
+    public int hashCode()
+    {
+      return hash;
+    }
+
+    /**
+     * Test if this ExtendedType object is equal to the given ExtendedType.
+     * 
+     * @param other The other ExtendedType object to test for equality
+     * @return true if the two ExtendedType objects are equal.
+     */
+    public boolean equals(ExtendedType other)
+    {
+      try
+      {
+        return other.nodetype == this.nodetype &&
+                other.localName.equals(this.localName) &&
+                other.namespace.equals(this.namespace);
+      }
+      catch(NullPointerException e)
+      {
+        return false;
+      }
+    }
+    
+    /**
+     * Return the node type
+     */
+    public int getNodeType()
+    {
+      return nodetype;
+    }
+    
+    /**
+     * Return the local name
+     */
+    public String getLocalName()
+    {
+      return localName;
+    }
+    
+    /**
+     * Return the namespace
+     */
+    public String getNamespace()
+    {
+      return namespace;
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource.java b/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource.java
new file mode 100644
index 0000000..5a12ff6
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IncrementalSAXSource.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/** <p>IncrementalSAXSource is an API that delivers a small number of
+ * SAX events each time a request is made from a "controller"
+ * coroutine.  See IncrementalSAXFilter and IncrementalSAXFilter_Xerces
+ * for examples.
+ * 
+ * Note that interaction is via the deliverMoreNodes
+ * method, and therefore coroutine support is not exposed
+ * here.</p>
+ * */
+public interface IncrementalSAXSource
+{
+  // ------------------------------------------------------------------
+  // SAX Output API
+  // ------------------------------------------------------------------
+
+  /** Register a SAX-style content handler for us to output to
+   */
+  public void setContentHandler(ContentHandler handler);
+
+  /**  Register a SAX-style lexical handler for us to output to
+   */
+  public void setLexicalHandler(org.xml.sax.ext.LexicalHandler handler);
+
+  /**  Register a SAX-style DTD handler for us to output to
+   */
+  public void setDTDHandler(org.xml.sax.DTDHandler handler);
+
+  // ------------------------------------------------------------------
+  // Command Input API
+  // ------------------------------------------------------------------
+
+  /** deliverMoreNodes() is a simple API which tells the thread in which the
+   * IncrementalSAXSource is running to deliver more events (true),
+   * or stop delivering events and close out its input (false).
+   *
+   * This is intended to be called from one of our partner coroutines,
+   * and serves to encapsulate the coroutine communication protocol.
+   *
+   * @param parsemore If true, tells the incremental SAX stream to deliver
+   * another chunk of events. If false, finishes out the stream.
+   *
+   * @return Boolean.TRUE if the IncrementalSAXSource believes more data
+   * may be available for further parsing. Boolean.FALSE if parsing
+   * ran to completion, or was ended by deliverMoreNodes(false).
+   * */
+  public Object deliverMoreNodes (boolean parsemore);
+
+  // ------------------------------------------------------------------
+  // Parse Thread Convenience API
+  // ------------------------------------------------------------------
+
+  /** Launch an XMLReader's parsing operation, feeding events to this
+   * IncrementalSAXSource. In some implementations, this may launch a
+   * thread which runs the previously supplied XMLReader's parse() operation.
+   * In others, it may do other forms of initialization.
+   *
+   * @throws SAXException is parse thread is already in progress
+   * or parsing can not be started.
+   * */
+  public void startParse(InputSource source) throws SAXException;
+    
+} // class IncrementalSAXSource
diff --git a/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource_Filter.java b/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource_Filter.java
new file mode 100644
index 0000000..7192094
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/IncrementalSAXSource_Filter.java
@@ -0,0 +1,807 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IncrementalSAXSource_Filter.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.IOException;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.utils.ThreadControllerWrapper;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+
+/** <p>IncrementalSAXSource_Filter implements IncrementalSAXSource, using a
+ * standard SAX2 event source as its input and parcelling out those
+ * events gradually in reponse to deliverMoreNodes() requests.  Output from the
+ * filter will be passed along to a SAX handler registered as our
+ * listener, but those callbacks will pass through a counting stage
+ * which periodically yields control back to the controller coroutine.
+ * </p>
+ *
+ * <p>%REVIEW%: This filter is not currenly intended to be reusable
+ * for parsing additional streams/documents. We may want to consider
+ * making it resettable at some point in the future. But it's a 
+ * small object, so that'd be mostly a convenience issue; the cost
+ * of allocating each time is trivial compared to the cost of processing
+ * any nontrival stream.</p>
+ *
+ * <p>For a brief usage example, see the unit-test main() method.</p>
+ *
+ * <p>This is a simplification of the old CoroutineSAXParser, focusing
+ * specifically on filtering. The resulting controller protocol is _far_
+ * simpler and less error-prone; the only controller operation is deliverMoreNodes(),
+ * and the only requirement is that deliverMoreNodes(false) be called if you want to
+ * discard the rest of the stream and the previous deliverMoreNodes() didn't return
+ * false.
+ * */
+public class IncrementalSAXSource_Filter
+implements IncrementalSAXSource, ContentHandler, DTDHandler, LexicalHandler, ErrorHandler, Runnable
+{
+  boolean DEBUG=false; //Internal status report
+
+  //
+  // Data
+  //
+  private CoroutineManager fCoroutineManager = null;
+  private int fControllerCoroutineID = -1;
+  private int fSourceCoroutineID = -1;
+
+  private ContentHandler clientContentHandler=null; // %REVIEW% support multiple?
+  private LexicalHandler clientLexicalHandler=null; // %REVIEW% support multiple?
+  private DTDHandler clientDTDHandler=null; // %REVIEW% support multiple?
+  private ErrorHandler clientErrorHandler=null; // %REVIEW% support multiple?
+  private int eventcounter;
+  private int frequency=5;
+
+  // Flag indicating that no more events should be delivered -- either
+  // because input stream ran to completion (endDocument), or because
+  // the user requested an early stop via deliverMoreNodes(false).
+  private boolean fNoMoreEvents=false;
+
+  // Support for startParse()
+  private XMLReader fXMLReader=null;
+  private InputSource fXMLReaderInputSource=null;
+
+  //
+  // Constructors
+  //
+
+  public IncrementalSAXSource_Filter() {
+    this.init( new CoroutineManager(), -1, -1);
+  }
+  
+  /** Create a IncrementalSAXSource_Filter which is not yet bound to a specific
+   * SAX event source.
+   * */
+  public IncrementalSAXSource_Filter(CoroutineManager co, int controllerCoroutineID)
+  {
+    this.init( co, controllerCoroutineID, -1 );
+  }
+
+  //
+  // Factories
+  //
+  static public IncrementalSAXSource createIncrementalSAXSource(CoroutineManager co, int controllerCoroutineID) {
+    return new IncrementalSAXSource_Filter(co, controllerCoroutineID);
+  }
+
+  //
+  // Public methods
+  //
+
+  public void init( CoroutineManager co, int controllerCoroutineID,
+                    int sourceCoroutineID)
+  {
+    if(co==null)
+      co = new CoroutineManager();
+    fCoroutineManager = co;
+    fControllerCoroutineID = co.co_joinCoroutineSet(controllerCoroutineID);
+    fSourceCoroutineID = co.co_joinCoroutineSet(sourceCoroutineID);
+    if (fControllerCoroutineID == -1 || fSourceCoroutineID == -1)
+      throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COJOINROUTINESET_FAILED, null)); //"co_joinCoroutineSet() failed");
+
+    fNoMoreEvents=false;
+    eventcounter=frequency;
+  }
+    
+  /** Bind our input streams to an XMLReader.
+   *
+   * Just a convenience routine; obviously you can explicitly register
+   * this as a listener with the same effect.
+   * */
+  public void setXMLReader(XMLReader eventsource)
+  {
+    fXMLReader=eventsource;
+    eventsource.setContentHandler(this);
+    eventsource.setDTDHandler(this);
+    eventsource.setErrorHandler(this); // to report fatal errors in filtering mode
+
+    // Not supported by all SAX2 filters:
+    try 
+    {
+      eventsource.
+        setProperty("http://xml.org/sax/properties/lexical-handler",
+                    this);
+    }
+    catch(SAXNotRecognizedException e)
+    {
+      // Nothing we can do about it
+    }
+    catch(SAXNotSupportedException e)
+    {
+      // Nothing we can do about it
+    }
+
+    // Should we also bind as other varieties of handler?
+    // (DTDHandler and so on)
+  }
+
+  // Register a content handler for us to output to
+  public void setContentHandler(ContentHandler handler)
+  {
+    clientContentHandler=handler;
+  }
+  // Register a DTD handler for us to output to
+  public void setDTDHandler(DTDHandler handler)
+  {
+    clientDTDHandler=handler;
+  }
+  // Register a lexical handler for us to output to
+  // Not all filters support this...
+  // ??? Should we register directly on the filter?
+  // NOTE NAME -- subclassing issue in the Xerces version
+  public void setLexicalHandler(LexicalHandler handler)
+  {
+    clientLexicalHandler=handler;
+  }
+  // Register an error handler for us to output to
+  // NOTE NAME -- subclassing issue in the Xerces version
+  public void setErrHandler(ErrorHandler handler)
+  {
+    clientErrorHandler=handler;
+  }
+
+  // Set the number of events between resumes of our coroutine
+  // Immediately resets number of events before _next_ resume as well.
+  public void setReturnFrequency(int events)
+  {
+    if(events<1) events=1;
+    frequency=eventcounter=events;
+  }
+  
+  //
+  // ContentHandler methods
+  // These  pass the data to our client ContentHandler...
+  // but they also count the number of events passing through,
+  // and resume our coroutine each time that counter hits zero and
+  // is reset.
+  //
+  // Note that for everything except endDocument and fatalError, we do the count-and-yield
+  // BEFORE passing the call along. I'm hoping that this will encourage JIT
+  // compilers to realize that these are tail-calls, reducing the expense of
+  // the additional layer of data flow.
+  //
+  // %REVIEW% Glenn suggests that pausing after endElement, endDocument,
+  // and characters may be sufficient. I actually may not want to
+  // stop after characters, since in our application these wind up being
+  // concatenated before they're processed... but that risks huge blocks of
+  // text causing greater than usual readahead. (Unlikely? Consider the
+  // possibility of a large base-64 block in a SOAP stream.)
+  //
+  public void characters(char[] ch, int start, int length)
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.characters(ch,start,length);
+  }
+  public void endDocument() 
+       throws org.xml.sax.SAXException
+  {
+    // EXCEPTION: In this case we need to run the event BEFORE we yield.
+    if(clientContentHandler!=null)
+      clientContentHandler.endDocument();
+
+    eventcounter=0;     
+    co_yield(false);
+  }
+  public void endElement(java.lang.String namespaceURI, java.lang.String localName,
+      java.lang.String qName) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.endElement(namespaceURI,localName,qName);
+  }
+  public void endPrefixMapping(java.lang.String prefix) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.endPrefixMapping(prefix);
+  }
+  public void ignorableWhitespace(char[] ch, int start, int length) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.ignorableWhitespace(ch,start,length);
+  }
+  public void processingInstruction(java.lang.String target, java.lang.String data) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.processingInstruction(target,data);
+  }
+  public void setDocumentLocator(Locator locator) 
+  {
+    if(--eventcounter<=0)
+      {
+        // This can cause a hang.  -sb
+        // co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.setDocumentLocator(locator);
+  }
+  public void skippedEntity(java.lang.String name) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.skippedEntity(name);
+  }
+  public void startDocument() 
+       throws org.xml.sax.SAXException
+  {
+    co_entry_pause();
+
+    // Otherwise, begin normal event delivery
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.startDocument();
+  }
+  public void startElement(java.lang.String namespaceURI, java.lang.String localName,
+      java.lang.String qName, Attributes atts) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.startElement(namespaceURI, localName, qName, atts);
+  }
+  public void startPrefixMapping(java.lang.String prefix, java.lang.String uri) 
+       throws org.xml.sax.SAXException
+  {
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+    if(clientContentHandler!=null)
+      clientContentHandler.startPrefixMapping(prefix,uri);
+  }
+
+  //
+  // LexicalHandler support. Not all SAX2 filters support these events
+  // but we may want to pass them through when they exist...
+  //
+  // %REVIEW% These do NOT currently affect the eventcounter; I'm asserting
+  // that they're rare enough that it makes little or no sense to
+  // pause after them. As such, it may make more sense for folks who
+  // actually want to use them to register directly with the filter.
+  // But I want 'em here for now, to remind us to recheck this assertion!
+  //
+  public void comment(char[] ch, int start, int length) 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.comment(ch,start,length);
+  }
+  public void endCDATA() 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.endCDATA();
+  }
+  public void endDTD() 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.endDTD();
+  }
+  public void endEntity(java.lang.String name) 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.endEntity(name);
+  }
+  public void startCDATA() 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.startCDATA();
+  }
+  public void startDTD(java.lang.String name, java.lang.String publicId,
+      java.lang.String systemId) 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler. startDTD(name, publicId, systemId);
+  }
+  public void startEntity(java.lang.String name) 
+       throws org.xml.sax.SAXException
+  {
+    if(null!=clientLexicalHandler)
+      clientLexicalHandler.startEntity(name);
+  }
+
+  //
+  // DTDHandler support.
+  
+  public void notationDecl(String a, String b, String c) throws SAXException
+  {
+  	if(null!=clientDTDHandler)
+	  	clientDTDHandler.notationDecl(a,b,c);
+  }
+  public void unparsedEntityDecl(String a, String b, String c, String d)  throws SAXException
+  {
+  	if(null!=clientDTDHandler)
+	  	clientDTDHandler.unparsedEntityDecl(a,b,c,d);
+  }
+  
+  //
+  // ErrorHandler support.
+  //
+  // PROBLEM: Xerces is apparently _not_ calling the ErrorHandler for
+  // exceptions thrown by the ContentHandler, which prevents us from
+  // handling this properly when running in filtering mode with Xerces
+  // as our event source.  It's unclear whether this is a Xerces bug
+  // or a SAX design flaw.
+  // 
+  // %REVIEW% Current solution: In filtering mode, it is REQUIRED that
+  // event source make sure this method is invoked if the event stream
+  // abends before endDocument is delivered. If that means explicitly calling
+  // us in the exception handling code because it won't be delivered as part
+  // of the normal SAX ErrorHandler stream, that's fine; Not Our Problem.
+  //
+  public void error(SAXParseException exception) throws SAXException
+  {
+    if(null!=clientErrorHandler)
+      clientErrorHandler.error(exception);
+  }
+  
+  public void fatalError(SAXParseException exception) throws SAXException
+  {
+    // EXCEPTION: In this case we need to run the event BEFORE we yield --
+    // just as with endDocument, this terminates the event stream.
+    if(null!=clientErrorHandler)
+      clientErrorHandler.error(exception);
+
+    eventcounter=0;     
+    co_yield(false);
+
+  }
+  
+  public void warning(SAXParseException exception) throws SAXException
+  {
+    if(null!=clientErrorHandler)
+      clientErrorHandler.error(exception);
+  }
+  
+
+  //
+  // coroutine support
+  //
+
+  public int getSourceCoroutineID() {
+    return fSourceCoroutineID;
+  }
+  public int getControllerCoroutineID() {
+    return fControllerCoroutineID;
+  }
+
+  /** @return the CoroutineManager this CoroutineFilter object is bound to.
+   * If you're using the do...() methods, applications should only
+   * need to talk to the CoroutineManager once, to obtain the
+   * application's Coroutine ID.
+   * */
+  public CoroutineManager getCoroutineManager()
+  {
+    return fCoroutineManager;
+  }
+
+  /** <p>In the SAX delegation code, I've inlined the count-down in
+   * the hope of encouraging compilers to deliver better
+   * performance. However, if we subclass (eg to directly connect the
+   * output to a DTM builder), that would require calling super in
+   * order to run that logic... which seems inelegant.  Hence this
+   * routine for the convenience of subclasses: every [frequency]
+   * invocations, issue a co_yield.</p>
+   *
+   * @param moreExepected Should always be true unless this is being called
+   * at the end of endDocument() handling.
+   * */
+  protected void count_and_yield(boolean moreExpected) throws SAXException
+  {
+    if(!moreExpected) eventcounter=0;
+    
+    if(--eventcounter<=0)
+      {
+        co_yield(true);
+        eventcounter=frequency;
+      }
+  }
+
+  /**
+   * co_entry_pause is called in startDocument() before anything else
+   * happens. It causes the filter to wait for a "go ahead" request
+   * from the controller before delivering any events. Note that
+   * the very first thing the controller tells us may be "I don't
+   * need events after all"!
+   */
+  private void co_entry_pause() throws SAXException
+  {
+    if(fCoroutineManager==null)
+    {
+      // Nobody called init()? Do it now...
+      init(null,-1,-1);
+    }
+
+    try
+    {
+      Object arg=fCoroutineManager.co_entry_pause(fSourceCoroutineID);
+      if(arg==Boolean.FALSE)
+        co_yield(false);
+    }
+    catch(NoSuchMethodException e)
+    {
+      // Coroutine system says we haven't registered. That's an
+      // application coding error, and is unrecoverable.
+      if(DEBUG) e.printStackTrace();
+      throw new SAXException(e);
+    }
+  }
+
+  /**
+   * Co_Yield handles coroutine interactions while a parse is in progress.
+   *
+   * When moreRemains==true, we are pausing after delivering events, to
+   * ask if more are needed. We will resume the controller thread with 
+   *   co_resume(Boolean.TRUE, ...)
+   * When control is passed back it may indicate
+   *      Boolean.TRUE    indication to continue delivering events
+   *      Boolean.FALSE   indication to discontinue events and shut down.
+   * 
+   * When moreRemains==false, we shut down immediately without asking the
+   * controller's permission. Normally this means end of document has been
+   * reached.
+   *
+   * Shutting down a IncrementalSAXSource_Filter requires terminating the incoming
+   * SAX event stream. If we are in control of that stream (if it came
+   * from an XMLReader passed to our startReader() method), we can do so
+   * very quickly by throwing a reserved exception to it. If the stream is
+   * coming from another source, we can't do that because its caller may
+   * not be prepared for this "normal abnormal exit", and instead we put
+   * ourselves in a "spin" mode where events are discarded.
+   */
+  private void co_yield(boolean moreRemains) throws SAXException
+  {
+    // Horrendous kluge to run filter to completion. See below.
+    if(fNoMoreEvents)
+      return;
+
+    try // Coroutine manager might throw no-such.
+    {
+      Object arg=Boolean.FALSE;
+      if(moreRemains)
+      {
+        // Yield control, resume parsing when done
+        arg = fCoroutineManager.co_resume(Boolean.TRUE, fSourceCoroutineID,
+                                          fControllerCoroutineID);
+        
+      }
+
+      // If we're at end of document or were told to stop early
+      if(arg==Boolean.FALSE)
+      {
+        fNoMoreEvents=true;
+        
+        if(fXMLReader!=null)    // Running under startParseThread()
+          throw new StopException(); // We'll co_exit from there.
+        
+        // Yield control. We do NOT expect anyone to ever ask us again.
+        fCoroutineManager.co_exit_to(Boolean.FALSE, fSourceCoroutineID,
+                                     fControllerCoroutineID);
+      }
+    }
+    catch(NoSuchMethodException e)
+    {
+      // Shouldn't happen unless we've miscoded our coroutine logic
+      // "Shut down the garbage smashers on the detention level!"
+      fNoMoreEvents=true;
+      fCoroutineManager.co_exit(fSourceCoroutineID);
+      throw new SAXException(e);
+    }
+  }
+
+  //
+  // Convenience: Run an XMLReader in a thread
+  //
+
+  /** Launch a thread that will run an XMLReader's parse() operation within
+   *  a thread, feeding events to this IncrementalSAXSource_Filter. Mostly a convenience
+   *  routine, but has the advantage that -- since we invoked parse() --
+   *  we can halt parsing quickly via a StopException rather than waiting
+   *  for the SAX stream to end by itself.
+   *
+   * @throws SAXException is parse thread is already in progress
+   * or parsing can not be started.
+   * */
+  public void startParse(InputSource source) throws SAXException
+  {
+    if(fNoMoreEvents)
+      throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INCRSAXSRCFILTER_NOT_RESTARTABLE, null)); //"IncrmentalSAXSource_Filter not currently restartable.");
+    if(fXMLReader==null)
+      throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_XMLRDR_NOT_BEFORE_STARTPARSE, null)); //"XMLReader not before startParse request");
+
+    fXMLReaderInputSource=source;
+    
+    // Xalan thread pooling...
+    // org.apache.xalan.transformer.TransformerImpl.runTransformThread(this);
+    ThreadControllerWrapper.runThread(this, -1);
+  }
+  
+  /* Thread logic to support startParseThread()
+   */
+  public void run()
+  {
+    // Guard against direct invocation of start().
+    if(fXMLReader==null) return;
+
+    if(DEBUG)System.out.println("IncrementalSAXSource_Filter parse thread launched");
+
+    // Initially assume we'll run successfully.
+    Object arg=Boolean.FALSE;
+
+    // For the duration of this operation, all coroutine handshaking
+    // will occur in the co_yield method. That's the nice thing about
+    // coroutines; they give us a way to hand off control from the
+    // middle of a synchronous method.
+    try
+    {
+      fXMLReader.parse(fXMLReaderInputSource);
+    }
+    catch(IOException ex)
+    {
+      arg=ex;
+    }
+    catch(StopException ex)
+    {
+      // Expected and harmless
+      if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception");
+    }
+    catch (SAXException ex)
+    {
+      Exception inner=ex.getException();
+      if(inner instanceof StopException){
+        // Expected and harmless
+        if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception");
+      }
+      else
+      {
+        // Unexpected malfunction
+        if(DEBUG)
+        {
+          System.out.println("Active IncrementalSAXSource_Filter UNEXPECTED SAX exception: "+inner);
+          inner.printStackTrace();
+        }                
+        arg=ex;
+      }
+    } // end parse
+    
+    // Mark as no longer running in thread.
+    fXMLReader=null;
+
+    try
+    {
+      // Mark as done and yield control to the controller coroutine
+      fNoMoreEvents=true;
+      fCoroutineManager.co_exit_to(arg, fSourceCoroutineID,
+                                   fControllerCoroutineID);
+    }
+    catch(java.lang.NoSuchMethodException e)
+    {
+      // Shouldn't happen unless we've miscoded our coroutine logic
+      // "CPO, shut down the garbage smashers on the detention level!"
+      e.printStackTrace(System.err);
+      fCoroutineManager.co_exit(fSourceCoroutineID);
+    }
+  }
+
+  /** Used to quickly terminate parse when running under a
+      startParse() thread. Only its type is important. */
+  class StopException extends RuntimeException
+  {
+          static final long serialVersionUID = -1129245796185754956L;
+  }
+
+  /** deliverMoreNodes() is a simple API which tells the coroutine
+   * parser that we need more nodes.  This is intended to be called
+   * from one of our partner routines, and serves to encapsulate the
+   * details of how incremental parsing has been achieved.
+   *
+   * @param parsemore If true, tells the incremental filter to generate
+   * another chunk of output. If false, tells the filter that we're
+   * satisfied and it can terminate parsing of this document.
+   *
+   * @return Boolean.TRUE if there may be more events available by invoking
+   * deliverMoreNodes() again. Boolean.FALSE if parsing has run to completion (or been
+   * terminated by deliverMoreNodes(false). Or an exception object if something
+   * malfunctioned. %REVIEW% We _could_ actually throw the exception, but
+   * that would require runinng deliverMoreNodes() in a try/catch... and for many
+   * applications, exception will be simply be treated as "not TRUE" in
+   * any case.
+   * */
+  public Object deliverMoreNodes(boolean parsemore)
+  {
+    // If parsing is already done, we can immediately say so
+    if(fNoMoreEvents)
+      return Boolean.FALSE;
+
+    try 
+    {
+      Object result =
+        fCoroutineManager.co_resume(parsemore?Boolean.TRUE:Boolean.FALSE,
+                                    fControllerCoroutineID, fSourceCoroutineID);
+      if(result==Boolean.FALSE)
+        fCoroutineManager.co_exit(fControllerCoroutineID);
+
+      return result;
+    }
+      
+    // SHOULD NEVER OCCUR, since the coroutine number and coroutine manager
+    // are those previously established for this IncrementalSAXSource_Filter...
+    // So I'm just going to return it as a parsing exception, for now.
+    catch(NoSuchMethodException e)
+      {
+        return e;
+      }
+  }
+  
+
+  //================================================================
+  /** Simple unit test. Attempt coroutine parsing of document indicated
+   * by first argument (as a URI), report progress.
+   */
+    /*
+  public static void main(String args[])
+  {
+    System.out.println("Starting...");
+
+    org.xml.sax.XMLReader theSAXParser=
+      new org.apache.xerces.parsers.SAXParser();
+  
+
+    for(int arg=0;arg<args.length;++arg)
+    {
+      // The filter is not currently designed to be restartable
+      // after a parse has ended. Generate a new one each time.
+      IncrementalSAXSource_Filter filter=
+        new IncrementalSAXSource_Filter();
+      // Use a serializer as our sample output
+      org.apache.xml.serialize.XMLSerializer trace;
+      trace=new org.apache.xml.serialize.XMLSerializer(System.out,null);
+      filter.setContentHandler(trace);
+      filter.setLexicalHandler(trace);
+
+      try
+      {
+        InputSource source = new InputSource(args[arg]);
+        Object result=null;
+        boolean more=true;
+
+        // init not issued; we _should_ automagically Do The Right Thing
+
+        // Bind parser, kick off parsing in a thread
+        filter.setXMLReader(theSAXParser);
+        filter.startParse(source);
+      
+        for(result = filter.deliverMoreNodes(more);
+            (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
+            result = filter.deliverMoreNodes(more))
+        {
+          System.out.println("\nSome parsing successful, trying more.\n");
+          
+          // Special test: Terminate parsing early.
+          if(arg+1<args.length && "!".equals(args[arg+1]))
+          {
+            ++arg;
+            more=false;
+          }
+          
+        }
+      
+        if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE)
+        {
+          System.out.println("\nFilter ended (EOF or on request).\n");
+        }
+        else if (result == null) {
+          System.out.println("\nUNEXPECTED: Filter says shut down prematurely.\n");
+        }
+        else if (result instanceof Exception) {
+          System.out.println("\nFilter threw exception:");
+          ((Exception)result).printStackTrace();
+        }
+      
+      }
+      catch(SAXException e)
+      {
+        e.printStackTrace();
+      }
+    } // end for
+  }
+    */  
+} // class IncrementalSAXSource_Filter
diff --git a/src/main/java/org/apache/xml/dtm/ref/NodeLocator.java b/src/main/java/org/apache/xml/dtm/ref/NodeLocator.java
new file mode 100644
index 0000000..c5fd89b
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/NodeLocator.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeLocator.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import javax.xml.transform.SourceLocator;
+
+/**
+ * <code>NodeLocator</code> maintains information on an XML source
+ * node.
+ *
+ * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
+ * @since May 23, 2001
+ */
+public class NodeLocator implements SourceLocator
+{
+  protected String m_publicId;
+  protected String m_systemId;
+  protected int m_lineNumber;
+  protected int m_columnNumber;
+
+  /**
+   * Creates a new <code>NodeLocator</code> instance.
+   *
+   * @param publicId a <code>String</code> value
+   * @param systemId a <code>String</code> value
+   * @param lineNumber an <code>int</code> value
+   * @param columnNumber an <code>int</code> value
+   */
+  public NodeLocator(String publicId, String systemId,
+                     int lineNumber, int columnNumber)
+  {
+    this.m_publicId = publicId;
+    this.m_systemId = systemId;
+    this.m_lineNumber = lineNumber;
+    this.m_columnNumber = columnNumber;
+  }
+
+  /**
+   * <code>getPublicId</code> returns the public ID of the node.
+   *
+   * @return a <code>String</code> value
+   */
+  public String getPublicId()
+  {
+    return m_publicId;
+  }
+
+  /**
+   * <code>getSystemId</code> returns the system ID of the node.
+   *
+   * @return a <code>String</code> value
+   */
+  public String getSystemId()
+  {
+    return m_systemId;
+  }
+
+  /**
+   * <code>getLineNumber</code> returns the line number of the node.
+   *
+   * @return an <code>int</code> value
+   */
+  public int getLineNumber()
+  {
+    return m_lineNumber;
+  }
+
+  /**
+   * <code>getColumnNumber</code> returns the column number of the
+   * node.
+   *
+   * @return an <code>int</code> value
+   */
+  public int getColumnNumber()
+  {
+    return m_columnNumber;
+  }
+
+  /**
+   * <code>toString</code> returns a string representation of this
+   * NodeLocator instance.
+   *
+   * @return a <code>String</code> value
+   */
+  public String toString()
+  {
+    return "file '" + m_systemId
+      + "', line #" + m_lineNumber
+      + ", column #" + m_columnNumber;
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/SecuritySupport.java b/src/main/java/org/apache/xml/dtm/ref/SecuritySupport.java
new file mode 100755
index 0000000..0dd7ac4
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/SecuritySupport.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/SecuritySupport12.java b/src/main/java/org/apache/xml/dtm/ref/SecuritySupport12.java
new file mode 100755
index 0000000..e70c91b
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/SecuritySupport12.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport12.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java b/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java
new file mode 100644
index 0000000..2c376a0
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java
@@ -0,0 +1,1766 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOM2DTM.java 478671 2006-11-23 21:00:31Z minchau $
+ */
+package org.apache.xml.dtm.ref.dom2dtm;
+
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.dom.DOMSource;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.dtm.ref.DTMDefaultBaseIterators;
+import org.apache.xml.dtm.ref.DTMManagerDefault;
+import org.apache.xml.dtm.ref.ExpandedNameTable;
+import org.apache.xml.dtm.ref.IncrementalSAXSource;
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.StringBufferPool;
+import org.apache.xml.utils.TreeWalker;
+import org.apache.xml.utils.XMLCharacterRecognizer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Entity;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+
+/** The <code>DOM2DTM</code> class serves up a DOM's contents via the
+ * DTM API.
+ *
+ * Note that it doesn't necessarily represent a full Document
+ * tree. You can wrap a DOM2DTM around a specific node and its subtree
+ * and the right things should happen. (I don't _think_ we currently
+ * support DocumentFrgment nodes as roots, though that might be worth
+ * considering.)
+ *
+ * Note too that we do not currently attempt to track document
+ * mutation. If you alter the DOM after wrapping DOM2DTM around it,
+ * all bets are off.
+ * */
+public class DOM2DTM extends DTMDefaultBaseIterators
+{
+  static final boolean JJK_DEBUG=false;
+  static final boolean JJK_NEWCODE=true;
+  
+  /** Manefest constant
+   */
+  static final String NAMESPACE_DECL_NS="http://www.w3.org/XML/1998/namespace";
+  
+  /** The current position in the DOM tree. Last node examined for
+   * possible copying to DTM. */
+  transient private Node m_pos;
+  /** The current position in the DTM tree. Who children get appended to. */
+  private int m_last_parent=0;
+  /** The current position in the DTM tree. Who children reference as their 
+   * previous sib. */
+  private int m_last_kid=NULL;
+
+  /** The top of the subtree.
+   * %REVIEW%: 'may not be the same as m_context if "//foo" pattern.'
+   * */
+  transient private Node m_root;
+
+  /** True iff the first element has been processed. This is used to control
+      synthesis of the implied xml: namespace declaration node. */
+  boolean m_processedFirstElement=false;
+        
+  /** true if ALL the nodes in the m_root subtree have been processed;
+   * false if our incremental build has not yet finished scanning the
+   * DOM tree.  */
+  transient private boolean m_nodesAreProcessed;
+
+  /** The node objects.  The instance part of the handle indexes
+   * directly into this vector.  Each DTM node may actually be
+   * composed of several DOM nodes (for example, if logically-adjacent
+   * Text/CDATASection nodes in the DOM have been coalesced into a
+   * single DTM Text node); this table points only to the first in
+   * that sequence. */
+  protected Vector m_nodes = new Vector();
+
+  /**
+   * Construct a DOM2DTM object from a DOM node.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param domSource the DOM source that this DTM will wrap.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may 
+   *                         be null.
+   * @param xstringfactory XMLString factory for creating character content.
+   * @param doIndexing true if the caller considers it worth it to use 
+   *                   indexing schemes.
+   */
+  public DOM2DTM(DTMManager mgr, DOMSource domSource, 
+                 int dtmIdentity, DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing)
+  {
+    super(mgr, domSource, dtmIdentity, whiteSpaceFilter, 
+          xstringfactory, doIndexing);
+
+    // Initialize DOM navigation
+    m_pos=m_root = domSource.getNode();
+    // Initialize DTM navigation
+    m_last_parent=m_last_kid=NULL;
+    m_last_kid=addNode(m_root, m_last_parent,m_last_kid, NULL);
+
+    // Apparently the domSource root may not actually be the
+    // Document node. If it's an Element node, we need to immediately
+    // add its attributes. Adapted from nextNode().
+    // %REVIEW% Move this logic into addNode and recurse? Cleaner!
+    //
+    // (If it's an EntityReference node, we're probably in 
+    // seriously bad trouble. For now
+    // I'm just hoping nobody is ever quite that foolish... %REVIEW%)
+		//
+		// %ISSUE% What about inherited namespaces in this case?
+		// Do we need to special-case initialize them into the DTM model?
+    if(ELEMENT_NODE == m_root.getNodeType())
+    {
+      NamedNodeMap attrs=m_root.getAttributes();
+      int attrsize=(attrs==null) ? 0 : attrs.getLength();
+      if(attrsize>0)
+      {
+        int attrIndex=NULL; // start with no previous sib
+        for(int i=0;i<attrsize;++i)
+        {
+          // No need to force nodetype in this case;
+          // addNode() will take care of switching it from
+          // Attr to Namespace if necessary.
+          attrIndex=addNode(attrs.item(i),0,attrIndex,NULL);
+          m_firstch.setElementAt(DTM.NULL,attrIndex);
+        }
+        // Terminate list of attrs, and make sure they aren't
+        // considered children of the element
+        m_nextsib.setElementAt(DTM.NULL,attrIndex);
+
+        // IMPORTANT: This does NOT change m_last_parent or m_last_kid!
+      } // if attrs exist
+    } //if(ELEMENT_NODE)
+
+    // Initialize DTM-completed status 
+    m_nodesAreProcessed = false;
+  }
+
+  /**
+   * Construct the node map from the node.
+   *
+   * @param node The node that is to be added to the DTM.
+   * @param parentIndex The current parent index.
+   * @param previousSibling The previous sibling index.
+   * @param forceNodeType If not DTM.NULL, overrides the DOM node type.
+   *	Used to force nodes to Text rather than CDATASection when their
+   *	coalesced value includes ordinary Text nodes (current DTM behavior).
+   *
+   * @return The index identity of the node that was added.
+   */
+  protected int addNode(Node node, int parentIndex,
+                        int previousSibling, int forceNodeType)
+  {
+    int nodeIndex = m_nodes.size();
+
+    // Have we overflowed a DTM Identity's addressing range?
+    if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
+    {
+      try
+      {
+        if(m_mgr==null)
+          throw new ClassCastException();
+                                
+                                // Handle as Extended Addressing
+        DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr;
+        int id=mgrD.getFirstFreeDTMID();
+        mgrD.addDTM(this,id,nodeIndex);
+        m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS);
+      }
+      catch(ClassCastException e)
+      {
+        // %REVIEW% Wrong error message, but I've been told we're trying
+        // not to add messages right not for I18N reasons.
+        // %REVIEW% Should this be a Fatal Error?
+        error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null));//"No more DTM IDs are available";
+      }
+    }
+
+    m_size++;
+    // ensureSize(nodeIndex);
+    
+    int type;
+    if(NULL==forceNodeType)
+        type = node.getNodeType();
+    else
+        type=forceNodeType;
+        
+    // %REVIEW% The Namespace Spec currently says that Namespaces are
+    // processed in a non-namespace-aware manner, by matching the
+    // QName, even though there is in fact a namespace assigned to
+    // these nodes in the DOM. If and when that changes, we will have
+    // to consider whether we check the namespace-for-namespaces
+    // rather than the node name.
+    //
+    // %TBD% Note that the DOM does not necessarily explicitly declare
+    // all the namespaces it uses. DOM Level 3 will introduce a
+    // namespace-normalization operation which reconciles that, and we
+    // can request that users invoke it or otherwise ensure that the
+    // tree is namespace-well-formed before passing the DOM to Xalan.
+    // But if they don't, what should we do about it? We probably
+    // don't want to alter the source DOM (and may not be able to do
+    // so if it's read-only). The best available answer might be to
+    // synthesize additional DTM Namespace Nodes that don't correspond
+    // to DOM Attr Nodes.
+    if (Node.ATTRIBUTE_NODE == type)
+    {
+      String name = node.getNodeName();
+
+      if (name.startsWith("xmlns:") || name.equals("xmlns"))
+      {
+        type = DTM.NAMESPACE_NODE;
+      }
+    }
+    
+    m_nodes.addElement(node);
+    
+    m_firstch.setElementAt(NOTPROCESSED,nodeIndex);
+    m_nextsib.setElementAt(NOTPROCESSED,nodeIndex);
+    m_prevsib.setElementAt(previousSibling,nodeIndex);
+    m_parent.setElementAt(parentIndex,nodeIndex);
+    
+    if(DTM.NULL != parentIndex && 
+       type != DTM.ATTRIBUTE_NODE && 
+       type != DTM.NAMESPACE_NODE)
+    {
+      // If the DTM parent had no children, this becomes its first child.
+      if(NOTPROCESSED == m_firstch.elementAt(parentIndex))
+        m_firstch.setElementAt(nodeIndex,parentIndex);
+    }
+    
+    String nsURI = node.getNamespaceURI();
+
+    // Deal with the difference between Namespace spec and XSLT
+    // definitions of local name. (The former says PIs don't have
+    // localnames; the latter says they do.)
+    String localName =  (type == Node.PROCESSING_INSTRUCTION_NODE) ? 
+                         node.getNodeName() :
+                         node.getLocalName();
+                         
+    // Hack to make DOM1 sort of work...
+    if(((type == Node.ELEMENT_NODE) || (type == Node.ATTRIBUTE_NODE)) 
+        && null == localName)
+      localName = node.getNodeName(); // -sb
+      
+    ExpandedNameTable exnt = m_expandedNameTable;
+
+    // %TBD% Nodes created with the old non-namespace-aware DOM
+    // calls createElement() and createAttribute() will never have a
+    // localname. That will cause their expandedNameID to be just the
+    // nodeType... which will keep them from being matched
+    // successfully by name. Since the DOM makes no promise that
+    // those will participate in namespace processing, this is
+    // officially accepted as Not Our Fault. But it might be nice to
+    // issue a diagnostic message!
+    if(node.getLocalName()==null &&
+       (type==Node.ELEMENT_NODE || type==Node.ATTRIBUTE_NODE))
+      {
+        // warning("DOM 'level 1' node "+node.getNodeName()+" won't be mapped properly in DOM2DTM.");
+      }
+    
+    int expandedNameID = (null != localName) 
+       ? exnt.getExpandedTypeID(nsURI, localName, type) :
+         exnt.getExpandedTypeID(type);
+
+    m_exptype.setElementAt(expandedNameID,nodeIndex);
+    
+    indexNode(expandedNameID, nodeIndex);
+
+    if (DTM.NULL != previousSibling)
+      m_nextsib.setElementAt(nodeIndex,previousSibling);
+
+    // This should be done after m_exptype has been set, and probably should
+    // always be the last thing we do
+    if (type == DTM.NAMESPACE_NODE)
+        declareNamespaceInContext(parentIndex,nodeIndex);
+
+    return nodeIndex;
+  }
+  
+  /**
+   * Get the number of nodes that have been added.
+   */
+  public int getNumberOfNodes()
+  {
+    return m_nodes.size();
+  }
+  
+ /**
+   * This method iterates to the next node that will be added to the table.
+   * Each call to this method adds a new node to the table, unless the end
+   * is reached, in which case it returns null.
+   *
+   * @return The true if a next node is found or false if 
+   *         there are no more nodes.
+   */
+  protected boolean nextNode()
+  {
+    // Non-recursive one-fetch-at-a-time depth-first traversal with 
+    // attribute/namespace nodes and white-space stripping.
+    // Navigating the DOM is simple, navigating the DTM is simple;
+    // keeping track of both at once is a trifle baroque but at least
+    // we've avoided most of the special cases.
+    if (m_nodesAreProcessed)
+      return false;
+        
+    // %REVIEW% Is this local copy Really Useful from a performance
+    // point of view?  Or is this a false microoptimization?
+    Node pos=m_pos; 
+    Node next=null;
+    int nexttype=NULL;
+
+    // Navigate DOM tree
+    do
+      {
+        // Look down to first child.
+        if (pos.hasChildNodes()) 
+          {
+            next = pos.getFirstChild();
+
+            // %REVIEW% There's probably a more elegant way to skip
+            // the doctype. (Just let it go and Suppress it?
+            if(next!=null && DOCUMENT_TYPE_NODE==next.getNodeType())
+              next=next.getNextSibling();
+
+            // Push DTM context -- except for children of Entity References, 
+            // which have no DTM equivalent and cause no DTM navigation.
+            if(ENTITY_REFERENCE_NODE!=pos.getNodeType())
+              {
+                m_last_parent=m_last_kid;
+                m_last_kid=NULL;
+                // Whitespace-handler context stacking
+                if(null != m_wsfilter)
+                {
+                  short wsv =
+                    m_wsfilter.getShouldStripSpace(makeNodeHandle(m_last_parent),this);
+                  boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) 
+                    ? getShouldStripWhitespace() 
+                    : (DTMWSFilter.STRIP == wsv);
+                  pushShouldStripWhitespace(shouldStrip);
+                } // if(m_wsfilter)
+              }
+          }
+
+        // If that fails, look up and right (but not past root!)
+        else 
+          {
+            if(m_last_kid!=NULL)
+              {
+                // Last node posted at this level had no more children
+                // If it has _no_ children, we need to record that.
+                if(m_firstch.elementAt(m_last_kid)==NOTPROCESSED)
+                  m_firstch.setElementAt(NULL,m_last_kid);
+              }
+                        
+            while(m_last_parent != NULL)
+              {
+                // %REVIEW% There's probably a more elegant way to
+                // skip the doctype. (Just let it go and Suppress it?
+                next = pos.getNextSibling();
+                if(next!=null && DOCUMENT_TYPE_NODE==next.getNodeType())
+                  next=next.getNextSibling();
+
+                if(next!=null)
+                  break; // Found it!
+                
+                // No next-sibling found. Pop the DOM.
+                pos=pos.getParentNode();
+                if(pos==null)
+                  {
+                    // %TBD% Should never arise, but I want to be sure of that...
+                    if(JJK_DEBUG)
+                      {
+                        System.out.println("***** DOM2DTM Pop Control Flow problem");
+                        for(;;); // Freeze right here!
+                      }
+                  }
+                
+                // The only parents in the DTM are Elements.  However,
+                // the DOM could contain EntityReferences.  If we
+                // encounter one, pop it _without_ popping DTM.
+                if(pos!=null && ENTITY_REFERENCE_NODE == pos.getNodeType())
+                  {
+                    // Nothing needs doing
+                    if(JJK_DEBUG)
+                      System.out.println("***** DOM2DTM popping EntRef");
+                  }
+                else
+                  {
+                    popShouldStripWhitespace();
+                    // Fix and pop DTM
+                    if(m_last_kid==NULL)
+                      m_firstch.setElementAt(NULL,m_last_parent); // Popping from an element
+                    else
+                      m_nextsib.setElementAt(NULL,m_last_kid); // Popping from anything else
+                    m_last_parent=m_parent.elementAt(m_last_kid=m_last_parent);
+                  }
+              }
+            if(m_last_parent==NULL)
+              next=null;
+          }
+                
+        if(next!=null)
+          nexttype=next.getNodeType();
+                
+        // If it's an entity ref, advance past it.
+        //
+        // %REVIEW% Should we let this out the door and just suppress it?
+        // More work, but simpler code, more likely to be correct, and
+        // it doesn't happen very often. We'd get rid of the loop too.
+        if (ENTITY_REFERENCE_NODE == nexttype)
+          pos=next;
+      }
+    while (ENTITY_REFERENCE_NODE == nexttype); 
+        
+    // Did we run out of the tree?
+    if(next==null)
+      {
+        m_nextsib.setElementAt(NULL,0);
+        m_nodesAreProcessed = true;
+        m_pos=null;
+                
+        if(JJK_DEBUG)
+          {
+            System.out.println("***** DOM2DTM Crosscheck:");
+            for(int i=0;i<m_nodes.size();++i)
+              System.out.println(i+":\t"+m_firstch.elementAt(i)+"\t"+m_nextsib.elementAt(i));
+          }
+                
+        return false;
+      }
+
+    // Text needs some special handling:
+    //
+    // DTM may skip whitespace. This is handled by the suppressNode flag, which
+    // when true will keep the DTM node from being created.
+    //
+    // DTM only directly records the first DOM node of any logically-contiguous
+    // sequence. The lastTextNode value will be set to the last node in the 
+    // contiguous sequence, and -- AFTER the DTM addNode -- can be used to 
+    // advance next over this whole block. Should be simpler than special-casing
+    // the above loop for "Was the logically-preceeding sibling a text node".
+    // 
+    // Finally, a DTM node should be considered a CDATASection only if all the
+    // contiguous text it covers is CDATASections. The first Text should
+    // force DTM to Text.
+        
+    boolean suppressNode=false;
+    Node lastTextNode=null;
+
+    nexttype=next.getNodeType();
+        
+    // nexttype=pos.getNodeType();
+    if(TEXT_NODE == nexttype || CDATA_SECTION_NODE == nexttype)
+      {
+        // If filtering, initially assume we're going to suppress the node
+        suppressNode=((null != m_wsfilter) && getShouldStripWhitespace());
+
+        // Scan logically contiguous text (siblings, plus "flattening"
+        // of entity reference boundaries).
+        Node n=next;
+        while(n!=null)
+          {
+            lastTextNode=n;
+            // Any Text node means DTM considers it all Text
+            if(TEXT_NODE == n.getNodeType())
+              nexttype=TEXT_NODE;
+            // Any non-whitespace in this sequence blocks whitespace
+            // suppression
+            suppressNode &=
+              XMLCharacterRecognizer.isWhiteSpace(n.getNodeValue());
+                        
+            n=logicalNextDOMTextNode(n);
+          }
+      }
+        
+    // Special handling for PIs: Some DOMs represent the XML
+    // Declaration as a PI. This is officially incorrect, per the DOM
+    // spec, but is considered a "wrong but tolerable" temporary
+    // workaround pending proper handling of these fields in DOM Level
+    // 3. We want to recognize and reject that case.
+    else if(PROCESSING_INSTRUCTION_NODE==nexttype)
+      {
+        suppressNode = (pos.getNodeName().toLowerCase().equals("xml"));
+      }
+        
+        
+    if(!suppressNode)
+      {
+        // Inserting next. NOTE that we force the node type; for
+        // coalesced Text, this records CDATASections adjacent to
+        // ordinary Text as Text.
+        int nextindex=addNode(next,m_last_parent,m_last_kid,
+			      nexttype);
+	
+        m_last_kid=nextindex;
+
+        if(ELEMENT_NODE == nexttype)
+          {
+            int attrIndex=NULL; // start with no previous sib
+            // Process attributes _now_, rather than waiting.
+            // Simpler control flow, makes NS cache available immediately.
+            NamedNodeMap attrs=next.getAttributes();
+            int attrsize=(attrs==null) ? 0 : attrs.getLength();
+            if(attrsize>0)
+              {
+                for(int i=0;i<attrsize;++i)
+                  {
+                    // No need to force nodetype in this case;
+                    // addNode() will take care of switching it from
+                    // Attr to Namespace if necessary.
+                    attrIndex=addNode(attrs.item(i),
+                                      nextindex,attrIndex,NULL);
+                    m_firstch.setElementAt(DTM.NULL,attrIndex);
+
+                    // If the xml: prefix is explicitly declared
+                    // we don't need to synthesize one.
+		    //
+		    // NOTE that XML Namespaces were not originally
+		    // defined as being namespace-aware (grrr), and
+		    // while the W3C is planning to fix this it's
+		    // safer for now to test the QName and trust the
+		    // parsers to prevent anyone from redefining the
+		    // reserved xmlns: prefix
+                    if(!m_processedFirstElement
+                       && "xmlns:xml".equals(attrs.item(i).getNodeName()))
+                      m_processedFirstElement=true; 
+                  }
+                // Terminate list of attrs, and make sure they aren't
+                // considered children of the element
+              } // if attrs exist
+            if(!m_processedFirstElement)
+            {
+              // The DOM might not have an explicit declaration for the
+              // implicit "xml:" prefix, but the XPath data model
+              // requires that this appear as a Namespace Node so we
+              // have to synthesize one. You can think of this as
+              // being a default attribute defined by the XML
+              // Namespaces spec rather than by the DTD.
+              attrIndex=addNode(new DOM2DTMdefaultNamespaceDeclarationNode(
+																	(Element)next,"xml",NAMESPACE_DECL_NS,
+																	makeNodeHandle(((attrIndex==NULL)?nextindex:attrIndex)+1)
+																	),
+                                nextindex,attrIndex,NULL);      
+              m_firstch.setElementAt(DTM.NULL,attrIndex);
+              m_processedFirstElement=true;
+            }
+            if(attrIndex!=NULL)
+              m_nextsib.setElementAt(DTM.NULL,attrIndex);
+          } //if(ELEMENT_NODE)
+      } // (if !suppressNode)
+
+    // Text postprocessing: Act on values stored above
+    if(TEXT_NODE == nexttype || CDATA_SECTION_NODE == nexttype)
+      {
+        // %TBD% If nexttype was forced to TEXT, patch the DTM node
+                
+        next=lastTextNode;      // Advance the DOM cursor over contiguous text
+      }
+        
+    // Remember where we left off.
+    m_pos=next;
+    return true;
+  }  
+
+
+  /**
+   * Return an DOM node for the given node.
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A node representation of the DTM node.
+   */
+  public Node getNode(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+
+    return (Node) m_nodes.elementAt(identity);
+  }
+
+  /**
+   * Get a Node from an identity index.
+   *
+   * NEEDSDOC @param nodeIdentity
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  protected Node lookupNode(int nodeIdentity)
+  {
+    return (Node) m_nodes.elementAt(nodeIdentity);
+  }
+
+  /**
+   * Get the next node identity value in the list, and call the iterator
+   * if it hasn't been added yet.
+   *
+   * @param identity The node identity (index).
+   * @return identity+1, or DTM.NULL.
+   */
+  protected int getNextNodeIdentity(int identity)
+  {
+
+    identity += 1;
+
+    if (identity >= m_nodes.size())
+    {
+      if (!nextNode())
+        identity = DTM.NULL;
+    }
+
+    return identity;
+  }
+
+  /**
+   * Get the handle from a Node.
+   * <p>%OPT% This will be pretty slow.</p>
+   *
+   * <p>%OPT% An XPath-like search (walk up DOM to root, tracking path;
+   * walk down DTM reconstructing path) might be considerably faster
+   * on later nodes in large documents. That might also imply improving
+   * this call to handle nodes which would be in this DTM but
+   * have not yet been built, which might or might not be a Good Thing.</p>
+   * 
+   * %REVIEW% This relies on being able to test node-identity via
+   * object-identity. DTM2DOM proxying is a great example of a case where
+   * that doesn't work. DOM Level 3 will provide the isSameNode() method
+   * to fix that, but until then this is going to be flaky.
+   *
+   * @param node A node, which may be null.
+   *
+   * @return The node handle or <code>DTM.NULL</code>.
+   */
+  private int getHandleFromNode(Node node)
+  {
+    if (null != node)
+    {
+      int len = m_nodes.size();        
+      boolean isMore;
+      int i = 0;
+      do
+      {          
+        for (; i < len; i++)
+        {
+          if (m_nodes.elementAt(i) == node)
+            return makeNodeHandle(i);
+        }
+
+        isMore = nextNode();
+  
+        len = m_nodes.size();
+            
+      } 
+      while(isMore || i < len);
+    }
+    
+    return DTM.NULL;
+  }
+
+  /** Get the handle from a Node. This is a more robust version of
+   * getHandleFromNode, intended to be usable by the public.
+   *
+   * <p>%OPT% This will be pretty slow.</p>
+   * 
+   * %REVIEW% This relies on being able to test node-identity via
+   * object-identity. DTM2DOM proxying is a great example of a case where
+   * that doesn't work. DOM Level 3 will provide the isSameNode() method
+   * to fix that, but until then this is going to be flaky.
+   *
+   * @param node A node, which may be null.
+   *
+   * @return The node handle or <code>DTM.NULL</code>.  */
+  public int getHandleOfNode(Node node)
+  {
+    if (null != node)
+    {
+      // Is Node actually within the same document? If not, don't search!
+      // This would be easier if m_root was always the Document node, but
+      // we decided to allow wrapping a DTM around a subtree.
+      if((m_root==node) ||
+         (m_root.getNodeType()==DOCUMENT_NODE &&
+          m_root==node.getOwnerDocument()) ||
+         (m_root.getNodeType()!=DOCUMENT_NODE &&
+          m_root.getOwnerDocument()==node.getOwnerDocument())
+         )
+        {
+          // If node _is_ in m_root's tree, find its handle
+          //
+          // %OPT% This check may be improved significantly when DOM
+          // Level 3 nodeKey and relative-order tests become
+          // available!
+          for(Node cursor=node;
+              cursor!=null;
+              cursor=
+                (cursor.getNodeType()!=ATTRIBUTE_NODE)
+                ? cursor.getParentNode()
+                : ((org.w3c.dom.Attr)cursor).getOwnerElement())
+            {
+              if(cursor==m_root)
+                // We know this node; find its handle.
+                return getHandleFromNode(node); 
+            } // for ancestors of node
+        } // if node and m_root in same Document
+    } // if node!=null
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Retrieves an attribute node by by qualified name and namespace URI.
+   *
+   * @param nodeHandle int Handle of the node upon which to look up this attribute..
+   * @param namespaceURI The namespace URI of the attribute to
+   *   retrieve, or null.
+   * @param name The local name of the attribute to
+   *   retrieve.
+   * @return The attribute node handle with the specified name (
+   *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
+   *   attribute.
+   */
+  public int getAttributeNode(int nodeHandle, String namespaceURI,
+                              String name)
+  {
+
+    // %OPT% This is probably slower than it needs to be.
+    if (null == namespaceURI)
+      namespaceURI = "";
+
+    int type = getNodeType(nodeHandle);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+
+      // Assume that attributes immediately follow the element.
+      int identity = makeNodeIdentity(nodeHandle);
+
+      while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+      {
+        // Assume this can not be null.
+        type = _type(identity);
+
+				// %REVIEW%
+				// Should namespace nodes be retrievable DOM-style as attrs?
+				// If not we need a separate function... which may be desirable
+				// architecturally, but which is ugly from a code point of view.
+				// (If we REALLY insist on it, this code should become a subroutine
+				// of both -- retrieve the node, then test if the type matches
+				// what you're looking for.)
+        if (type == DTM.ATTRIBUTE_NODE || type==DTM.NAMESPACE_NODE)
+        {
+          Node node = lookupNode(identity);
+          String nodeuri = node.getNamespaceURI();
+
+          if (null == nodeuri)
+            nodeuri = "";
+
+          String nodelocalname = node.getLocalName();
+
+          if (nodeuri.equals(namespaceURI) && name.equals(nodelocalname))
+            return makeNodeHandle(identity);
+        }
+				
+        else // if (DTM.NAMESPACE_NODE != type)
+        {
+          break;
+        }
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Get the string-value of a node as a String object
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public XMLString getStringValue(int nodeHandle)
+  {
+
+    int type = getNodeType(nodeHandle);
+    Node node = getNode(nodeHandle);
+    // %TBD% If an element only has one text node, we should just use it 
+    // directly.
+    if(DTM.ELEMENT_NODE == type || DTM.DOCUMENT_NODE == type 
+    || DTM.DOCUMENT_FRAGMENT_NODE == type)
+    {
+      FastStringBuffer buf = StringBufferPool.get();
+      String s;
+  
+      try
+      {
+        getNodeData(node, buf);
+  
+        s = (buf.length() > 0) ? buf.toString() : "";
+      }
+      finally
+      {
+        StringBufferPool.free(buf);
+      }
+  
+      return m_xstrf.newstr( s );
+    }
+    else if(TEXT_NODE == type || CDATA_SECTION_NODE == type)
+    {
+      // If this is a DTM text node, it may be made of multiple DOM text
+      // nodes -- including navigating into Entity References. DOM2DTM
+      // records the first node in the sequence and requires that we
+      // pick up the others when we retrieve the DTM node's value.
+      //
+      // %REVIEW% DOM Level 3 is expected to add a "whole text"
+      // retrieval method which performs this function for us.
+      FastStringBuffer buf = StringBufferPool.get();
+      while(node!=null)
+      {
+        buf.append(node.getNodeValue());
+        node=logicalNextDOMTextNode(node);
+      }
+      String s=(buf.length() > 0) ? buf.toString() : "";
+      StringBufferPool.free(buf);
+      return m_xstrf.newstr( s );
+    }
+    else
+      return m_xstrf.newstr( node.getNodeValue() );
+  }
+  
+  /**
+   * Determine if the string-value of a node is whitespace
+   *
+   * @param nodeHandle The node Handle.
+   *
+   * @return Return true if the given node is whitespace.
+   */
+  public boolean isWhitespace(int nodeHandle)
+  {
+  	int type = getNodeType(nodeHandle);
+    Node node = getNode(nodeHandle);
+  	if(TEXT_NODE == type || CDATA_SECTION_NODE == type)
+    {
+      // If this is a DTM text node, it may be made of multiple DOM text
+      // nodes -- including navigating into Entity References. DOM2DTM
+      // records the first node in the sequence and requires that we
+      // pick up the others when we retrieve the DTM node's value.
+      //
+      // %REVIEW% DOM Level 3 is expected to add a "whole text"
+      // retrieval method which performs this function for us.
+      FastStringBuffer buf = StringBufferPool.get();
+      while(node!=null)
+      {
+        buf.append(node.getNodeValue());
+        node=logicalNextDOMTextNode(node);
+      }
+     boolean b = buf.isWhitespace(0, buf.length());
+      StringBufferPool.free(buf);
+     return b;
+    }
+    return false;
+  }
+  
+  /**
+   * Retrieve the text content of a DOM subtree, appending it into a
+   * user-supplied FastStringBuffer object. Note that attributes are
+   * not considered part of the content of an element.
+   * <p>
+   * There are open questions regarding whitespace stripping. 
+   * Currently we make no special effort in that regard, since the standard
+   * DOM doesn't yet provide DTD-based information to distinguish
+   * whitespace-in-element-context from genuine #PCDATA. Note that we
+   * should probably also consider xml:space if/when we address this.
+   * DOM Level 3 may solve the problem for us.
+   * <p>
+   * %REVIEW% Actually, since this method operates on the DOM side of the
+   * fence rather than the DTM side, it SHOULDN'T do
+   * any special handling. The DOM does what the DOM does; if you want
+   * DTM-level abstractions, use DTM-level methods.
+   *
+   * @param node Node whose subtree is to be walked, gathering the
+   * contents of all Text or CDATASection nodes.
+   * @param buf FastStringBuffer into which the contents of the text
+   * nodes are to be concatenated.
+   */
+  protected static void getNodeData(Node node, FastStringBuffer buf)
+  {
+
+    switch (node.getNodeType())
+    {
+    case Node.DOCUMENT_FRAGMENT_NODE :
+    case Node.DOCUMENT_NODE :
+    case Node.ELEMENT_NODE :
+    {
+      for (Node child = node.getFirstChild(); null != child;
+              child = child.getNextSibling())
+      {
+        getNodeData(child, buf);
+      }
+    }
+    break;
+    case Node.TEXT_NODE :
+    case Node.CDATA_SECTION_NODE :
+    case Node.ATTRIBUTE_NODE :	// Never a child but might be our starting node
+      buf.append(node.getNodeValue());
+      break;
+    case Node.PROCESSING_INSTRUCTION_NODE :
+      // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);        
+      break;
+    default :
+      // ignore
+      break;
+    }
+  }
+
+  /**
+   * Given a node handle, return its DOM-style node name. This will
+   * include names such as #text or #document.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   * %REVIEW% Document when empty string is possible...
+   * %REVIEW-COMMENT% It should never be empty, should it?
+   */
+  public String getNodeName(int nodeHandle)
+  {
+
+    Node node = getNode(nodeHandle);
+
+    // Assume non-null.
+    return node.getNodeName();
+  }
+
+  /**
+   * Given a node handle, return the XPath node name.  This should be
+   * the name as described by the XPath data model, NOT the DOM-style
+   * name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   */
+  public String getNodeNameX(int nodeHandle)
+  {
+
+    String name;
+    short type = getNodeType(nodeHandle);
+
+    switch (type)
+    {
+    case DTM.NAMESPACE_NODE :
+    {
+      Node node = getNode(nodeHandle);
+
+      // assume not null.
+      name = node.getNodeName();
+      if(name.startsWith("xmlns:"))
+      {
+        name = QName.getLocalPart(name);
+      }
+      else if(name.equals("xmlns"))
+      {
+        name = "";
+      }
+    }
+    break;
+    case DTM.ATTRIBUTE_NODE :
+    case DTM.ELEMENT_NODE :
+    case DTM.ENTITY_REFERENCE_NODE :
+    case DTM.PROCESSING_INSTRUCTION_NODE :
+    {
+      Node node = getNode(nodeHandle);
+
+      // assume not null.
+      name = node.getNodeName();
+    }
+    break;
+    default :
+      name = "";
+    }
+
+    return name;
+  }
+
+  /**
+   * Given a node handle, return its XPath-style localname.
+   * (As defined in Namespaces, this is the portion of the name after any
+   * colon character).
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Local name of this node.
+   */
+  public String getLocalName(int nodeHandle)
+  {
+    if(JJK_NEWCODE)
+    {
+      int id=makeNodeIdentity(nodeHandle);
+      if(NULL==id) return null;
+      Node newnode=(Node)m_nodes.elementAt(id);
+      String newname=newnode.getLocalName();
+      if (null == newname)
+      {
+	// XSLT treats PIs, and possibly other things, as having QNames.
+	String qname = newnode.getNodeName();
+	if('#'==qname.charAt(0))
+	{
+	  //  Match old default for this function
+	  // This conversion may or may not be necessary
+	  newname="";
+	}
+	else
+	{
+	  int index = qname.indexOf(':');
+	  newname = (index < 0) ? qname : qname.substring(index + 1);
+	}
+      }
+      return newname;
+    }
+    else
+    {
+      String name;
+      short type = getNodeType(nodeHandle);
+      switch (type)
+      {
+      case DTM.ATTRIBUTE_NODE :
+      case DTM.ELEMENT_NODE :
+      case DTM.ENTITY_REFERENCE_NODE :
+      case DTM.NAMESPACE_NODE :
+      case DTM.PROCESSING_INSTRUCTION_NODE :
+	{
+	  Node node = getNode(nodeHandle);
+	  
+	  // assume not null.
+	  name = node.getLocalName();
+	  
+	  if (null == name)
+	  {
+	    String qname = node.getNodeName();
+	    int index = qname.indexOf(':');
+	    
+	    name = (index < 0) ? qname : qname.substring(index + 1);
+	  }
+	}
+	break;
+      default :
+	name = "";
+      }
+      return name;
+    }
+  }
+
+  /**
+   * Given a namespace handle, return the prefix that the namespace decl is
+   * mapping.
+   * Given a node handle, return the prefix used to map to the namespace.
+   *
+   * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
+   * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb  </p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String prefix of this node's name, or "" if no explicit
+   * namespace prefix was given.
+   */
+  public String getPrefix(int nodeHandle)
+  {
+
+    String prefix;
+    short type = getNodeType(nodeHandle);
+
+    switch (type)
+    {
+    case DTM.NAMESPACE_NODE :
+    {
+      Node node = getNode(nodeHandle);
+
+      // assume not null.
+      String qname = node.getNodeName();
+      int index = qname.indexOf(':');
+
+      prefix = (index < 0) ? "" : qname.substring(index + 1);
+    }
+    break;
+    case DTM.ATTRIBUTE_NODE :
+    case DTM.ELEMENT_NODE :
+    {
+      Node node = getNode(nodeHandle);
+
+      // assume not null.
+      String qname = node.getNodeName();
+      int index = qname.indexOf(':');
+
+      prefix = (index < 0) ? "" : qname.substring(0, index);
+    }
+    break;
+    default :
+      prefix = "";
+    }
+
+    return prefix;
+  }
+
+  /**
+   * Given a node handle, return its DOM-style namespace URI
+   * (As defined in Namespaces, this is the declared URI which this node's
+   * prefix -- or default in lieu thereof -- was mapped to.)
+   *
+   * <p>%REVIEW% Null or ""? -sb</p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespaceURI(int nodeHandle)
+  {
+    if(JJK_NEWCODE)
+    {
+      int id=makeNodeIdentity(nodeHandle);
+      if(id==NULL) return null;
+      Node node=(Node)m_nodes.elementAt(id);
+      return node.getNamespaceURI();
+    }
+    else
+    {
+      String nsuri;
+      short type = getNodeType(nodeHandle);
+      
+      switch (type)
+      {
+      case DTM.ATTRIBUTE_NODE :
+      case DTM.ELEMENT_NODE :
+      case DTM.ENTITY_REFERENCE_NODE :
+      case DTM.NAMESPACE_NODE :
+      case DTM.PROCESSING_INSTRUCTION_NODE :
+	{
+	  Node node = getNode(nodeHandle);
+	  
+	  // assume not null.
+	  nsuri = node.getNamespaceURI();
+	  
+	  // %TBD% Handle DOM1?
+	}
+	break;
+      default :
+	nsuri = null;
+      }
+
+      return nsuri;
+    }
+    
+  }
+  
+  /** Utility function: Given a DOM Text node, determine whether it is
+   * logically followed by another Text or CDATASection node. This may
+   * involve traversing into Entity References.
+   * 
+   * %REVIEW% DOM Level 3 is expected to add functionality which may 
+   * allow us to retire this.
+   */
+  private Node logicalNextDOMTextNode(Node n)
+  {
+        Node p=n.getNextSibling();
+        if(p==null)
+        {
+                // Walk out of any EntityReferenceNodes that ended with text
+                for(n=n.getParentNode();
+                        n!=null && ENTITY_REFERENCE_NODE == n.getNodeType();
+                        n=n.getParentNode())
+                {
+                        p=n.getNextSibling();
+                        if(p!=null)
+                                break;
+                }
+        }
+        n=p;
+        while(n!=null && ENTITY_REFERENCE_NODE == n.getNodeType())
+        {
+                // Walk into any EntityReferenceNodes that start with text
+                if(n.hasChildNodes())
+                        n=n.getFirstChild();
+                else
+                        n=n.getNextSibling();
+        }
+        if(n!=null)
+        {
+                // Found a logical next sibling. Is it text?
+                int ntype=n.getNodeType();
+                if(TEXT_NODE != ntype && CDATA_SECTION_NODE != ntype)
+                        n=null;
+        }
+        return n;
+  }
+
+  /**
+   * Given a node handle, return its node value. This is mostly
+   * as defined by the DOM, but may ignore some conveniences.
+   * <p>
+   *
+   * @param nodeHandle The node id.
+   * @return String Value of this node, or null if not
+   * meaningful for this node type.
+   */
+  public String getNodeValue(int nodeHandle)
+  {
+    // The _type(nodeHandle) call was taking the lion's share of our
+    // time, and was wrong anyway since it wasn't coverting handle to
+    // identity. Inlined it.
+    int type = _exptype(makeNodeIdentity(nodeHandle));
+    type=(NULL != type) ? getNodeType(nodeHandle) : NULL;
+    
+    if(TEXT_NODE!=type && CDATA_SECTION_NODE!=type)
+      return getNode(nodeHandle).getNodeValue();
+    
+    // If this is a DTM text node, it may be made of multiple DOM text
+    // nodes -- including navigating into Entity References. DOM2DTM
+    // records the first node in the sequence and requires that we
+    // pick up the others when we retrieve the DTM node's value.
+    //
+    // %REVIEW% DOM Level 3 is expected to add a "whole text"
+    // retrieval method which performs this function for us.
+    Node node = getNode(nodeHandle);
+    Node n=logicalNextDOMTextNode(node);
+    if(n==null)
+      return node.getNodeValue();
+    
+    FastStringBuffer buf = StringBufferPool.get();
+        buf.append(node.getNodeValue());
+    while(n!=null)
+    {
+      buf.append(n.getNodeValue());
+      n=logicalNextDOMTextNode(n);
+    }
+    String s = (buf.length() > 0) ? buf.toString() : "";
+    StringBufferPool.free(buf);
+    return s;
+  }
+
+  /**
+   *   A document type declaration information item has the following properties:
+   *
+   *     1. [system identifier] The system identifier of the external subset, if
+   *        it exists. Otherwise this property has no value.
+   *
+   * @return the system identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationSystemIdentifier()
+  {
+
+    Document doc;
+
+    if (m_root.getNodeType() == Node.DOCUMENT_NODE)
+      doc = (Document) m_root;
+    else
+      doc = m_root.getOwnerDocument();
+
+    if (null != doc)
+    {
+      DocumentType dtd = doc.getDoctype();
+
+      if (null != dtd)
+      {
+        return dtd.getSystemId();
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Return the public identifier of the external subset,
+   * normalized as described in 4.2.2 External Entities [XML]. If there is
+   * no external subset or if it has no public identifier, this property
+   * has no value.
+   *
+   * @return the public identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationPublicIdentifier()
+  {
+
+    Document doc;
+
+    if (m_root.getNodeType() == Node.DOCUMENT_NODE)
+      doc = (Document) m_root;
+    else
+      doc = m_root.getOwnerDocument();
+
+    if (null != doc)
+    {
+      DocumentType dtd = doc.getDoctype();
+
+      if (null != dtd)
+      {
+        return dtd.getPublicId();
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Returns the <code>Element</code> whose <code>ID</code> is given by
+   * <code>elementId</code>. If no such element exists, returns
+   * <code>DTM.NULL</code>. Behavior is not defined if more than one element
+   * has this <code>ID</code>. Attributes (including those
+   * with the name "ID") are not of type ID unless so defined by DTD/Schema
+   * information available to the DTM implementation.
+   * Implementations that do not know whether attributes are of type ID or
+   * not are expected to return <code>DTM.NULL</code>.
+   *
+   * <p>%REVIEW% Presumably IDs are still scoped to a single document,
+   * and this operation searches only within a single document, right?
+   * Wouldn't want collisions between DTMs in the same process.</p>
+   *
+   * @param elementId The unique <code>id</code> value for an element.
+   * @return The handle of the matching element.
+   */
+  public int getElementById(String elementId)
+  {
+
+    Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) 
+        ? (Document) m_root : m_root.getOwnerDocument();
+        
+    if(null != doc)
+    {
+      Node elem = doc.getElementById(elementId);
+      if(null != elem)
+      {
+        int elemHandle = getHandleFromNode(elem);
+        
+        if(DTM.NULL == elemHandle)
+        {
+          int identity = m_nodes.size()-1;
+          while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+          {
+            Node node = getNode(identity);
+            if(node == elem)
+            {
+              elemHandle = getHandleFromNode(elem);
+              break;
+            }
+           }
+        }
+        
+        return elemHandle;
+      }
+    
+    }
+    return DTM.NULL;
+  }
+
+  /**
+   * The getUnparsedEntityURI function returns the URI of the unparsed
+   * entity with the specified name in the same document as the context
+   * node (see [3.3 Unparsed Entities]). It returns the empty string if
+   * there is no such entity.
+   * <p>
+   * XML processors may choose to use the System Identifier (if one
+   * is provided) to resolve the entity, rather than the URI in the
+   * Public Identifier. The details are dependent on the processor, and
+   * we would have to support some form of plug-in resolver to handle
+   * this properly. Currently, we simply return the System Identifier if
+   * present, and hope that it a usable URI or that our caller can
+   * map it to one.
+   * TODO: Resolve Public Identifiers... or consider changing function name.
+   * <p>
+   * If we find a relative URI
+   * reference, XML expects it to be resolved in terms of the base URI
+   * of the document. The DOM doesn't do that for us, and it isn't
+   * entirely clear whether that should be done here; currently that's
+   * pushed up to a higher level of our application. (Note that DOM Level
+   * 1 didn't store the document's base URI.)
+   * TODO: Consider resolving Relative URIs.
+   * <p>
+   * (The DOM's statement that "An XML processor may choose to
+   * completely expand entities before the structure model is passed
+   * to the DOM" refers only to parsed entities, not unparsed, and hence
+   * doesn't affect this function.)
+   *
+   * @param name A string containing the Entity Name of the unparsed
+   * entity.
+   *
+   * @return String containing the URI of the Unparsed Entity, or an
+   * empty string if no such entity exists.
+   */
+  public String getUnparsedEntityURI(String name)
+  {
+
+    String url = "";
+    Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) 
+        ? (Document) m_root : m_root.getOwnerDocument();
+
+    if (null != doc)
+    {
+      DocumentType doctype = doc.getDoctype();
+  
+      if (null != doctype)
+      {
+        NamedNodeMap entities = doctype.getEntities();
+        if(null == entities)
+          return url;
+        Entity entity = (Entity) entities.getNamedItem(name);
+        if(null == entity)
+          return url;
+        
+        String notationName = entity.getNotationName();
+  
+        if (null != notationName)  // then it's unparsed
+        {
+          // The draft says: "The XSLT processor may use the public 
+          // identifier to generate a URI for the entity instead of the URI 
+          // specified in the system identifier. If the XSLT processor does 
+          // not use the public identifier to generate the URI, it must use 
+          // the system identifier; if the system identifier is a relative 
+          // URI, it must be resolved into an absolute URI using the URI of 
+          // the resource containing the entity declaration as the base 
+          // URI [RFC2396]."
+          // So I'm falling a bit short here.
+          url = entity.getSystemId();
+  
+          if (null == url)
+          {
+            url = entity.getPublicId();
+          }
+          else
+          {
+            // This should be resolved to an absolute URL, but that's hard 
+            // to do from here.
+          }        
+        }
+      }
+    }
+
+    return url;
+  }
+
+  /**
+   *     5. [specified] A flag indicating whether this attribute was actually
+   *        specified in the start-tag of its element, or was defaulted from the
+   *        DTD.
+   *
+   * @param attributeHandle the attribute handle
+   * @return <code>true</code> if the attribute was specified;
+   *         <code>false</code> if it was defaulted.
+   */
+  public boolean isAttributeSpecified(int attributeHandle)
+  {
+    int type = getNodeType(attributeHandle);
+
+    if (DTM.ATTRIBUTE_NODE == type)
+    {
+      Attr attr = (Attr)getNode(attributeHandle);
+      return attr.getSpecified();
+    }
+    return false;
+  }
+
+  /** Bind an IncrementalSAXSource to this DTM. NOT RELEVANT for DOM2DTM, since
+   * we're wrapped around an existing DOM.
+   *
+   * @param source The IncrementalSAXSource that we want to recieve events from
+   * on demand.
+   */
+  public void setIncrementalSAXSource(IncrementalSAXSource source)
+  {
+  }
+  
+  /** getContentHandler returns "our SAX builder" -- the thing that
+   * someone else should send SAX events to in order to extend this
+   * DTM model.
+   *
+   * @return null if this model doesn't respond to SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrmentalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   * */
+  public org.xml.sax.ContentHandler getContentHandler()
+  {
+      return null;
+  }
+  
+  /**
+   * Return this DTM's lexical handler.
+   *
+   * %REVIEW% Should this return null if constrution already done/begun?
+   *
+   * @return null if this model doesn't respond to lexical SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrementalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   */
+  public org.xml.sax.ext.LexicalHandler getLexicalHandler()
+  {
+
+    return null;
+  }
+
+  
+  /**
+   * Return this DTM's EntityResolver.
+   *
+   * @return null if this model doesn't respond to SAX entity ref events.
+   */
+  public org.xml.sax.EntityResolver getEntityResolver()
+  {
+
+    return null;
+  }
+  
+  /**
+   * Return this DTM's DTDHandler.
+   *
+   * @return null if this model doesn't respond to SAX dtd events.
+   */
+  public org.xml.sax.DTDHandler getDTDHandler()
+  {
+
+    return null;
+  }
+
+  /**
+   * Return this DTM's ErrorHandler.
+   *
+   * @return null if this model doesn't respond to SAX error events.
+   */
+  public org.xml.sax.ErrorHandler getErrorHandler()
+  {
+
+    return null;
+  }
+  
+  /**
+   * Return this DTM's DeclHandler.
+   *
+   * @return null if this model doesn't respond to SAX Decl events.
+   */
+  public org.xml.sax.ext.DeclHandler getDeclHandler()
+  {
+
+    return null;
+  }  
+
+  /** @return true iff we're building this model incrementally (eg
+   * we're partnered with a IncrementalSAXSource) and thus require that the
+   * transformation and the parse run simultaneously. Guidance to the
+   * DTMManager.
+   * */
+  public boolean needsTwoThreads()
+  {
+    return false;
+  }
+
+  // ========== Direct SAX Dispatch, for optimization purposes ========
+  
+  /**
+   * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition
+   * of whitespace.  Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
+   * the definition of <CODE>S</CODE></A> for details.
+   * @param   ch      Character to check as XML whitespace.
+   * @return          =true if <var>ch</var> is XML whitespace; otherwise =false.
+   */
+  private static boolean isSpace(char ch)
+  {
+    return XMLCharacterRecognizer.isWhiteSpace(ch);  // Take the easy way out for now.
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value). Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(
+          int nodeHandle, org.xml.sax.ContentHandler ch, 
+          boolean normalize)
+            throws org.xml.sax.SAXException
+  {
+    if(normalize)
+    {
+      XMLString str = getStringValue(nodeHandle);
+      str = str.fixWhiteSpace(true, true, false);
+      str.dispatchCharactersEvents(ch);
+    }
+    else
+    {
+      int type = getNodeType(nodeHandle);
+      Node node = getNode(nodeHandle);
+      dispatchNodeData(node, ch, 0);
+          // Text coalition -- a DTM text node may represent multiple
+          // DOM nodes.
+          if(TEXT_NODE == type || CDATA_SECTION_NODE == type)
+          {
+                  while( null != (node=logicalNextDOMTextNode(node)) )
+                  {
+                      dispatchNodeData(node, ch, 0);
+                  }
+          }
+    }
+  }
+  
+  /**
+   * Retrieve the text content of a DOM subtree, appending it into a
+   * user-supplied FastStringBuffer object. Note that attributes are
+   * not considered part of the content of an element.
+   * <p>
+   * There are open questions regarding whitespace stripping. 
+   * Currently we make no special effort in that regard, since the standard
+   * DOM doesn't yet provide DTD-based information to distinguish
+   * whitespace-in-element-context from genuine #PCDATA. Note that we
+   * should probably also consider xml:space if/when we address this.
+   * DOM Level 3 may solve the problem for us.
+   * <p>
+   * %REVIEW% Note that as a DOM-level operation, it can be argued that this
+   * routine _shouldn't_ perform any processing beyond what the DOM already
+   * does, and that whitespace stripping and so on belong at the DTM level.
+   * If you want a stripped DOM view, wrap DTM2DOM around DOM2DTM.
+   *
+   * @param node Node whose subtree is to be walked, gathering the
+   * contents of all Text or CDATASection nodes.
+   */
+  protected static void dispatchNodeData(Node node, 
+                                         org.xml.sax.ContentHandler ch, 
+                                         int depth)
+            throws org.xml.sax.SAXException
+  {
+
+    switch (node.getNodeType())
+    {
+    case Node.DOCUMENT_FRAGMENT_NODE :
+    case Node.DOCUMENT_NODE :
+    case Node.ELEMENT_NODE :
+    {
+      for (Node child = node.getFirstChild(); null != child;
+              child = child.getNextSibling())
+      {
+        dispatchNodeData(child, ch, depth+1);
+      }
+    }
+    break;
+    case Node.PROCESSING_INSTRUCTION_NODE : // %REVIEW%
+    case Node.COMMENT_NODE :
+      if(0 != depth)
+        break;
+        // NOTE: Because this operation works in the DOM space, it does _not_ attempt
+        // to perform Text Coalition. That should only be done in DTM space. 
+    case Node.TEXT_NODE :
+    case Node.CDATA_SECTION_NODE :
+    case Node.ATTRIBUTE_NODE :
+      String str = node.getNodeValue();
+      if(ch instanceof CharacterNodeHandler)
+      {
+        ((CharacterNodeHandler)ch).characters(node);
+      }
+      else
+      {
+        ch.characters(str.toCharArray(), 0, str.length());
+      }
+      break;
+//    /* case Node.PROCESSING_INSTRUCTION_NODE :
+//      // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);        
+//      break; */
+    default :
+      // ignore
+      break;
+    }
+  }
+  
+  TreeWalker m_walker = new TreeWalker(null);
+  
+  /**
+   * Directly create SAX parser events from a subtree.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+    TreeWalker treeWalker = m_walker;
+    ContentHandler prevCH = treeWalker.getContentHandler();
+    
+    if(null != prevCH)
+    {
+      treeWalker = new TreeWalker(null);
+    }
+    treeWalker.setContentHandler(ch);
+    
+    try
+    {
+      Node node = getNode(nodeHandle);
+      treeWalker.traverseFragment(node);
+    }
+    finally
+    {
+      treeWalker.setContentHandler(null);
+    }
+  }
+  
+  public interface CharacterNodeHandler
+  {
+    public void characters(Node node)
+            throws org.xml.sax.SAXException;
+  }
+
+  /**
+   * For the moment all the run time properties are ignored by this
+   * class.
+   *
+   * @param property a <code>String</code> value
+   * @param value an <code>Object</code> value
+   */
+  public void setProperty(String property, Object value)
+  {
+  }
+  
+  /**
+   * No source information is available for DOM2DTM, so return
+   * <code>null</code> here.
+   *
+   * @param node an <code>int</code> value
+   * @return null
+   */
+  public SourceLocator getSourceLocatorFor(int node)
+  {
+    return null;
+  }
+
+}
+
+
diff --git a/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java b/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java
new file mode 100644
index 0000000..1629326
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java
@@ -0,0 +1,679 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOM2DTMdefaultNamespaceDeclarationNode.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+
+package org.apache.xml.dtm.ref.dom2dtm;
+
+import org.apache.xml.dtm.DTMException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.TypeInfo;
+import org.w3c.dom.UserDataHandler;
+import org.w3c.dom.DOMException;
+
+/** This is a kluge to let us shove a declaration for xml: into the
+ * DOM2DTM model.  Basically, it creates a proxy node in DOM space to
+ * carry the additional information. This is _NOT_ a full DOM
+ * implementation, and shouldn't be one since it sits alongside the
+ * DOM rather than becoming part of the DOM model.
+ * 
+ * (This used to be an internal class within DOM2DTM. Moved out because
+ * I need to perform an instanceof operation on it to support a temporary
+ * workaround in DTMManagerDefault.)
+ * 
+ * %REVIEW% What if the DOM2DTM was built around a DocumentFragment and
+ * there isn't a single root element? I think this fails that case...
+ * 
+ * %REVIEW% An alternative solution would be to create the node _only_
+ * in DTM space, but given how DOM2DTM is currently written I think
+ * this is simplest.
+ * */
+public class DOM2DTMdefaultNamespaceDeclarationNode implements Attr,TypeInfo
+{
+  final String NOT_SUPPORTED_ERR="Unsupported operation on pseudonode";
+  
+  Element pseudoparent;
+  String prefix,uri,nodename;
+  int handle;
+  DOM2DTMdefaultNamespaceDeclarationNode(Element pseudoparent,String prefix,String uri,int handle)
+  {
+    this.pseudoparent=pseudoparent;
+    this.prefix=prefix;
+    this.uri=uri;
+    this.handle=handle;
+    this.nodename="xmlns:"+prefix;
+  }
+  public String getNodeName() {return nodename;}
+  public String getName() {return nodename;}
+  public String getNamespaceURI() {return "http://www.w3.org/2000/xmlns/";}
+  public String getPrefix() {return prefix;}
+  public String getLocalName() {return prefix;}
+  public String getNodeValue() {return uri;}
+  public String getValue() {return uri;}
+  public Element getOwnerElement() {return pseudoparent;}
+  
+  public boolean isSupported(String feature, String version) {return false;}
+  public boolean hasChildNodes() {return false;}
+  public boolean hasAttributes() {return false;}
+  public Node getParentNode() {return null;}
+  public Node getFirstChild() {return null;}
+  public Node getLastChild() {return null;}
+  public Node getPreviousSibling() {return null;}
+  public Node getNextSibling() {return null;}
+  public boolean getSpecified() {return false;}
+  public void normalize() {return;}
+  public NodeList getChildNodes() {return null;}
+  public NamedNodeMap getAttributes() {return null;}
+  public short getNodeType() {return Node.ATTRIBUTE_NODE;}
+  public void setNodeValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public void setValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public void setPrefix(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public Node insertBefore(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public Node replaceChild(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public Node appendChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public Node removeChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);}
+  public Document getOwnerDocument() {return pseudoparent.getOwnerDocument();}
+  public Node cloneNode(boolean deep) {throw new DTMException(NOT_SUPPORTED_ERR);}
+	
+    /** Non-DOM method, part of the temporary kluge
+     * %REVIEW% This would be a pruning problem, but since it will always be
+     * added to the root element and we prune on elements, we shouldn't have 
+     * to worry.
+     */
+    public int getHandleOfNode()		
+    {
+        return handle;
+    }
+
+    //RAMESH: PENDING=> Add proper implementation for the below DOM L3 additions
+
+    /**
+     * @see org.w3c.dom.TypeInfo#getTypeName()
+     */
+    public String getTypeName() {return null; }
+     
+    /**
+     * @see org.w3c.dom.TypeInfo#getTypeNamespace()
+     */
+    public String getTypeNamespace() { return null;}
+    
+    /**
+     * @see or.gw3c.dom.TypeInfo#isDerivedFrom(String,String,int)
+     */
+    public boolean isDerivedFrom( String ns, String localName, int derivationMethod ) {
+        return false;
+    }
+
+    public TypeInfo getSchemaTypeInfo() { return this; }
+    
+    public boolean isId( ) { return false; }
+
+    /**
+     * Associate an object to a key on this node. The object can later be
+     * retrieved from this node by calling <code>getUserData</code> with the
+     * same key.
+     * @param key The key to associate the object to.
+     * @param data The object to associate to the given key, or
+     *   <code>null</code> to remove any existing association to that key.
+     * @param handler The handler to associate to that key, or
+     *   <code>null</code>.
+     * @return Returns the <code>DOMObject</code> previously associated to
+     *   the given key on this node, or <code>null</code> if there was none.
+     * @since DOM Level 3
+     */
+    public Object setUserData(String key,
+                              Object data,
+                              UserDataHandler handler) {
+        return getOwnerDocument().setUserData( key, data, handler);
+    }
+
+    /**
+     * Retrieves the object associated to a key on a this node. The object
+     * must first have been set to this node by calling
+     * <code>setUserData</code> with the same key.
+     * @param key The key the object is associated to.
+     * @return Returns the <code>DOMObject</code> associated to the given key
+     *   on this node, or <code>null</code> if there was none.
+     * @since DOM Level 3
+     */
+    public Object getUserData(String key) {
+        return getOwnerDocument().getUserData( key);
+    } 
+
+    /**
+     *  This method returns a specialized object which implements the
+     * specialized APIs of the specified feature and version. The
+     * specialized object may also be obtained by using binding-specific
+     * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
+     * @param feature The name of the feature requested (case-insensitive).
+     * @param version  This is the version number of the feature to test. If
+     *   the version is <code>null</code> or the empty string, supporting
+     *   any version of the feature will cause the method to return an
+     *   object that supports at least one version of the feature.
+     * @return  Returns an object which implements the specialized APIs of
+     *   the specified feature and version, if any, or <code>null</code> if
+     *   there is no object which implements interfaces associated with that
+     *   feature. If the <code>DOMObject</code> returned by this method
+     *   implements the <code>Node</code> interface, it must delegate to the
+     *   primary core <code>Node</code> and not return results inconsistent
+     *   with the primary core <code>Node</code> such as attributes,
+     *   childNodes, etc.
+     * @since DOM Level 3
+     */
+    public Object getFeature(String feature, String version) {
+        // we don't have any alternate node, either this node does the job
+        // or we don't have anything that does
+        return isSupported(feature, version) ? this : null;
+    }
+
+    /**
+     * Tests whether two nodes are equal.
+     * <br>This method tests for equality of nodes, not sameness (i.e.,
+     * whether the two nodes are references to the same object) which can be
+     * tested with <code>Node.isSameNode</code>. All nodes that are the same
+     * will also be equal, though the reverse may not be true.
+     * <br>Two nodes are equal if and only if the following conditions are
+     * satisfied: The two nodes are of the same type.The following string
+     * attributes are equal: <code>nodeName</code>, <code>localName</code>,
+     * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
+     * , <code>baseURI</code>. This is: they are both <code>null</code>, or
+     * they have the same length and are character for character identical.
+     * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
+     * This is: they are both <code>null</code>, or they have the same
+     * length and for each node that exists in one map there is a node that
+     * exists in the other map and is equal, although not necessarily at the
+     * same index.The <code>childNodes</code> <code>NodeLists</code> are
+     * equal. This is: they are both <code>null</code>, or they have the
+     * same length and contain equal nodes at the same index. This is true
+     * for <code>Attr</code> nodes as for any other type of node. Note that
+     * normalization can affect equality; to avoid this, nodes should be
+     * normalized before being compared.
+     * <br>For two <code>DocumentType</code> nodes to be equal, the following
+     * conditions must also be satisfied: The following string attributes
+     * are equal: <code>publicId</code>, <code>systemId</code>,
+     * <code>internalSubset</code>.The <code>entities</code>
+     * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
+     * <code>NamedNodeMaps</code> are equal.
+     * <br>On the other hand, the following do not affect equality: the
+     * <code>ownerDocument</code> attribute, the <code>specified</code>
+     * attribute for <code>Attr</code> nodes, the
+     * <code>isWhitespaceInElementContent</code> attribute for
+     * <code>Text</code> nodes, as well as any user data or event listeners
+     * registered on the nodes.
+     * @param arg The node to compare equality with.
+     * @param deep If <code>true</code>, recursively compare the subtrees; if
+     *   <code>false</code>, compare only the nodes themselves (and its
+     *   attributes, if it is an <code>Element</code>).
+     * @return If the nodes, and possibly subtrees are equal,
+     *   <code>true</code> otherwise <code>false</code>.
+     * @since DOM Level 3
+     */
+    public boolean isEqualNode(Node arg) {
+        if (arg == this) {
+            return true;
+        }
+        if (arg.getNodeType() != getNodeType()) {
+            return false;
+        }
+        // in theory nodeName can't be null but better be careful
+        // who knows what other implementations may be doing?...
+        if (getNodeName() == null) {
+            if (arg.getNodeName() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeName().equals(arg.getNodeName())) {
+            return false;
+        }
+
+        if (getLocalName() == null) {
+            if (arg.getLocalName() != null) {
+                return false;
+            }
+        }
+        else if (!getLocalName().equals(arg.getLocalName())) {
+            return false;
+        }
+
+        if (getNamespaceURI() == null) {
+            if (arg.getNamespaceURI() != null) {
+                return false;
+            }
+        }
+        else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
+            return false;
+        }
+
+        if (getPrefix() == null) {
+            if (arg.getPrefix() != null) {
+                return false;
+            }
+        }
+        else if (!getPrefix().equals(arg.getPrefix())) {
+            return false;
+        }
+
+        if (getNodeValue() == null) {
+            if (arg.getNodeValue() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeValue().equals(arg.getNodeValue())) {
+            return false;
+        }
+    /*
+        if (getBaseURI() == null) {
+            if (((NodeImpl) arg).getBaseURI() != null) {
+                return false;
+            }
+        }
+        else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
+            return false;
+        }
+*/
+
+             return true;
+    }
+
+    /**
+     * DOM Level 3 - Experimental:
+     * Look up the namespace URI associated to the given prefix, starting from this node.
+     * Use lookupNamespaceURI(null) to lookup the default namespace
+     *
+     * @param namespaceURI
+     * @return th URI for the namespace
+     * @since DOM Level 3
+     */
+    public String lookupNamespaceURI(String specifiedPrefix) {
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE : {
+
+                String namespace = this.getNamespaceURI();
+                String prefix = this.getPrefix();
+                if (namespace !=null) {
+                    // REVISIT: is it possible that prefix is empty string?
+                    if (specifiedPrefix== null && prefix==specifiedPrefix) {
+                        // looking for default namespace
+                        return namespace;
+                    } else if (prefix != null && prefix.equals(specifiedPrefix)) {
+                        // non default namespace
+                        return namespace;
+                    }
+                }
+                if (this.hasAttributes()) {
+                    NamedNodeMap map = this.getAttributes();
+                    int length = map.getLength();
+                    for (int i=0;i<length;i++) {
+                        Node attr = map.item(i);
+                        String attrPrefix = attr.getPrefix();
+                        String value = attr.getNodeValue();
+                        namespace = attr.getNamespaceURI();
+                        if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
+                            // at this point we are dealing with DOM Level 2 nodes only
+                            if (specifiedPrefix == null &&
+                                attr.getNodeName().equals("xmlns")) {
+                                // default namespace
+                                return value;
+                            } else if (attrPrefix !=null &&
+                                       attrPrefix.equals("xmlns") &&
+                                       attr.getLocalName().equals(specifiedPrefix)) {
+                 // non default namespace
+                                return value;
+                            }
+                        }
+                    }
+                }
+		/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+		*/
+
+                return null;
+
+
+            }
+/*
+        case Node.DOCUMENT_NODE : {
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
+
+                }
+                return null;
+            }
+        default:{
+	   /*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+             */
+                return null;
+            }
+
+        }
+    }
+    
+    /**
+     *  DOM Level 3: Experimental
+     *  This method checks if the specified <code>namespaceURI</code> is the
+     *  default namespace or not.
+     *  @param namespaceURI The namespace URI to look for.
+     *  @return  <code>true</code> if the specified <code>namespaceURI</code>
+     *   is the default namespace, <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isDefaultNamespace(String namespaceURI){
+       /*
+        // REVISIT: remove casts when DOM L3 becomes REC.
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE: {
+            String namespace = this.getNamespaceURI();
+            String prefix = this.getPrefix();
+
+            // REVISIT: is it possible that prefix is empty string?
+            if (prefix == null || prefix.length() == 0) {
+                if (namespaceURI == null) {
+                    return (namespace == namespaceURI);
+                }
+                return namespaceURI.equals(namespace);
+            }
+            if (this.hasAttributes()) {
+                ElementImpl elem = (ElementImpl)this;
+                NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
+                if (attr != null) {
+                    String value = attr.getNodeValue();
+                    if (namespaceURI == null) {
+                        return (namespace == value);
+                    }
+                    return namespaceURI.equals(value);
+                }
+            }
+
+            NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+            if (ancestor != null) {
+                return ancestor.isDefaultNamespace(namespaceURI);
+            }
+            return false;
+        }
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
+            }
+
+        case Node.ENTITY_NODE :
+          case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return false;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
+                    return ownerNode.isDefaultNamespace(namespaceURI);
+
+                }
+                return false;
+            }
+        default:{  
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.isDefaultNamespace(namespaceURI);
+                }
+                return false;
+            }
+
+        }
+*/
+        return false;
+
+
+    }
+
+    /**
+     *
+     * DOM Level 3 - Experimental:
+     * Look up the prefix associated to the given namespace URI, starting from this node.
+     *
+     * @param namespaceURI
+     * @return the prefix for the namespace
+     */
+    public String lookupPrefix(String namespaceURI){
+
+        // REVISIT: When Namespaces 1.1 comes out this may not be true
+        // Prefix can't be bound to null namespace
+        if (namespaceURI == null) {
+            return null;
+        }
+
+        short type = this.getNodeType();
+
+        switch (type) {
+/*
+        case Node.ELEMENT_NODE: {
+
+                String namespace = this.getNamespaceURI(); // to flip out children
+                return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
+            }
+
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupPrefix(namespaceURI);
+
+                }
+                return null;
+            }
+        default:{ 
+/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupPrefix(namespaceURI);
+                }
+*/
+                return null;
+            }
+         }
+    }
+
+    /**
+     * Returns whether this node is the same node as the given one.
+     * <br>This method provides a way to determine whether two
+     * <code>Node</code> references returned by the implementation reference
+     * the same object. When two <code>Node</code> references are references
+     * to the same object, even if through a proxy, the references may be
+     * used completely interchangably, such that all attributes have the
+     * same values and calling the same DOM method on either reference
+     * always has exactly the same effect.
+     * @param other The node to test against.
+     * @return Returns <code>true</code> if the nodes are the same,
+     *   <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isSameNode(Node other) {
+        // we do not use any wrapper so the answer is obvious
+        return this == other;
+    }
+
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public void setTextContent(String textContent)
+        throws DOMException {
+        setNodeValue(textContent);
+    }
+    
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public String getTextContent() throws DOMException {
+        return getNodeValue();  // overriden in some subclasses
+    }
+
+    /**
+     * Compares a node with this node with regard to their position in the
+     * document.
+     * @param other The node to compare against this node.
+     * @return Returns how the given node is positioned relatively to this
+     *   node.
+     * @since DOM Level 3
+     */
+    public short compareDocumentPosition(Node other) throws DOMException {
+        return 0;
+    }
+
+    /**
+     * The absolute base URI of this node or <code>null</code> if undefined.
+     * This value is computed according to . However, when the
+     * <code>Document</code> supports the feature "HTML" , the base URI is
+     * computed using first the value of the href attribute of the HTML BASE
+     * element if any, and the value of the <code>documentURI</code>
+     * attribute from the <code>Document</code> interface otherwise.
+     * <br> When the node is an <code>Element</code>, a <code>Document</code>
+     * or a a <code>ProcessingInstruction</code>, this attribute represents
+     * the properties [base URI] defined in . When the node is a
+     * <code>Notation</code>, an <code>Entity</code>, or an
+     * <code>EntityReference</code>, this attribute represents the
+     * properties [declaration base URI] in the . How will this be affected
+     * by resolution of relative namespace URIs issue?It's not.Should this
+     * only be on Document, Element, ProcessingInstruction, Entity, and
+     * Notation nodes, according to the infoset? If not, what is it equal to
+     * on other nodes? Null? An empty string? I think it should be the
+     * parent's.No.Should this be read-only and computed or and actual
+     * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
+     * teleconference 30 May 2001).If the base HTML element is not yet
+     * attached to a document, does the insert change the Document.baseURI?
+     * Yes. (F2F 26 Sep 2001)
+     * @since DOM Level 3
+     */
+    public String getBaseURI() {
+        return null;
+    }
+}
+
diff --git a/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java
new file mode 100644
index 0000000..8033787
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java
@@ -0,0 +1,2513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SAX2DTM.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref.sax2dtm;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xml.dtm.*;
+import org.apache.xml.dtm.ref.*;
+import org.apache.xml.utils.StringVector;
+import org.apache.xml.utils.IntVector;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.SuballocatedIntVector;
+import org.apache.xml.utils.SystemIDResolver;
+import org.apache.xml.utils.WrappedRuntimeException;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+import org.xml.sax.*;
+import org.xml.sax.ext.*;
+
+/**
+ * This class implements a DTM that tends to be optimized more for speed than
+ * for compactness, that is constructed via SAX2 ContentHandler events.
+ */
+public class SAX2DTM extends DTMDefaultBaseIterators
+        implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
+                   DeclHandler, LexicalHandler
+{
+  /** Set true to monitor SAX events and similar diagnostic info. */
+  private static final boolean DEBUG = false;
+
+  /**
+   * If we're building the model incrementally on demand, we need to
+   * be able to tell the source when to send us more data.
+   *
+   * Note that if this has not been set, and you attempt to read ahead
+   * of the current build point, we'll probably throw a null-pointer
+   * exception. We could try to wait-and-retry instead, as a very poor
+   * fallback, but that has all the known problems with multithreading
+   * on multiprocessors and we Don't Want to Go There.
+   *
+   * @see setIncrementalSAXSource
+   */
+  private IncrementalSAXSource m_incrementalSAXSource = null;
+
+  /**
+   * All the character content, including attribute values, are stored in
+   * this buffer.
+   *
+   * %REVIEW% Should this have an option of being shared across DTMs?
+   * Sequentially only; not threadsafe... Currently, I think not.
+   *
+   * %REVIEW% Initial size was pushed way down to reduce weight of RTFs.
+   * pending reduction in number of RTF DTMs. Now that we're sharing a DTM
+   * between RTFs, and tail-pruning... consider going back to the larger/faster.
+   *
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  //private FastStringBuffer m_chars = new FastStringBuffer(13, 13);
+  protected FastStringBuffer m_chars;
+
+  /** This vector holds offset and length data.
+   */
+  protected SuballocatedIntVector m_data;
+
+  /** The parent stack, needed only for construction.
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  transient protected IntStack m_parents;
+
+  /** The current previous node, needed only for construction time.
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  transient protected int m_previous = 0;
+
+  /** Namespace support, only relevent at construction time.
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  transient protected java.util.Vector m_prefixMappings =
+    new java.util.Vector();
+
+  /** Namespace support, only relevent at construction time.
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  transient protected IntStack m_contextIndexes;
+
+  /** Type of next characters() event within text block in prgress. */
+  transient protected int m_textType = DTM.TEXT_NODE;
+
+  /**
+   * Type of coalesced text block. See logic in the characters()
+   * method.
+   */
+  transient protected int m_coalescedTextType = DTM.TEXT_NODE;
+
+  /** The SAX Document locator */
+  transient protected Locator m_locator = null;
+
+  /** The SAX Document system-id */
+  transient private String m_systemId = null;
+
+  /** We are inside the DTD.  This is used for ignoring comments.  */
+  transient protected boolean m_insideDTD = false;
+
+  /** Tree Walker for dispatchToEvents. */
+  protected DTMTreeWalker m_walker = new DTMTreeWalker();
+
+  /** pool of string values that come as strings. */
+  protected DTMStringPool m_valuesOrPrefixes;
+
+  /** End document has been reached.
+   * Made protected rather than private so SAX2RTFDTM can access it.
+   */
+  protected boolean m_endDocumentOccured = false;
+
+  /** Data or qualified name values, one array element for each node. */
+  protected SuballocatedIntVector m_dataOrQName;
+
+  /**
+   * This table holds the ID string to node associations, for
+   * XML IDs.
+   */
+  protected Hashtable m_idAttributes = new Hashtable();
+
+  /**
+   * fixed dom-style names.
+   */
+  private static final String[] m_fixednames = { null, 
+                    null,  // nothing, Element
+                    null, "#text",  // Attr, Text
+                    "#cdata_section", null,  // CDATA, EntityReference
+                    null, null,  // Entity, PI
+                    "#comment", "#document",  // Comment, Document
+                    null, "#document-fragment",  // Doctype, DocumentFragment
+                    null };  // Notation
+
+  /**
+   * Vector of entities.  Each record is composed of four Strings:
+   *  publicId, systemID, notationName, and name.
+   */
+  private Vector m_entities = null;
+
+  /** m_entities public ID offset. */
+  private static final int ENTITY_FIELD_PUBLICID = 0;
+
+  /** m_entities system ID offset. */
+  private static final int ENTITY_FIELD_SYSTEMID = 1;
+
+  /** m_entities notation name offset. */
+  private static final int ENTITY_FIELD_NOTATIONNAME = 2;
+
+  /** m_entities name offset. */
+  private static final int ENTITY_FIELD_NAME = 3;
+
+  /** Number of entries per record for m_entities. */
+  private static final int ENTITY_FIELDS_PER = 4;
+
+  /**
+   * The starting offset within m_chars for the text or
+   * CDATA_SECTION node currently being acumulated,
+   * or -1 if there is no text node in progress
+   */
+  protected int m_textPendingStart = -1;
+
+  /**
+   * Describes whether information about document source location
+   * should be maintained or not.
+   * 
+   * Made protected for access by SAX2RTFDTM.
+   */
+  protected boolean m_useSourceLocationProperty = false;
+
+   /** Made protected for access by SAX2RTFDTM.
+   */
+  protected StringVector m_sourceSystemId;
+   /** Made protected for access by SAX2RTFDTM.
+   */
+  protected IntVector m_sourceLine;
+   /** Made protected for access by SAX2RTFDTM.
+   */
+  protected IntVector m_sourceColumn;
+  
+  /**
+   * Construct a SAX2DTM object using the default block size.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source the JAXP 1.1 Source object for this DTM.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory XMLString factory for creating character content.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   */
+  public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity,
+                 DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing)
+  {
+
+    this(mgr, source, dtmIdentity, whiteSpaceFilter,
+          xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, false);
+  }
+  
+  /**
+   * Construct a SAX2DTM object ready to be constructed from SAX2
+   * ContentHandler events.
+   *
+   * @param mgr The DTMManager who owns this DTM.
+   * @param source the JAXP 1.1 Source object for this DTM.
+   * @param dtmIdentity The DTM identity ID for this DTM.
+   * @param whiteSpaceFilter The white space filter for this DTM, which may
+   *                         be null.
+   * @param xstringfactory XMLString factory for creating character content.
+   * @param doIndexing true if the caller considers it worth it to use
+   *                   indexing schemes.
+   * @param blocksize The block size of the DTM.
+   * @param usePrevsib true if we want to build the previous sibling node array.
+   * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
+   */
+  public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity,
+                 DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing,
+                 int blocksize,
+                 boolean usePrevsib,
+                 boolean newNameTable)
+  {
+
+    super(mgr, source, dtmIdentity, whiteSpaceFilter,
+          xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
+
+    // %OPT% Use smaller sizes for all internal storage units when
+    // the blocksize is small. This reduces the cost of creating an RTF.
+    if (blocksize <= 64) 
+    {
+      m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
+      m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
+      m_valuesOrPrefixes = new DTMStringPool(16);
+      m_chars = new FastStringBuffer(7, 10);
+      m_contextIndexes = new IntStack(4);
+      m_parents = new IntStack(4);
+    }
+    else
+    {
+      m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
+      m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
+      m_valuesOrPrefixes = new DTMStringPool();
+      m_chars = new FastStringBuffer(10, 13);
+      m_contextIndexes = new IntStack();
+      m_parents = new IntStack();
+    }
+         
+    // %REVIEW%  Initial size pushed way down to reduce weight of RTFs
+    // (I'm not entirely sure 0 would work, so I'm playing it safe for now.)
+    //m_data = new SuballocatedIntVector(doIndexing ? (1024*2) : 512, 1024);
+    //m_data = new SuballocatedIntVector(blocksize);
+
+    m_data.addElement(0);   // Need placeholder in case index into here must be <0.
+
+    //m_dataOrQName = new SuballocatedIntVector(blocksize);
+    
+    // m_useSourceLocationProperty=org.apache.xalan.processor.TransformerFactoryImpl.m_source_location;
+    m_useSourceLocationProperty = mgr.getSource_location();
+    m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null;
+ 	m_sourceLine = (m_useSourceLocationProperty) ?  new IntVector() : null;
+    m_sourceColumn = (m_useSourceLocationProperty) ?  new IntVector() : null; 
+  }
+
+  /**
+   * Set whether information about document source location
+   * should be maintained or not. 
+   */
+  public void setUseSourceLocation(boolean useSourceLocation)
+  {
+    m_useSourceLocationProperty = useSourceLocation;
+  }
+
+  /**
+   * Get the data or qualified name for the given node identity.
+   *
+   * @param identity The node identity.
+   *
+   * @return The data or qualified name, or DTM.NULL.
+   */
+  protected int _dataOrQName(int identity)
+  {
+
+    if (identity < m_size)
+      return m_dataOrQName.elementAt(identity);
+
+    // Check to see if the information requested has been processed, and,
+    // if not, advance the iterator until we the information has been
+    // processed.
+    while (true)
+    {
+      boolean isMore = nextNode();
+
+      if (!isMore)
+        return NULL;
+      else if (identity < m_size)
+        return m_dataOrQName.elementAt(identity);
+    }
+  }
+
+  /**
+   * Ask the CoRoutine parser to doTerminate and clear the reference.
+   */
+  public void clearCoRoutine()
+  {
+    clearCoRoutine(true);
+  }
+
+  /**
+   * Ask the CoRoutine parser to doTerminate and clear the reference. If
+   * the CoRoutine parser has already been cleared, this will have no effect.
+   *
+   * @param callDoTerminate true of doTerminate should be called on the
+   * coRoutine parser.
+   */
+  public void clearCoRoutine(boolean callDoTerminate)
+  {
+
+    if (null != m_incrementalSAXSource)
+    {
+      if (callDoTerminate)
+        m_incrementalSAXSource.deliverMoreNodes(false);
+
+      m_incrementalSAXSource = null;
+    }
+  }
+
+  /**
+   * Bind a IncrementalSAXSource to this DTM. If we discover we need nodes
+   * that have not yet been built, we will ask this object to send us more
+   * events, and it will manage interactions with its data sources.
+   *
+   * Note that we do not actually build the IncrementalSAXSource, since we don't
+   * know what source it's reading from, what thread that source will run in,
+   * or when it will run.
+   *
+   * @param incrementalSAXSource The parser that we want to recieve events from
+   * on demand.
+   */
+  public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource)
+  {
+
+    // Establish coroutine link so we can request more data
+    //
+    // Note: It's possible that some versions of IncrementalSAXSource may
+    // not actually use a CoroutineManager, and hence may not require
+    // that we obtain an Application Coroutine ID. (This relies on the
+    // coroutine transaction details having been encapsulated in the
+    // IncrementalSAXSource.do...() methods.)
+    m_incrementalSAXSource = incrementalSAXSource;
+
+    // Establish SAX-stream link so we can receive the requested data
+    incrementalSAXSource.setContentHandler(this);
+    incrementalSAXSource.setLexicalHandler(this);
+    incrementalSAXSource.setDTDHandler(this);
+
+    // Are the following really needed? incrementalSAXSource doesn't yet
+    // support them, and they're mostly no-ops here...
+    //incrementalSAXSource.setErrorHandler(this);
+    //incrementalSAXSource.setDeclHandler(this);
+  }
+
+  /**
+   * getContentHandler returns "our SAX builder" -- the thing that
+   * someone else should send SAX events to in order to extend this
+   * DTM model.
+   *
+   * %REVIEW% Should this return null if constrution already done/begun?
+   *
+   * @return null if this model doesn't respond to SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrementalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   */
+  public ContentHandler getContentHandler()
+  {
+
+    if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter)
+      return (ContentHandler) m_incrementalSAXSource;
+    else
+      return this;
+  }
+
+  /**
+   * Return this DTM's lexical handler.
+   *
+   * %REVIEW% Should this return null if constrution already done/begun?
+   *
+   * @return null if this model doesn't respond to lexical SAX events,
+   * "this" if the DTM object has a built-in SAX ContentHandler,
+   * the IncrementalSAXSource if we're bound to one and should receive
+   * the SAX stream via it for incremental build purposes...
+   */
+  public LexicalHandler getLexicalHandler()
+  {
+
+    if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter)
+      return (LexicalHandler) m_incrementalSAXSource;
+    else
+      return this;
+  }
+
+  /**
+   * Return this DTM's EntityResolver.
+   *
+   * @return null if this model doesn't respond to SAX entity ref events.
+   */
+  public EntityResolver getEntityResolver()
+  {
+    return this;
+  }
+
+  /**
+   * Return this DTM's DTDHandler.
+   *
+   * @return null if this model doesn't respond to SAX dtd events.
+   */
+  public DTDHandler getDTDHandler()
+  {
+    return this;
+  }
+
+  /**
+   * Return this DTM's ErrorHandler.
+   *
+   * @return null if this model doesn't respond to SAX error events.
+   */
+  public ErrorHandler getErrorHandler()
+  {
+    return this;
+  }
+
+  /**
+   * Return this DTM's DeclHandler.
+   *
+   * @return null if this model doesn't respond to SAX Decl events.
+   */
+  public DeclHandler getDeclHandler()
+  {
+    return this;
+  }
+
+  /**
+   * @return true iff we're building this model incrementally (eg
+   * we're partnered with a IncrementalSAXSource) and thus require that the
+   * transformation and the parse run simultaneously. Guidance to the
+   * DTMManager.
+   */
+  public boolean needsTwoThreads()
+  {
+    return null != m_incrementalSAXSource;
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value). Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   * @param normalize true if the content should be normalized according to
+   * the rules for the XPath
+   * <a href="http://www.w3.org/TR/xpath#function-normalize-space">normalize-space</a>
+   * function.
+   *
+   * @throws SAXException
+   */
+  public void dispatchCharactersEvents(int nodeHandle, ContentHandler ch,
+                                       boolean normalize)
+          throws SAXException
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    
+    if (identity == DTM.NULL)
+      return;
+    
+    int type = _type(identity);
+
+    if (isTextType(type))
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+      int offset = m_data.elementAt(dataIndex);
+      int length = m_data.elementAt(dataIndex + 1);
+
+      if(normalize)
+        m_chars.sendNormalizedSAXcharacters(ch, offset, length);
+      else
+        m_chars.sendSAXcharacters(ch, offset, length);
+    }
+    else
+    {
+      int firstChild = _firstch(identity);
+
+      if (DTM.NULL != firstChild)
+      {
+        int offset = -1;
+        int length = 0;
+        int startNode = identity;
+
+        identity = firstChild;
+
+        do {
+          type = _type(identity);
+
+          if (isTextType(type))
+          {
+            int dataIndex = _dataOrQName(identity);
+
+            if (-1 == offset)
+            {
+              offset = m_data.elementAt(dataIndex);
+            }
+
+            length += m_data.elementAt(dataIndex + 1);
+          }
+
+          identity = getNextNodeIdentity(identity);
+        } while (DTM.NULL != identity && (_parent(identity) >= startNode));
+
+        if (length > 0)
+        {
+          if(normalize)
+            m_chars.sendNormalizedSAXcharacters(ch, offset, length);
+          else
+            m_chars.sendSAXcharacters(ch, offset, length);
+        }
+      }
+      else if(type != DTM.ELEMENT_NODE)
+      {
+        int dataIndex = _dataOrQName(identity);
+
+        if (dataIndex < 0)
+        {
+          dataIndex = -dataIndex;
+          dataIndex = m_data.elementAt(dataIndex + 1);
+        }
+
+        String str = m_valuesOrPrefixes.indexToString(dataIndex);
+
+          if(normalize)
+            FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
+                                                         0, str.length(), ch);
+          else
+            ch.characters(str.toCharArray(), 0, str.length());
+      }
+    }
+  }
+
+
+  /**
+   * Given a node handle, return its DOM-style node name. This will
+   * include names such as #text or #document.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   * %REVIEW% Document when empty string is possible...
+   * %REVIEW-COMMENT% It should never be empty, should it?
+   */
+  public String getNodeName(int nodeHandle)
+  {
+
+    int expandedTypeID = getExpandedTypeID(nodeHandle);
+    // If just testing nonzero, no need to shift...
+    int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);                     
+
+    if (0 == namespaceID)
+    {
+      // Don't retrieve name until/unless needed
+      // String name = m_expandedNameTable.getLocalName(expandedTypeID);
+      int type = getNodeType(nodeHandle);
+
+      if (type == DTM.NAMESPACE_NODE)
+      {
+        if (null == m_expandedNameTable.getLocalName(expandedTypeID))
+          return "xmlns";
+        else
+          return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID);
+      }
+      else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID))
+      {
+        return m_fixednames[type];
+      }
+      else
+        return m_expandedNameTable.getLocalName(expandedTypeID);
+    }
+    else
+    {
+      int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
+
+      if (qnameIndex < 0)
+      {
+        qnameIndex = -qnameIndex;
+        qnameIndex = m_data.elementAt(qnameIndex);
+      }
+
+      return m_valuesOrPrefixes.indexToString(qnameIndex);
+    }
+  }
+
+  /**
+   * Given a node handle, return the XPath node name.  This should be
+   * the name as described by the XPath data model, NOT the DOM-style
+   * name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   */
+  public String getNodeNameX(int nodeHandle)
+  {
+
+    int expandedTypeID = getExpandedTypeID(nodeHandle);    
+    int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);                      
+
+    if (0 == namespaceID)
+    {
+      String name = m_expandedNameTable.getLocalName(expandedTypeID);
+
+      if (name == null)
+        return "";
+      else
+        return name;
+    }
+    else
+    {
+      int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
+
+      if (qnameIndex < 0)
+      {
+        qnameIndex = -qnameIndex;
+        qnameIndex = m_data.elementAt(qnameIndex);
+      }
+
+      return m_valuesOrPrefixes.indexToString(qnameIndex);
+    }
+  }
+
+  /**
+   *     5. [specified] A flag indicating whether this attribute was actually
+   *        specified in the start-tag of its element, or was defaulted from the
+   *        DTD.
+   *
+   * @param attributeHandle Must be a valid handle to an attribute node.
+   * @return <code>true</code> if the attribute was specified;
+   *         <code>false</code> if it was defaulted.
+   */
+  public boolean isAttributeSpecified(int attributeHandle)
+  {
+
+    // I'm not sure if I want to do anything with this...
+    return true;  // ??
+  }
+
+  /**
+   *   A document type declaration information item has the following properties:
+   *
+   *     1. [system identifier] The system identifier of the external subset, if
+   *        it exists. Otherwise this property has no value.
+   *
+   * @return the system identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationSystemIdentifier()
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMDefaultBase abstract method */
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!");
+
+    return null;
+  }
+
+  /**
+   * Get the next node identity value in the list, and call the iterator
+   * if it hasn't been added yet.
+   *
+   * @param identity The node identity (index).
+   * @return identity+1, or DTM.NULL.
+   */
+  protected int getNextNodeIdentity(int identity)
+  {
+
+    identity += 1;
+
+    while (identity >= m_size)
+    {
+      if (null == m_incrementalSAXSource)
+        return DTM.NULL;
+
+      nextNode();
+    }
+
+    return identity;
+  }
+
+  /**
+   * Directly create SAX parser events from a subtree.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+
+    DTMTreeWalker treeWalker = m_walker;
+    ContentHandler prevCH = treeWalker.getcontentHandler();
+
+    if (null != prevCH)
+    {
+      treeWalker = new DTMTreeWalker();
+    }
+
+    treeWalker.setcontentHandler(ch);
+    treeWalker.setDTM(this);
+
+    try
+    {
+      treeWalker.traverse(nodeHandle);
+    }
+    finally
+    {
+      treeWalker.setcontentHandler(null);
+    }
+  }
+
+  /**
+   * Get the number of nodes that have been added.
+   *
+   * @return The number of that are currently in the tree.
+   */
+  public int getNumberOfNodes()
+  {
+    return m_size;
+  }
+
+  /**
+   * This method should try and build one or more nodes in the table.
+   *
+   * @return The true if a next node is found or false if
+   *         there are no more nodes.
+   */
+  protected boolean nextNode()
+  {
+
+    if (null == m_incrementalSAXSource)
+      return false;
+
+    if (m_endDocumentOccured)
+    {
+      clearCoRoutine();
+
+      return false;
+    }
+
+    Object gotMore = m_incrementalSAXSource.deliverMoreNodes(true);
+
+    // gotMore may be a Boolean (TRUE if still parsing, FALSE if
+    // EOF) or an exception if IncrementalSAXSource malfunctioned
+    // (code error rather than user error).
+    //
+    // %REVIEW% Currently the ErrorHandlers sketched herein are
+    // no-ops, so I'm going to initially leave this also as a
+    // no-op.
+    if (!(gotMore instanceof Boolean))
+    {
+      if(gotMore instanceof RuntimeException)
+      {
+        throw (RuntimeException)gotMore;
+      }
+      else if(gotMore instanceof Exception)
+      {
+        throw new WrappedRuntimeException((Exception)gotMore);
+      }
+      // for now...
+      clearCoRoutine();
+
+      return false;
+
+      // %TBD%
+    }
+
+    if (gotMore != Boolean.TRUE)
+    {
+
+      // EOF reached without satisfying the request
+      clearCoRoutine();  // Drop connection, stop trying
+
+      // %TBD% deregister as its listener?
+    }
+
+    return true;
+  }
+
+  /**
+   * Bottleneck determination of text type.
+   *
+   * @param type oneof DTM.XXX_NODE.
+   *
+   * @return true if this is a text or cdata section.
+   */
+  private final boolean isTextType(int type)
+  {
+    return (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type);
+  }
+
+//    /**
+//     * Ensure that the size of the information arrays can hold another entry
+//     * at the given index.
+//     *
+//     * @param on exit from this function, the information arrays sizes must be
+//     * at least index+1.
+//     *
+//     * NEEDSDOC @param index
+//     */
+//    protected void ensureSize(int index)
+//    {
+//          // dataOrQName is an SuballocatedIntVector and hence self-sizing.
+//          // But DTMDefaultBase may need fixup.
+//        super.ensureSize(index);
+//    }
+
+  /**
+   * Construct the node map from the node.
+   *
+   * @param type raw type ID, one of DTM.XXX_NODE.
+   * @param expandedTypeID The expended type ID.
+   * @param parentIndex The current parent index.
+   * @param previousSibling The previous sibling index.
+   * @param dataOrPrefix index into m_data table, or string handle.
+   * @param canHaveFirstChild true if the node can have a first child, false
+   *                          if it is atomic.
+   *
+   * @return The index identity of the node that was added.
+   */
+  protected int addNode(int type, int expandedTypeID,
+                        int parentIndex, int previousSibling,
+                        int dataOrPrefix, boolean canHaveFirstChild)
+  {
+    // Common to all nodes:
+    int nodeIndex = m_size++;
+
+    // Have we overflowed a DTM Identity's addressing range?
+    if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
+    {
+      addNewDTMID(nodeIndex);
+    }
+
+    m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL);
+    m_nextsib.addElement(NOTPROCESSED);
+    m_parent.addElement(parentIndex);
+    m_exptype.addElement(expandedTypeID);
+    m_dataOrQName.addElement(dataOrPrefix);
+
+    if (m_prevsib != null) {
+      m_prevsib.addElement(previousSibling);
+    }
+
+    if (DTM.NULL != previousSibling) {
+      m_nextsib.setElementAt(nodeIndex,previousSibling);
+    }
+
+    if (m_locator != null && m_useSourceLocationProperty) {
+      setSourceLocation();
+    }
+
+    // Note that nextSibling is not processed until charactersFlush()
+    // is called, to handle successive characters() events.
+
+    // Special handling by type: Declare namespaces, attach first child
+    switch(type)
+    {
+    case DTM.NAMESPACE_NODE:
+      declareNamespaceInContext(parentIndex,nodeIndex);
+      break;
+    case DTM.ATTRIBUTE_NODE:
+      break;
+    default:
+      if (DTM.NULL == previousSibling && DTM.NULL != parentIndex) {
+        m_firstch.setElementAt(nodeIndex,parentIndex);
+      }
+      break;
+    }
+
+    return nodeIndex;
+  }
+
+  /**
+   * Get a new DTM ID beginning at the specified node index.
+   * @param  nodeIndex The node identity at which the new DTM ID will begin
+   * addressing.
+   */
+  protected void addNewDTMID(int nodeIndex) {
+    try
+    {
+      if(m_mgr==null)
+        throw new ClassCastException();
+                              
+                              // Handle as Extended Addressing
+      DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr;
+      int id=mgrD.getFirstFreeDTMID();
+      mgrD.addDTM(this,id,nodeIndex);
+      m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS);
+    }
+    catch(ClassCastException e)
+    {
+      // %REVIEW% Wrong error message, but I've been told we're trying
+      // not to add messages right not for I18N reasons.
+      // %REVIEW% Should this be a Fatal Error?
+      error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null));//"No more DTM IDs are available";
+    }
+  }
+
+  /**
+    * Migrate a DTM built with an old DTMManager to a new DTMManager.
+    * After the migration, the new DTMManager will treat the DTM as
+    * one that is built by itself.
+    * This is used to support DTM sharing between multiple transformations.
+    * @param manager the DTMManager
+    */
+  public void migrateTo(DTMManager manager) {
+    super.migrateTo(manager);
+    
+    // We have to reset the information in m_dtmIdent and
+    // register the DTM with the new manager. 
+    int numDTMs = m_dtmIdent.size();
+    int dtmId = m_mgrDefault.getFirstFreeDTMID();
+    int nodeIndex = 0;
+    for (int i = 0; i < numDTMs; i++)
+    {     
+      m_dtmIdent.setElementAt(dtmId << DTMManager.IDENT_DTM_NODE_BITS, i);
+      m_mgrDefault.addDTM(this, dtmId, nodeIndex);
+      dtmId++;
+      nodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);
+    }
+  }
+
+  /**
+   * Store the source location of the current node.  This method must be called
+   * as every node is added to the DTM or for no node.
+   */
+  protected void setSourceLocation() {
+    m_sourceSystemId.addElement(m_locator.getSystemId());
+    m_sourceLine.addElement(m_locator.getLineNumber());
+    m_sourceColumn.addElement(m_locator.getColumnNumber());
+
+    //%REVIEW% %BUG% Prevent this from arising in the first place
+    // by not allowing the enabling conditions to change after we start
+    // building the document.
+    if (m_sourceSystemId.size() != m_size) {
+        String msg = "CODING ERROR in Source Location: " + m_size + " != "
+                    + m_sourceSystemId.size();
+        System.err.println(msg);
+        throw new RuntimeException(msg);
+    }
+  }
+
+  /**
+   * Given a node handle, return its node value. This is mostly
+   * as defined by the DOM, but may ignore some conveniences.
+   * <p>
+   *
+   * @param nodeHandle The node id.
+   * @return String Value of this node, or null if not
+   * meaningful for this node type.
+   */
+  public String getNodeValue(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int type = _type(identity);
+
+    if (isTextType(type))
+    {
+      int dataIndex = _dataOrQName(identity);
+      int offset = m_data.elementAt(dataIndex);
+      int length = m_data.elementAt(dataIndex + 1);
+
+      // %OPT% We should cache this, I guess.
+      return m_chars.getString(offset, length);
+    }
+    else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type
+             || DTM.DOCUMENT_NODE == type)
+    {
+      return null;
+    }
+    else
+    {
+      int dataIndex = _dataOrQName(identity);
+
+      if (dataIndex < 0)
+      {
+        dataIndex = -dataIndex;
+        dataIndex = m_data.elementAt(dataIndex + 1);
+      }
+
+      return m_valuesOrPrefixes.indexToString(dataIndex);
+    }
+  }
+
+  /**
+   * Given a node handle, return its XPath-style localname.
+   * (As defined in Namespaces, this is the portion of the name after any
+   * colon character).
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Local name of this node.
+   */
+  public String getLocalName(int nodeHandle)
+  {
+    return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle)));
+  }
+
+  /**
+   * The getUnparsedEntityURI function returns the URI of the unparsed
+   * entity with the specified name in the same document as the context
+   * node (see [3.3 Unparsed Entities]). It returns the empty string if
+   * there is no such entity.
+   * <p>
+   * XML processors may choose to use the System Identifier (if one
+   * is provided) to resolve the entity, rather than the URI in the
+   * Public Identifier. The details are dependent on the processor, and
+   * we would have to support some form of plug-in resolver to handle
+   * this properly. Currently, we simply return the System Identifier if
+   * present, and hope that it a usable URI or that our caller can
+   * map it to one.
+   * TODO: Resolve Public Identifiers... or consider changing function name.
+   * <p>
+   * If we find a relative URI
+   * reference, XML expects it to be resolved in terms of the base URI
+   * of the document. The DOM doesn't do that for us, and it isn't
+   * entirely clear whether that should be done here; currently that's
+   * pushed up to a higher level of our application. (Note that DOM Level
+   * 1 didn't store the document's base URI.)
+   * TODO: Consider resolving Relative URIs.
+   * <p>
+   * (The DOM's statement that "An XML processor may choose to
+   * completely expand entities before the structure model is passed
+   * to the DOM" refers only to parsed entities, not unparsed, and hence
+   * doesn't affect this function.)
+   *
+   * @param name A string containing the Entity Name of the unparsed
+   * entity.
+   *
+   * @return String containing the URI of the Unparsed Entity, or an
+   * empty string if no such entity exists.
+   */
+  public String getUnparsedEntityURI(String name)
+  {
+
+    String url = "";
+
+    if (null == m_entities)
+      return url;
+
+    int n = m_entities.size();
+
+    for (int i = 0; i < n; i += ENTITY_FIELDS_PER)
+    {
+      String ename = (String) m_entities.elementAt(i + ENTITY_FIELD_NAME);
+
+      if (null != ename && ename.equals(name))
+      {
+        String nname = (String) m_entities.elementAt(i
+                         + ENTITY_FIELD_NOTATIONNAME);
+
+        if (null != nname)
+        {
+
+          // The draft says: "The XSLT processor may use the public
+          // identifier to generate a URI for the entity instead of the URI
+          // specified in the system identifier. If the XSLT processor does
+          // not use the public identifier to generate the URI, it must use
+          // the system identifier; if the system identifier is a relative
+          // URI, it must be resolved into an absolute URI using the URI of
+          // the resource containing the entity declaration as the base
+          // URI [RFC2396]."
+          // So I'm falling a bit short here.
+          url = (String) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID);
+
+          if (null == url)
+          {
+            url = (String) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID);
+          }
+        }
+
+        break;
+      }
+    }
+
+    return url;
+  }
+
+  /**
+   * Given a namespace handle, return the prefix that the namespace decl is
+   * mapping.
+   * Given a node handle, return the prefix used to map to the namespace.
+   *
+   * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
+   * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb  </p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String prefix of this node's name, or "" if no explicit
+   * namespace prefix was given.
+   */
+  public String getPrefix(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int type = _type(identity);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      int prefixIndex = _dataOrQName(identity);
+
+      if (0 == prefixIndex)
+        return "";
+      else
+      {
+        String qname = m_valuesOrPrefixes.indexToString(prefixIndex);
+
+        return getPrefix(qname, null);
+      }
+    }
+    else if (DTM.ATTRIBUTE_NODE == type)
+    {
+      int prefixIndex = _dataOrQName(identity);
+
+      if (prefixIndex < 0)
+      {
+        prefixIndex = m_data.elementAt(-prefixIndex);
+
+        String qname = m_valuesOrPrefixes.indexToString(prefixIndex);
+
+        return getPrefix(qname, null);
+      }
+    }
+
+    return "";
+  }
+
+  /**
+   * Retrieves an attribute node by by qualified name and namespace URI.
+   *
+   * @param nodeHandle int Handle of the node upon which to look up this attribute..
+   * @param namespaceURI The namespace URI of the attribute to
+   *   retrieve, or null.
+   * @param name The local name of the attribute to
+   *   retrieve.
+   * @return The attribute node handle with the specified name (
+   *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
+   *   attribute.
+   */
+  public int getAttributeNode(int nodeHandle, String namespaceURI,
+                              String name)
+  {
+
+    for (int attrH = getFirstAttribute(nodeHandle); DTM.NULL != attrH;
+            attrH = getNextAttribute(attrH))
+    {
+      String attrNS = getNamespaceURI(attrH);
+      String attrName = getLocalName(attrH);
+      boolean nsMatch = namespaceURI == attrNS
+                        || (namespaceURI != null
+                            && namespaceURI.equals(attrNS));
+
+      if (nsMatch && name.equals(attrName))
+        return attrH;
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Return the public identifier of the external subset,
+   * normalized as described in 4.2.2 External Entities [XML]. If there is
+   * no external subset or if it has no public identifier, this property
+   * has no value.
+   *
+   * @return the public identifier String object, or null if there is none.
+   */
+  public String getDocumentTypeDeclarationPublicIdentifier()
+  {
+
+    /** @todo: implement this org.apache.xml.dtm.DTMDefaultBase abstract method */
+    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!");
+
+    return null;
+  }
+
+  /**
+   * Given a node handle, return its DOM-style namespace URI
+   * (As defined in Namespaces, this is the declared URI which this node's
+   * prefix -- or default in lieu thereof -- was mapped to.)
+   *
+   * <p>%REVIEW% Null or ""? -sb</p>
+   *
+   * @param nodeHandle the id of the node.
+   * @return String URI value of this node's namespace, or null if no
+   * namespace was resolved.
+   */
+  public String getNamespaceURI(int nodeHandle)
+  {
+
+    return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle)));
+  }
+
+  /**
+   * Get the string-value of a node as a String object
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public XMLString getStringValue(int nodeHandle)
+  {
+    int identity = makeNodeIdentity(nodeHandle);
+    int type;
+    if(identity==DTM.NULL) // Separate lines because I wanted to breakpoint it
+      type = DTM.NULL;
+    else
+      type= _type(identity);
+
+    if (isTextType(type))
+    {
+      int dataIndex = _dataOrQName(identity);
+      int offset = m_data.elementAt(dataIndex);
+      int length = m_data.elementAt(dataIndex + 1);
+
+      return m_xstrf.newstr(m_chars, offset, length);
+    }
+    else
+    {
+      int firstChild = _firstch(identity);
+
+      if (DTM.NULL != firstChild)
+      {
+        int offset = -1;
+        int length = 0;
+        int startNode = identity;
+
+        identity = firstChild;
+
+        do {
+          type = _type(identity);
+
+          if (isTextType(type))
+          {
+            int dataIndex = _dataOrQName(identity);
+
+            if (-1 == offset)
+            {
+              offset = m_data.elementAt(dataIndex);
+            }
+
+            length += m_data.elementAt(dataIndex + 1);
+          }
+
+          identity = getNextNodeIdentity(identity);
+        } while (DTM.NULL != identity && (_parent(identity) >= startNode));
+
+        if (length > 0)
+        {
+          return m_xstrf.newstr(m_chars, offset, length);
+        }
+      }
+      else if(type != DTM.ELEMENT_NODE)
+      {
+        int dataIndex = _dataOrQName(identity);
+
+        if (dataIndex < 0)
+        {
+          dataIndex = -dataIndex;
+          dataIndex = m_data.elementAt(dataIndex + 1);
+        }
+        return m_xstrf.newstr(m_valuesOrPrefixes.indexToString(dataIndex));
+      }
+    }
+
+    return m_xstrf.emptystr();
+  }
+  
+  /**
+   * Determine if the string-value of a node is whitespace
+   *
+   * @param nodeHandle The node Handle.
+   *
+   * @return Return true if the given node is whitespace.
+   */
+  public boolean isWhitespace(int nodeHandle)
+  {
+    int identity = makeNodeIdentity(nodeHandle);
+    int type;
+    if(identity==DTM.NULL) // Separate lines because I wanted to breakpoint it
+      type = DTM.NULL;
+    else
+      type= _type(identity);
+
+    if (isTextType(type))
+    {
+      int dataIndex = _dataOrQName(identity);
+      int offset = m_data.elementAt(dataIndex);
+      int length = m_data.elementAt(dataIndex + 1);
+
+      return m_chars.isWhitespace(offset, length);
+    }
+    return false;
+  }
+
+  /**
+   * Returns the <code>Element</code> whose <code>ID</code> is given by
+   * <code>elementId</code>. If no such element exists, returns
+   * <code>DTM.NULL</code>. Behavior is not defined if more than one element
+   * has this <code>ID</code>. Attributes (including those
+   * with the name "ID") are not of type ID unless so defined by DTD/Schema
+   * information available to the DTM implementation.
+   * Implementations that do not know whether attributes are of type ID or
+   * not are expected to return <code>DTM.NULL</code>.
+   *
+   * <p>%REVIEW% Presumably IDs are still scoped to a single document,
+   * and this operation searches only within a single document, right?
+   * Wouldn't want collisions between DTMs in the same process.</p>
+   *
+   * @param elementId The unique <code>id</code> value for an element.
+   * @return The handle of the matching element.
+   */
+  public int getElementById(String elementId)
+  {
+
+    Integer intObj;
+    boolean isMore = true;
+
+    do
+    {
+      intObj = (Integer) m_idAttributes.get(elementId);
+
+      if (null != intObj)
+        return makeNodeHandle(intObj.intValue());
+
+      if (!isMore || m_endDocumentOccured)
+        break;
+
+      isMore = nextNode();
+    }
+    while (null == intObj);
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Get a prefix either from the qname or from the uri mapping, or just make
+   * one up!
+   *
+   * @param qname The qualified name, which may be null.
+   * @param uri The namespace URI, which may be null.
+   *
+   * @return The prefix if there is one, or null.
+   */
+  public String getPrefix(String qname, String uri)
+  {
+
+    String prefix;
+    int uriIndex = -1;
+
+    if (null != uri && uri.length() > 0)
+    {
+
+      do
+      {
+        uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex);
+      } while ( (uriIndex & 0x01) == 0);
+
+      if (uriIndex >= 0)
+      {
+        prefix = (String) m_prefixMappings.elementAt(uriIndex - 1);
+      }
+      else if (null != qname)
+      {
+        int indexOfNSSep = qname.indexOf(':');
+
+        if (qname.equals("xmlns"))
+          prefix = "";
+        else if (qname.startsWith("xmlns:"))
+          prefix = qname.substring(indexOfNSSep + 1);
+        else
+          prefix = (indexOfNSSep > 0)
+                   ? qname.substring(0, indexOfNSSep) : null;
+      }
+      else
+      {
+        prefix = null;
+      }
+    }
+    else if (null != qname)
+    {
+      int indexOfNSSep = qname.indexOf(':');
+
+      if (indexOfNSSep > 0)
+      {
+        if (qname.startsWith("xmlns:"))
+          prefix = qname.substring(indexOfNSSep + 1);
+        else
+          prefix = qname.substring(0, indexOfNSSep);	
+      }
+      else
+      {
+      	if (qname.equals("xmlns"))
+      	  prefix = "";
+      	else
+      	  prefix = null;
+      }
+    }
+    else
+    {
+      prefix = null;
+    }
+
+    return prefix;
+  }
+  
+  /**
+   * Get a prefix either from the uri mapping, or just make
+   * one up!
+   *
+   * @param uri The namespace URI, which may be null.
+   *
+   * @return The prefix if there is one, or null.
+   */
+  public int getIdForNamespace(String uri)
+  {
+
+     return m_valuesOrPrefixes.stringToIndex(uri);
+    
+  }
+
+    /**
+   * Get a prefix either from the qname or from the uri mapping, or just make
+   * one up!
+   *
+   * @return The prefix if there is one, or null.
+   */
+  public String getNamespaceURI(String prefix)
+  {
+
+    String uri = "";
+    int prefixIndex = m_contextIndexes.peek() - 1 ;
+
+    if(null == prefix)
+      prefix = "";
+
+      do
+      {
+        prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex);
+      } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01);
+
+      if (prefixIndex > -1)
+      {
+        uri = (String) m_prefixMappings.elementAt(prefixIndex + 1);
+      }
+
+
+    return uri;
+  }
+
+  /**
+   * Set an ID string to node association in the ID table.
+   *
+   * @param id The ID string.
+   * @param elem The associated element handle.
+   */
+  public void setIDAttribute(String id, int elem)
+  {
+    m_idAttributes.put(id, new Integer(elem));
+  }
+
+  /**
+   * Check whether accumulated text should be stripped; if not,
+   * append the appropriate flavor of text/cdata node.
+   */
+  protected void charactersFlush()
+  {
+
+    if (m_textPendingStart >= 0)  // -1 indicates no-text-in-progress
+    {
+      int length = m_chars.size() - m_textPendingStart;
+      boolean doStrip = false;
+
+      if (getShouldStripWhitespace())
+      {
+        doStrip = m_chars.isWhitespace(m_textPendingStart, length);
+      }
+
+      if (doStrip) {
+        m_chars.setLength(m_textPendingStart);  // Discard accumulated text
+      } else {
+        // Guard against characters/ignorableWhitespace events that
+        // contained no characters.  They should not result in a node.
+        if (length > 0) {
+          int exName = m_expandedNameTable.getExpandedTypeID(DTM.TEXT_NODE);
+          int dataIndex = m_data.size();
+
+          m_previous = addNode(m_coalescedTextType, exName,
+                               m_parents.peek(), m_previous, dataIndex, false);
+
+          m_data.addElement(m_textPendingStart);
+          m_data.addElement(length);
+        }
+      }
+
+      // Reset for next text block
+      m_textPendingStart = -1;
+      m_textType = m_coalescedTextType = DTM.TEXT_NODE;
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the EntityResolver interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Resolve an external entity.
+   *
+   * <p>Always return null, so that the parser will use the system
+   * identifier provided in the XML document.  This method implements
+   * the SAX default behaviour: application writers can override it
+   * in a subclass to do special translations such as catalog lookups
+   * or URI redirection.</p>
+   *
+   * @param publicId The public identifer, or null if none is
+   *                 available.
+   * @param systemId The system identifier provided in the XML
+   *                 document.
+   * @return The new input source, or null to require the
+   *         default behaviour.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.EntityResolver#resolveEntity
+   *
+   * @throws SAXException
+   */
+  public InputSource resolveEntity(String publicId, String systemId)
+          throws SAXException
+  {
+    return null;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of DTDHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive notification of a notation declaration.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass if they wish to keep track of the notations
+   * declared in a document.</p>
+   *
+   * @param name The notation name.
+   * @param publicId The notation public identifier, or null if not
+   *                 available.
+   * @param systemId The notation system identifier.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.DTDHandler#notationDecl
+   *
+   * @throws SAXException
+   */
+  public void notationDecl(String name, String publicId, String systemId)
+          throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Receive notification of an unparsed entity declaration.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to keep track of the unparsed entities
+   * declared in a document.</p>
+   *
+   * @param name The entity name.
+   * @param publicId The entity public identifier, or null if not
+   *                 available.
+   * @param systemId The entity system identifier.
+   * @param notationName The name of the associated notation.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   *
+   * @throws SAXException
+   */
+  public void unparsedEntityDecl(
+          String name, String publicId, String systemId, String notationName)
+            throws SAXException
+  {
+
+    if (null == m_entities)
+    {
+      m_entities = new Vector();
+    }
+
+    try
+    {
+      systemId = SystemIDResolver.getAbsoluteURI(systemId,
+                                                 getDocumentBaseURI());
+    }
+    catch (Exception e)
+    {
+      throw new org.xml.sax.SAXException(e);
+    }
+
+    //  private static final int ENTITY_FIELD_PUBLICID = 0;
+    m_entities.addElement(publicId);
+
+    //  private static final int ENTITY_FIELD_SYSTEMID = 1;
+    m_entities.addElement(systemId);
+
+    //  private static final int ENTITY_FIELD_NOTATIONNAME = 2;
+    m_entities.addElement(notationName);
+
+    //  private static final int ENTITY_FIELD_NAME = 3;
+    m_entities.addElement(name);
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of ContentHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive a Locator object for document events.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass if they wish to store the locator for use
+   * with other document events.</p>
+   *
+   * @param locator A locator for all SAX document events.
+   * @see org.xml.sax.ContentHandler#setDocumentLocator
+   * @see org.xml.sax.Locator
+   */
+  public void setDocumentLocator(Locator locator)
+  {
+    m_locator = locator;
+    m_systemId = locator.getSystemId();
+  }
+
+  /**
+   * Receive notification of the beginning of the document.
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startDocument
+   */
+  public void startDocument() throws SAXException
+  {
+    if (DEBUG)
+      System.out.println("startDocument");
+
+		
+    int doc = addNode(DTM.DOCUMENT_NODE,
+                      m_expandedNameTable.getExpandedTypeID(DTM.DOCUMENT_NODE),
+                      DTM.NULL, DTM.NULL, 0, true);
+
+    m_parents.push(doc);
+    m_previous = DTM.NULL;
+
+    m_contextIndexes.push(m_prefixMappings.size());  // for the next element.
+  }
+
+  /**
+   * Receive notification of the end of the document.
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endDocument
+   */
+  public void endDocument() throws SAXException
+  {
+    if (DEBUG)
+      System.out.println("endDocument");
+
+		charactersFlush();
+
+    m_nextsib.setElementAt(NULL,0);
+
+    if (m_firstch.elementAt(0) == NOTPROCESSED)
+      m_firstch.setElementAt(NULL,0);
+
+    if (DTM.NULL != m_previous)
+      m_nextsib.setElementAt(DTM.NULL,m_previous);
+
+    m_parents = null;
+    m_prefixMappings = null;
+    m_contextIndexes = null;
+
+    m_endDocumentOccured = true;
+    
+    // Bugzilla 4858: throw away m_locator. we cache m_systemId
+    m_locator = null;
+  }
+
+  /**
+   * Receive notification of the start of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each Namespace prefix scope (such as storing the prefix mapping).</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @param uri The Namespace URI mapped to the prefix.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startPrefixMapping
+   */
+  public void startPrefixMapping(String prefix, String uri)
+          throws SAXException
+  {
+
+    if (DEBUG)
+      System.out.println("startPrefixMapping: prefix: " + prefix + ", uri: "
+                         + uri);
+
+    if(null == prefix)
+      prefix = "";
+    m_prefixMappings.addElement(prefix);  // JDK 1.1.x compat -sc
+    m_prefixMappings.addElement(uri);  // JDK 1.1.x compat -sc
+  }
+
+  /**
+   * Receive notification of the end of a Namespace mapping.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end of
+   * each prefix mapping.</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endPrefixMapping
+   */
+  public void endPrefixMapping(String prefix) throws SAXException
+  {
+    if (DEBUG)
+      System.out.println("endPrefixMapping: prefix: " + prefix);
+
+    if(null == prefix)
+      prefix = "";
+
+    int index = m_contextIndexes.peek() - 1;
+
+    do
+    {
+      index = m_prefixMappings.indexOf(prefix, ++index);
+    } while ( (index >= 0) && ((index & 0x01) == 0x01) );
+
+
+    if (index > -1)
+    {
+      m_prefixMappings.setElementAt("%@$#^@#", index);
+      m_prefixMappings.setElementAt("%@$#^@#", index + 1);
+    }
+
+    // no op
+  }
+
+  /**
+   * Check if a declaration has already been made for a given prefix.
+   *
+   * @param prefix non-null prefix string.
+   *
+   * @return true if the declaration has already been declared in the
+   *         current context.
+   */
+  protected boolean declAlreadyDeclared(String prefix)
+  {
+
+    int startDecls = m_contextIndexes.peek();
+    java.util.Vector prefixMappings = m_prefixMappings;
+    int nDecls = prefixMappings.size();
+
+    for (int i = startDecls; i < nDecls; i += 2)
+    {
+      String prefixDecl = (String) prefixMappings.elementAt(i);
+
+      if (prefixDecl == null)
+        continue;
+
+      if (prefixDecl.equals(prefix))
+        return true;
+    }
+
+    return false;
+  }
+
+	boolean m_pastFirstElement=false;
+
+  /**
+   * Receive notification of the start of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each element (such as allocating a new tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @param attributes The specified or defaulted attributes.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startElement
+   */
+  public void startElement(
+          String uri, String localName, String qName, Attributes attributes)
+            throws SAXException
+  {
+   if (DEBUG)
+	 {
+      System.out.println("startElement: uri: " + uri + ", localname: "
+												 + localName + ", qname: "+qName+", atts: " + attributes);
+
+			boolean DEBUG_ATTRS=true;
+			if(DEBUG_ATTRS & attributes!=null)
+			{
+				int n = attributes.getLength();
+				if(n==0)
+					System.out.println("\tempty attribute list");
+				else for (int i = 0; i < n; i++)
+					System.out.println("\t attr: uri: " + attributes.getURI(i) +
+														 ", localname: " + attributes.getLocalName(i) +
+														 ", qname: " + attributes.getQName(i) +
+														 ", type: " + attributes.getType(i) +
+														 ", value: " + attributes.getValue(i)
+														 );
+			}
+	 }
+		
+    charactersFlush();
+
+    int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
+    String prefix = getPrefix(qName, uri);
+    int prefixIndex = (null != prefix)
+                      ? m_valuesOrPrefixes.stringToIndex(qName) : 0;
+
+    int elemNode = addNode(DTM.ELEMENT_NODE, exName,
+                           m_parents.peek(), m_previous, prefixIndex, true);
+
+    if(m_indexing)
+      indexNode(exName, elemNode);
+    
+
+    m_parents.push(elemNode);
+
+    int startDecls = m_contextIndexes.peek();
+    int nDecls = m_prefixMappings.size();
+    int prev = DTM.NULL;
+
+    if(!m_pastFirstElement)
+    {
+      // SPECIAL CASE: Implied declaration at root element
+      prefix="xml";
+      String declURL = "http://www.w3.org/XML/1998/namespace";
+      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
+      int val = m_valuesOrPrefixes.stringToIndex(declURL);
+      prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode,
+                     prev, val, false);
+      m_pastFirstElement=true;
+    }
+
+    for (int i = startDecls; i < nDecls; i += 2)
+    {
+      prefix = (String) m_prefixMappings.elementAt(i);
+
+      if (prefix == null)
+        continue;
+
+      String declURL = (String) m_prefixMappings.elementAt(i + 1);
+
+      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
+
+      int val = m_valuesOrPrefixes.stringToIndex(declURL);
+
+      prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode,
+                     prev, val, false);
+    }
+
+    int n = attributes.getLength();
+
+    for (int i = 0; i < n; i++)
+    {
+      String attrUri = attributes.getURI(i);
+      String attrQName = attributes.getQName(i);
+      String valString = attributes.getValue(i);
+
+      prefix = getPrefix(attrQName, attrUri);
+
+      int nodeType;
+      
+       String attrLocalName = attributes.getLocalName(i);
+
+      if ((null != attrQName)
+              && (attrQName.equals("xmlns")
+                  || attrQName.startsWith("xmlns:")))
+      {
+        if (declAlreadyDeclared(prefix))
+          continue;  // go to the next attribute.
+
+        nodeType = DTM.NAMESPACE_NODE;
+      }
+      else
+      {
+        nodeType = DTM.ATTRIBUTE_NODE;
+
+        if (attributes.getType(i).equalsIgnoreCase("ID"))
+          setIDAttribute(valString, elemNode);
+      }
+
+      // Bit of a hack... if somehow valString is null, stringToIndex will
+      // return -1, which will make things very unhappy.
+      if(null == valString)
+        valString = "";
+
+      int val = m_valuesOrPrefixes.stringToIndex(valString);
+      //String attrLocalName = attributes.getLocalName(i);
+
+      if (null != prefix)
+      {
+
+        prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
+
+        int dataIndex = m_data.size();
+
+        m_data.addElement(prefixIndex);
+        m_data.addElement(val);
+
+        val = -dataIndex;
+      }
+
+      exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
+      prev = addNode(nodeType, exName, elemNode, prev, val,
+                     false);
+    }
+
+    if (DTM.NULL != prev)
+      m_nextsib.setElementAt(DTM.NULL,prev);
+
+    if (null != m_wsfilter)
+    {
+      short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
+      boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
+                            ? getShouldStripWhitespace()
+                            : (DTMWSFilter.STRIP == wsv);
+
+      pushShouldStripWhitespace(shouldStrip);
+    }
+
+    m_previous = DTM.NULL;
+
+    m_contextIndexes.push(m_prefixMappings.size());  // for the children.
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end of
+   * each element (such as finalising a tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified XML 1.0 name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endElement
+   */
+  public void endElement(String uri, String localName, String qName)
+          throws SAXException
+  {
+   if (DEBUG)
+      System.out.println("endElement: uri: " + uri + ", localname: "
+												 + localName + ", qname: "+qName);
+
+    charactersFlush();
+
+    // If no one noticed, startPrefixMapping is a drag.
+    // Pop the context for the last child (the one pushed by startElement)
+    m_contextIndexes.quickPop(1);
+
+    // Do it again for this one (the one pushed by the last endElement).
+    int topContextIndex = m_contextIndexes.peek();
+    if (topContextIndex != m_prefixMappings.size()) {
+      m_prefixMappings.setSize(topContextIndex);
+    }
+
+    int lastNode = m_previous;
+
+    m_previous = m_parents.pop();
+
+    // If lastNode is still DTM.NULL, this element had no children
+    if (DTM.NULL == lastNode)
+      m_firstch.setElementAt(DTM.NULL,m_previous);
+    else
+      m_nextsib.setElementAt(DTM.NULL,lastNode);
+
+    popShouldStripWhitespace();
+  }
+
+  /**
+   * Receive notification of character data inside an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method to take specific actions for each chunk of character data
+   * (such as adding the data to a node or buffer, or printing it to
+   * a file).</p>
+   *
+   * @param ch The characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#characters
+   */
+  public void characters(char ch[], int start, int length) throws SAXException
+  {
+    if (m_textPendingStart == -1)  // First one in this block
+    {
+      m_textPendingStart = m_chars.size();
+      m_coalescedTextType = m_textType;
+    }
+    // Type logic: If all adjacent text is CDATASections, the
+    // concatentated text is treated as a single CDATASection (see
+    // initialization above).  If any were ordinary Text, the whole
+    // thing is treated as Text. This may be worth %REVIEW%ing.
+    else if (m_textType == DTM.TEXT_NODE)
+    {
+      m_coalescedTextType = DTM.TEXT_NODE;
+    }
+
+    m_chars.append(ch, start, length);
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method to take specific actions for each chunk of ignorable
+   * whitespace (such as adding data to a node or buffer, or printing
+   * it to a file).</p>
+   *
+   * @param ch The whitespace characters.
+   * @param start The start position in the character array.
+   * @param length The number of characters to use from the
+   *               character array.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#ignorableWhitespace
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws SAXException
+  {
+
+    // %OPT% We can probably take advantage of the fact that we know this 
+    // is whitespace.
+    characters(ch, start, length);
+  }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   */
+  public void processingInstruction(String target, String data)
+          throws SAXException
+  {
+    if (DEBUG)
+		 System.out.println("processingInstruction: target: " + target +", data: "+data);
+
+    charactersFlush();
+
+    int exName = m_expandedNameTable.getExpandedTypeID(null, target,
+                                         DTM.PROCESSING_INSTRUCTION_NODE);
+    int dataIndex = m_valuesOrPrefixes.stringToIndex(data);
+
+    m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE, exName,
+                         m_parents.peek(), m_previous,
+                         dataIndex, false);
+  }
+
+  /**
+   * Receive notification of a skipped entity.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions for each
+   * processing instruction, such as setting status variables or
+   * invoking other methods.</p>
+   *
+   * @param name The name of the skipped entity.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   */
+  public void skippedEntity(String name) throws SAXException
+  {
+
+    // %REVIEW% What should be done here?
+    // no op
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the ErrorHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Receive notification of a parser warning.
+   *
+   * <p>The default implementation does nothing.  Application writers
+   * may override this method in a subclass to take specific actions
+   * for each warning, such as inserting the message in a log file or
+   * printing it to the console.</p>
+   *
+   * @param e The warning information encoded as an exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ErrorHandler#warning
+   * @see org.xml.sax.SAXParseException
+   */
+  public void warning(SAXParseException e) throws SAXException
+  {
+
+    // %REVIEW% Is there anyway to get the JAXP error listener here?
+    System.err.println(e.getMessage());
+  }
+
+  /**
+   * Receive notification of a recoverable parser error.
+   *
+   * <p>The default implementation does nothing.  Application writers
+   * may override this method in a subclass to take specific actions
+   * for each error, such as inserting the message in a log file or
+   * printing it to the console.</p>
+   *
+   * @param e The warning information encoded as an exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ErrorHandler#warning
+   * @see org.xml.sax.SAXParseException
+   */
+  public void error(SAXParseException e) throws SAXException
+  {
+    throw e;
+  }
+
+  /**
+   * Report a fatal XML parsing error.
+   *
+   * <p>The default implementation throws a SAXParseException.
+   * Application writers may override this method in a subclass if
+   * they need to take specific actions for each fatal error (such as
+   * collecting all of the errors into a single report): in any case,
+   * the application must stop all regular processing when this
+   * method is invoked, since the document is no longer reliable, and
+   * the parser may no longer report parsing events.</p>
+   *
+   * @param e The error information encoded as an exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ErrorHandler#fatalError
+   * @see org.xml.sax.SAXParseException
+   */
+  public void fatalError(SAXParseException e) throws SAXException
+  {
+    throw e;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the DeclHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Report an element type declaration.
+   *
+   * <p>The content model will consist of the string "EMPTY", the
+   * string "ANY", or a parenthesised group, optionally followed
+   * by an occurrence indicator.  The model will be normalized so
+   * that all whitespace is removed,and will include the enclosing
+   * parentheses.</p>
+   *
+   * @param name The element type name.
+   * @param model The content model as a normalized string.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void elementDecl(String name, String model) throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Report an attribute type declaration.
+   *
+   * <p>Only the effective (first) declaration for an attribute will
+   * be reported.  The type will be one of the strings "CDATA",
+   * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+   * "ENTITIES", or "NOTATION", or a parenthesized token group with
+   * the separator "|" and all whitespace removed.</p>
+   *
+   * @param eName The name of the associated element.
+   * @param aName The name of the attribute.
+   * @param type A string representing the attribute type.
+   * @param valueDefault A string representing the attribute default
+   *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+   *        none of these applies.
+   * @param value A string representing the attribute's default value,
+   *        or null if there is none.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void attributeDecl(
+          String eName, String aName, String type, String valueDefault, String value)
+            throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Report an internal entity declaration.
+   *
+   * <p>Only the effective (first) declaration for each entity
+   * will be reported.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @param value The replacement text of the entity.
+   * @throws SAXException The application may raise an exception.
+   * @see #externalEntityDecl
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void internalEntityDecl(String name, String value)
+          throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Report a parsed external entity declaration.
+   *
+   * <p>Only the effective (first) declaration for each entity
+   * will be reported.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @param publicId The declared public identifier of the entity, or
+   *        null if none was declared.
+   * @param systemId The declared system identifier of the entity.
+   * @throws SAXException The application may raise an exception.
+   * @see #internalEntityDecl
+   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+   */
+  public void externalEntityDecl(
+          String name, String publicId, String systemId) throws SAXException
+  {
+
+    // no op
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // Implementation of the LexicalHandler interface.
+  ////////////////////////////////////////////////////////////////////
+
+  /**
+   * Report the start of DTD declarations, if any.
+   *
+   * <p>Any declarations are assumed to be in the internal subset
+   * unless otherwise indicated by a {@link #startEntity startEntity}
+   * event.</p>
+   *
+   * <p>Note that the start/endDTD events will appear within
+   * the start/endDocument events from ContentHandler and
+   * before the first startElement event.</p>
+   *
+   * @param name The document type name.
+   * @param publicId The declared public identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @param systemId The declared system identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @throws SAXException The application may raise an
+   *            exception.
+   * @see #endDTD
+   * @see #startEntity
+   */
+  public void startDTD(String name, String publicId, String systemId)
+          throws SAXException
+  {
+
+    m_insideDTD = true;
+  }
+
+  /**
+   * Report the end of DTD declarations.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startDTD
+   */
+  public void endDTD() throws SAXException
+  {
+
+    m_insideDTD = false;
+  }
+
+  /**
+   * Report the beginning of an entity in content.
+   *
+   * <p><strong>NOTE:</entity> entity references in attribute
+   * values -- and the start and end of the document entity --
+   * are never reported.</p>
+   *
+   * <p>The start and end of the external DTD subset are reported
+   * using the pseudo-name "[dtd]".  All other events must be
+   * properly nested within start/end entity events.</p>
+   *
+   * <p>Note that skipped entities will be reported through the
+   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+   * event, which is part of the ContentHandler interface.</p>
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @throws SAXException The application may raise an exception.
+   * @see #endEntity
+   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+   */
+  public void startEntity(String name) throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Report the end of an entity.
+   *
+   * @param name The name of the entity that is ending.
+   * @throws SAXException The application may raise an exception.
+   * @see #startEntity
+   */
+  public void endEntity(String name) throws SAXException
+  {
+
+    // no op
+  }
+
+  /**
+   * Report the start of a CDATA section.
+   *
+   * <p>The contents of the CDATA section will be reported through
+   * the regular {@link org.xml.sax.ContentHandler#characters
+   * characters} event.</p>
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #endCDATA
+   */
+  public void startCDATA() throws SAXException
+  {
+    m_textType = DTM.CDATA_SECTION_NODE;
+  }
+
+  /**
+   * Report the end of a CDATA section.
+   *
+   * @throws SAXException The application may raise an exception.
+   * @see #startCDATA
+   */
+  public void endCDATA() throws SAXException
+  {
+    m_textType = DTM.TEXT_NODE;
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * <p>This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).</p>
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void comment(char ch[], int start, int length) throws SAXException
+  {
+
+    if (m_insideDTD)      // ignore comments if we're inside the DTD
+      return;
+
+    charactersFlush();
+
+    int exName = m_expandedNameTable.getExpandedTypeID(DTM.COMMENT_NODE);
+
+    // For now, treat comments as strings...  I guess we should do a
+    // seperate FSB buffer instead.
+    int dataIndex = m_valuesOrPrefixes.stringToIndex(new String(ch, start,
+                      length));
+
+
+    m_previous = addNode(DTM.COMMENT_NODE, exName,
+                         m_parents.peek(), m_previous, dataIndex, false);
+  }
+
+  /**
+   * Set a run time property for this DTM instance.
+   * 
+   * %REVIEW% Now that we no longer use this method to support
+   * getSourceLocatorFor, can we remove it?
+   *
+   * @param property a <code>String</code> value
+   * @param value an <code>Object</code> value
+   */
+  public void setProperty(String property, Object value)
+  {
+  }
+
+  /** Retrieve the SourceLocator associated with a specific node.
+   * This is only meaningful if the XalanProperties.SOURCE_LOCATION flag was
+   * set True using setProperty; if it was never set, or was set false, we
+   * will return null. 
+   * 
+   * (We _could_ return a locator with the document's base URI and bogus 
+   * line/column information. Trying that; see the else clause.)
+   * */
+  public SourceLocator getSourceLocatorFor(int node)
+  {
+    if (m_useSourceLocationProperty)
+    {
+
+      node = makeNodeIdentity(node);
+      
+
+      return new NodeLocator(null,
+                             m_sourceSystemId.elementAt(node),
+                             m_sourceLine.elementAt(node),
+                             m_sourceColumn.elementAt(node));
+    }
+    else if(m_locator!=null)
+    {
+    	return new NodeLocator(null,m_locator.getSystemId(),-1,-1);
+    }
+    else if(m_systemId!=null)
+    {
+    	return new NodeLocator(null,m_systemId,-1,-1);
+    }
+    return null;
+  }
+  
+  public String getFixedNames(int type){
+    return m_fixednames[type];
+  }
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM2.java b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM2.java
new file mode 100644
index 0000000..be2941a
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM2.java
@@ -0,0 +1,3383 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SAX2DTM2.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref.sax2dtm;
+
+import org.apache.xml.dtm.*;
+import org.apache.xml.dtm.ref.*;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringDefault;
+import org.apache.xml.utils.XMLStringFactory;
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.serializer.SerializationHandler;
+
+import javax.xml.transform.Source;
+import java.util.Vector;
+import org.apache.xml.utils.SuballocatedIntVector;
+import org.xml.sax.*;
+
+/**
+ * SAX2DTM2 is an optimized version of SAX2DTM which is used in non-incremental situation.
+ * It is used as the super class of the XSLTC SAXImpl. Many of the interfaces in SAX2DTM
+ * and DTMDefaultBase are overridden in SAX2DTM2 in order to allow fast, efficient
+ * access to the DTM model. Some nested iterators in DTMDefaultBaseIterators
+ * are also overridden in SAX2DTM2 for performance reasons.
+ * <p>
+ * Performance is the biggest consideration in the design of SAX2DTM2. To make the code most
+ * efficient, the incremental support is dropped in SAX2DTM2, which means that you should not
+ * use it in incremental situation. To reduce the overhead of pulling data from the DTM model,
+ * a few core interfaces in SAX2DTM2 have direct access to the internal arrays of the
+ * SuballocatedIntVectors.
+ * <p>
+ * The design of SAX2DTM2 may limit its extensibilty. If you have a reason to extend the
+ * SAX2DTM model, please extend from SAX2DTM instead of this class.
+ * <p>
+ * TODO: This class is currently only used by XSLTC. We need to investigate the possibility
+ * of also using it in Xalan-J Interpretive. Xalan's performance is likely to get an instant
+ * boost if we use SAX2DTM2 instead of SAX2DTM in non-incremental case.
+ * <p>
+ * %MK% The code in this class is critical to the XSLTC_DTM performance. Be very careful
+ * when making changes here!
+ */
+public class SAX2DTM2 extends SAX2DTM
+{
+
+  /****************************************************************
+   *       Optimized version of the nested iterators
+   ****************************************************************/
+
+  /**
+   * Iterator that returns all immediate children of a given node
+   */
+  public final class ChildrenIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Setting start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     * <p>
+     * If the iterator is not restartable, this has no effect.
+     * %REVIEW% Should it return/throw something in that case,
+     * or set current node to END, to indicate request-not-honored?
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = (node == DTM.NULL) ? DTM.NULL
+                                          : _firstch2(makeNodeIdentity(node));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END if no more
+     * are available.
+     */
+    public int next()
+    {
+      if (_currentNode != NULL) {
+        int node = _currentNode;
+        _currentNode = _nextsib2(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+      return END;
+    }
+  }  // end of ChildrenIterator
+
+  /**
+   * Iterator that returns the parent of a given node. Note that
+   * this delivers only a single node; if you want all the ancestors,
+   * see AncestorIterator.
+   */
+  public final class ParentIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private int _nodeType = DTM.NULL;
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+
+        if (node != DTM.NULL)
+          _currentNode = _parent2(makeNodeIdentity(node));
+        else
+          _currentNode = DTM.NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Set the node type of the parent that we're looking for.
+     * Note that this does _not_ mean "find the nearest ancestor of
+     * this type", but "yield the parent if it is of this type".
+     *
+     *
+     * @param type extended type ID.
+     *
+     * @return ParentIterator configured with the type filter set.
+     */
+    public DTMAxisIterator setNodeType(final int type)
+    {
+
+      _nodeType = type;
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration. In this case, we return
+     * only the immediate parent, _if_ it matches the requested nodeType.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int result = _currentNode;
+      if (result == END)
+        return DTM.NULL;
+
+      // %OPT% The most common case is handled first.
+      if (_nodeType == NULL) {
+        _currentNode = END;
+        return returnNode(makeNodeHandle(result));
+      }
+      else if (_nodeType >= DTM.NTYPES) {
+        if (_nodeType == _exptype2(result)) {
+          _currentNode = END;
+	  return returnNode(makeNodeHandle(result));
+        }
+      }
+      else {
+        if (_nodeType == _type2(result)) {
+	  _currentNode = END;
+	  return returnNode(makeNodeHandle(result));
+        }
+      }
+
+      return DTM.NULL;
+    }
+  }  // end of ParentIterator
+
+  /**
+   * Iterator that returns children of a given type for a given node.
+   * The functionality chould be achieved by putting a filter on top
+   * of a basic child iterator, but a specialised iterator is used
+   * for efficiency (both speed and size of translet).
+   */
+  public final class TypedChildrenIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedChildrenIterator
+     *
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedChildrenIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = (node == DTM.NULL)
+                                   ? DTM.NULL
+                                   : _firstch2(makeNodeIdentity(_startNode));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node = _currentNode;
+      if (node == DTM.NULL)
+        return DTM.NULL;
+
+      final int nodeType = _nodeType;
+
+      if (nodeType != DTM.ELEMENT_NODE) {
+        while (node != DTM.NULL && _exptype2(node) != nodeType) {
+          node = _nextsib2(node);
+        }
+      }
+      // %OPT% If the nodeType is element (matching child::*), we only
+      // need to compare the expType with DTM.NTYPES. A child node of
+      // an element can be either an element, text, comment or
+      // processing instruction node. Only element node has an extended
+      // type greater than or equal to DTM.NTYPES.
+      else {
+      	int eType;
+      	while (node != DTM.NULL) {
+      	  eType = _exptype2(node);
+      	  if (eType >= DTM.NTYPES)
+      	    break;
+      	  else
+      	    node = _nextsib2(node);
+      	}
+      }
+
+      if (node == DTM.NULL) {
+        _currentNode = DTM.NULL;
+        return DTM.NULL;
+      } else {
+        _currentNode = _nextsib2(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+    }
+
+    /**
+     * Return the node at the given position.
+     */
+    public int getNodeByPosition(int position)
+    {
+      if (position <= 0)
+        return DTM.NULL;
+
+      int node = _currentNode;
+      int pos = 0;
+
+      final int nodeType = _nodeType;
+      if (nodeType != DTM.ELEMENT_NODE) {
+        while (node != DTM.NULL) {
+          if (_exptype2(node) == nodeType) {
+            pos++;
+            if (pos == position)
+              return makeNodeHandle(node);
+          }
+
+          node = _nextsib2(node);
+        }
+        return NULL;
+      }
+      else {
+      	while (node != DTM.NULL) {
+      	  if (_exptype2(node) >= DTM.NTYPES) {
+      	    pos++;
+      	    if (pos == position)
+      	      return makeNodeHandle(node);
+      	  }
+      	  node = _nextsib2(node);
+      	}
+      	return NULL;
+      }
+    }
+
+  }  // end of TypedChildrenIterator
+
+  /**
+   * Iterator that returns the namespace nodes as defined by the XPath data model
+   * for a given node, filtered by extended type ID.
+   */
+  public class TypedRootIterator extends RootIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedRootIterator
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedRootIterator(int nodeType)
+    {
+      super();
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if(_startNode == _currentNode)
+        return NULL;
+
+      final int node = _startNode;
+      int expType = _exptype2(makeNodeIdentity(node));
+
+      _currentNode = node;
+
+      if (_nodeType >= DTM.NTYPES) {
+        if (_nodeType == expType) {
+          return returnNode(node);
+        }
+      }
+      else {
+        if (expType < DTM.NTYPES) {
+          if (expType == _nodeType) {
+            return returnNode(node);
+          }
+        }
+        else {
+          if (m_extendedTypes[expType].getNodeType() == _nodeType) {
+            return returnNode(node);
+          }
+        }
+      }
+
+      return NULL;
+    }
+  }  // end of TypedRootIterator
+
+  /**
+   * Iterator that returns all siblings of a given node.
+   */
+  public class FollowingSiblingIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = makeNodeIdentity(node);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
+                                                : _nextsib2(_currentNode);
+      return returnNode(makeNodeHandle(_currentNode));
+    }
+  }  // end of FollowingSiblingIterator
+
+  /**
+   * Iterator that returns all following siblings of a given node.
+   */
+  public final class TypedFollowingSiblingIterator
+          extends FollowingSiblingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedFollowingSiblingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedFollowingSiblingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      if (_currentNode == DTM.NULL) {
+        return DTM.NULL;
+      }
+
+      int node = _currentNode;
+      final int nodeType = _nodeType;
+
+      if (nodeType != DTM.ELEMENT_NODE) {
+        while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) != nodeType) {}
+      }
+      else {
+        while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) < DTM.NTYPES) {}
+      }
+
+      _currentNode = node;
+
+      return (node == DTM.NULL)
+                      ? DTM.NULL
+                      : returnNode(makeNodeHandle(node));
+    }
+
+  }  // end of TypedFollowingSiblingIterator
+
+  /**
+   * Iterator that returns attribute nodes (of what nodes?)
+   */
+  public final class AttributeIterator extends InternalAxisIteratorBase
+  {
+
+    // assumes caller will pass element nodes
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int node = _currentNode;
+
+      if (node != NULL) {
+        _currentNode = getNextAttributeIdentity(node);
+        return returnNode(makeNodeHandle(node));
+      }
+
+      return NULL;
+    }
+  }  // end of AttributeIterator
+
+  /**
+   * Iterator that returns attribute nodes of a given type
+   */
+  public final class TypedAttributeIterator extends InternalAxisIteratorBase
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedAttributeIterator
+     *
+     *
+     * @param nodeType The extended type ID that is requested.
+     */
+    public TypedAttributeIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    // assumes caller will pass element nodes
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+      if (_isRestartable)
+      {
+        _startNode = node;
+
+        _currentNode = getTypedAttribute(node, _nodeType);
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int node = _currentNode;
+
+      // singleton iterator, since there can only be one attribute of
+      // a given type.
+      _currentNode = NULL;
+
+      return returnNode(node);
+    }
+  }  // end of TypedAttributeIterator
+
+  /**
+   * Iterator that returns preceding siblings of a given node
+   */
+  public class PrecedingSiblingIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * The node identity of _startNode for this iterator
+     */
+    protected int _startNodeID;
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true.
+     */
+    public boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+        node = _startNodeID = makeNodeIdentity(node);
+
+        if(node == NULL)
+        {
+          _currentNode = node;
+          return resetPosition();
+        }
+
+        int type = _type2(node);
+        if(ExpandedNameTable.ATTRIBUTE == type
+           || ExpandedNameTable.NAMESPACE == type )
+        {
+          _currentNode = node;
+        }
+        else
+        {
+          // Be careful to handle the Document node properly
+          _currentNode = _parent2(node);
+          if(NULL!=_currentNode)
+            _currentNode = _firstch2(_currentNode);
+          else
+            _currentNode = node;
+        }
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
+      {
+        return NULL;
+      }
+      else
+      {
+        final int node = _currentNode;
+        _currentNode = _nextsib2(node);
+
+        return returnNode(makeNodeHandle(node));
+      }
+    }
+  }  // end of PrecedingSiblingIterator
+
+  /**
+   * Iterator that returns preceding siblings of a given type for
+   * a given node
+   */
+  public final class TypedPrecedingSiblingIterator
+          extends PrecedingSiblingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedPrecedingSiblingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedPrecedingSiblingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node = _currentNode;
+
+      final int nodeType = _nodeType;
+      final int startNodeID = _startNodeID;
+
+      if (nodeType != DTM.ELEMENT_NODE) {
+        while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) {
+          node = _nextsib2(node);
+        }
+      }
+      else {
+        while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) {
+          node = _nextsib2(node);
+        }
+      }
+
+      if (node == DTM.NULL || node == startNodeID) {
+        _currentNode = NULL;
+        return NULL;
+      }
+      else {
+        _currentNode = _nextsib2(node);
+        return returnNode(makeNodeHandle(node));
+      }
+    }
+
+    /**
+     * Return the index of the last node in this iterator.
+     */
+    public int getLast()
+    {
+      if (_last != -1)
+        return _last;
+
+      setMark();
+
+      int node = _currentNode;
+      final int nodeType = _nodeType;
+      final int startNodeID = _startNodeID;
+
+      int last = 0;
+      if (nodeType != DTM.ELEMENT_NODE) {
+        while (node != NULL && node != startNodeID) {
+          if (_exptype2(node) == nodeType) {
+            last++;
+          }
+          node = _nextsib2(node);
+        }
+      }
+      else {
+        while (node != NULL && node != startNodeID) {
+          if (_exptype2(node) >= DTM.NTYPES) {
+            last++;
+          }
+          node = _nextsib2(node);
+        }
+      }
+
+      gotoMark();
+
+      return (_last = last);
+    }
+  }  // end of TypedPrecedingSiblingIterator
+
+  /**
+   * Iterator that returns preceding nodes of a given node.
+   * This includes the node set {root+1, start-1}, but excludes
+   * all ancestors, attributes, and namespace nodes.
+   */
+  public class PrecedingIterator extends InternalAxisIteratorBase
+  {
+
+    /** The max ancestors, but it can grow... */
+    private final int _maxAncestors = 8;
+
+    /**
+     * The stack of start node + ancestors up to the root of the tree,
+     *  which we must avoid.
+     */
+    protected int[] _stack = new int[_maxAncestors];
+
+    /** (not sure yet... -sb) */
+    protected int _sp, _oldsp;
+
+    protected int _markedsp, _markedNode, _markedDescendant;
+
+    /* _currentNode precedes candidates.  This is the identity, not the handle! */
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true since this iterator is a reversed axis.
+     */
+    public boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Returns a deep copy of this iterator.   The cloned iterator is not reset.
+     *
+     * @return a deep copy of this iterator.
+     */
+    public DTMAxisIterator cloneIterator()
+    {
+      _isRestartable = false;
+
+      try
+      {
+        final PrecedingIterator clone = (PrecedingIterator) super.clone();
+        final int[] stackCopy = new int[_stack.length];
+        System.arraycopy(_stack, 0, stackCopy, 0, _stack.length);
+
+        clone._stack = stackCopy;
+
+        // return clone.reset();
+        return clone;
+      }
+      catch (CloneNotSupportedException e)
+      {
+        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
+      }
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        node = makeNodeIdentity(node);
+
+        // iterator is not a clone
+        int parent, index;
+
+       if (_type2(node) == DTM.ATTRIBUTE_NODE)
+         node = _parent2(node);
+
+        _startNode = node;
+        _stack[index = 0] = node;
+
+       	parent=node;
+	while ((parent = _parent2(parent)) != NULL)
+	{
+	  if (++index == _stack.length)
+	  {
+	    final int[] stack = new int[index*2];
+	    System.arraycopy(_stack, 0, stack, 0, index);
+	    _stack = stack;
+	  }
+	  _stack[index] = parent;
+        }
+
+        if(index>0)
+	  --index; // Pop actual root node (if not start) back off the stack
+
+        _currentNode=_stack[index]; // Last parent before root node
+
+        _oldsp = _sp = index;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+    	// Bugzilla 8324: We were forgetting to skip Attrs and NS nodes.
+    	// Also recoded the loop controls for clarity and to flatten out
+    	// the tail-recursion.
+   	for(++_currentNode; _sp>=0; ++_currentNode)
+   	{
+   	  if(_currentNode < _stack[_sp])
+   	  {
+   	    int type = _type2(_currentNode);
+   	    if(type != ATTRIBUTE_NODE && type != NAMESPACE_NODE)
+   	      return returnNode(makeNodeHandle(_currentNode));
+   	  }
+   	  else
+   	    --_sp;
+   	}
+   	return NULL;
+    }
+
+    // redefine DTMAxisIteratorBase's reset
+
+    /**
+     * Resets the iterator to the last start node.
+     *
+     * @return A DTMAxisIterator, which may or may not be the same as this
+     *         iterator.
+     */
+    public DTMAxisIterator reset()
+    {
+
+      _sp = _oldsp;
+
+      return resetPosition();
+    }
+
+    public void setMark() {
+        _markedsp = _sp;
+        _markedNode = _currentNode;
+        _markedDescendant = _stack[0];
+    }
+
+    public void gotoMark() {
+        _sp = _markedsp;
+        _currentNode = _markedNode;
+    }
+  }  // end of PrecedingIterator
+
+  /**
+   * Iterator that returns preceding nodes of agiven type for a
+   * given node. This includes the node set {root+1, start-1}, but
+   * excludes all ancestors.
+   */
+  public final class TypedPrecedingIterator extends PrecedingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedPrecedingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedPrecedingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int node = _currentNode;
+      final int nodeType = _nodeType;
+
+      if (nodeType >= DTM.NTYPES) {
+        while (true) {
+          node++;
+
+          if (_sp < 0) {
+            node = NULL;
+            break;
+          }
+          else if (node >= _stack[_sp]) {
+            if (--_sp < 0) {
+              node = NULL;
+              break;
+            }
+          }
+          else if (_exptype2(node) == nodeType) {
+            break;
+          }
+        }
+      }
+      else {
+        int expType;
+
+        while (true) {
+          node++;
+
+          if (_sp < 0) {
+            node = NULL;
+            break;
+          }
+          else if (node >= _stack[_sp]) {
+            if (--_sp < 0) {
+              node = NULL;
+              break;
+            }
+          }
+          else {
+            expType = _exptype2(node);
+            if (expType < DTM.NTYPES) {
+              if (expType == nodeType) {
+                break;
+              }
+            }
+            else {
+              if (m_extendedTypes[expType].getNodeType() == nodeType) {
+                break;
+              }
+            }
+          }
+        }
+      }
+
+      _currentNode = node;
+
+      return (node == NULL) ? NULL : returnNode(makeNodeHandle(node));
+    }
+  }  // end of TypedPrecedingIterator
+
+  /**
+   * Iterator that returns following nodes of for a given node.
+   */
+  public class FollowingIterator extends InternalAxisIteratorBase
+  {
+    //DTMAxisTraverser m_traverser; // easier for now
+
+    public FollowingIterator()
+    {
+      //m_traverser = getAxisTraverser(Axis.FOLLOWING);
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        _startNode = node;
+
+        //_currentNode = m_traverser.first(node);
+
+        node = makeNodeIdentity(node);
+
+        int first;
+        int type = _type2(node);
+
+        if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
+        {
+          node = _parent2(node);
+          first = _firstch2(node);
+
+          if (NULL != first) {
+            _currentNode = makeNodeHandle(first);
+            return resetPosition();
+          }
+        }
+
+        do
+        {
+          first = _nextsib2(node);
+
+          if (NULL == first)
+            node = _parent2(node);
+        }
+        while (NULL == first && NULL != node);
+
+        _currentNode = makeNodeHandle(first);
+
+        // _currentNode precedes possible following(node) nodes
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int node = _currentNode;
+
+      //_currentNode = m_traverser.next(_startNode, _currentNode);
+      int current = makeNodeIdentity(node);
+
+      while (true)
+      {
+        current++;
+
+        int type = _type2(current);
+        if (NULL == type) {
+          _currentNode = NULL;
+          return returnNode(node);
+        }
+
+        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+          continue;
+
+        _currentNode = makeNodeHandle(current);
+        return returnNode(node);
+      }
+    }
+
+  }  // end of FollowingIterator
+
+  /**
+   * Iterator that returns following nodes of a given type for a given node.
+   */
+  public final class TypedFollowingIterator extends FollowingIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedFollowingIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedFollowingIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      int current;
+      int node;
+      int type;
+
+      final int nodeType = _nodeType;
+      int currentNodeID = makeNodeIdentity(_currentNode);
+
+      if (nodeType >= DTM.NTYPES) {
+        do {
+          node = currentNodeID;
+	  current = node;
+
+          do {
+            current++;
+            type = _type2(current);
+          }
+          while (type != NULL && (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type));
+
+          currentNodeID = (type != NULL) ? current : NULL;
+        }
+        while (node != DTM.NULL && _exptype2(node) != nodeType);
+      }
+      else {
+        do {
+          node = currentNodeID;
+	  current = node;
+
+          do {
+            current++;
+            type = _type2(current);
+          }
+          while (type != NULL && (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type));
+
+          currentNodeID = (type != NULL) ? current : NULL;
+        }
+        while (node != DTM.NULL
+               && (_exptype2(node) != nodeType && _type2(node) != nodeType));
+      }
+
+      _currentNode = makeNodeHandle(currentNodeID);
+      return (node == DTM.NULL ? DTM.NULL :returnNode(makeNodeHandle(node)));
+    }
+  }  // end of TypedFollowingIterator
+
+  /**
+   * Iterator that returns the ancestors of a given node in document
+   * order.  (NOTE!  This was changed from the XSLTC code!)
+   */
+  public class AncestorIterator extends InternalAxisIteratorBase
+  {
+    // The initial size of the ancestor array
+    private static final int m_blocksize = 32;
+
+    // The array for ancestor nodes. This array will grow dynamically.
+    int[] m_ancestors = new int[m_blocksize];
+
+    // Number of ancestor nodes in the array
+    int m_size = 0;
+
+    int m_ancestorsPos;
+
+    int m_markedPos;
+
+    /** The real start node for this axes, since _startNode will be adjusted. */
+    int m_realStartNode;
+
+    /**
+     * Get start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @return The root node of the iteration.
+     */
+    public int getStartNode()
+    {
+      return m_realStartNode;
+    }
+
+    /**
+     * True if this iterator has a reversed axis.
+     *
+     * @return true since this iterator is a reversed axis.
+     */
+    public final boolean isReverse()
+    {
+      return true;
+    }
+
+    /**
+     * Returns a deep copy of this iterator.  The cloned iterator is not reset.
+     *
+     * @return a deep copy of this iterator.
+     */
+    public DTMAxisIterator cloneIterator()
+    {
+      _isRestartable = false;  // must set to false for any clone
+
+      try
+      {
+        final AncestorIterator clone = (AncestorIterator) super.clone();
+
+        clone._startNode = _startNode;
+
+        // return clone.reset();
+        return clone;
+      }
+      catch (CloneNotSupportedException e)
+      {
+        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
+      }
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      m_realStartNode = node;
+
+      if (_isRestartable)
+      {
+        int nodeID = makeNodeIdentity(node);
+        m_size = 0;
+
+        if (nodeID == DTM.NULL) {
+          _currentNode = DTM.NULL;
+          m_ancestorsPos = 0;
+          return this;
+        }
+
+        // Start from the current node's parent if
+        // _includeSelf is false.
+        if (!_includeSelf) {
+          nodeID = _parent2(nodeID);
+          node = makeNodeHandle(nodeID);
+        }
+
+        _startNode = node;
+
+        while (nodeID != END) {
+          //m_ancestors.addElement(node);
+          if (m_size >= m_ancestors.length)
+          {
+            int[] newAncestors = new int[m_size * 2];
+            System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
+            m_ancestors = newAncestors;
+          }
+
+          m_ancestors[m_size++] = node;
+          nodeID = _parent2(nodeID);
+          node = makeNodeHandle(nodeID);
+        }
+
+        m_ancestorsPos = m_size - 1;
+
+        _currentNode = (m_ancestorsPos>=0)
+                               ? m_ancestors[m_ancestorsPos]
+                               : DTM.NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Resets the iterator to the last start node.
+     *
+     * @return A DTMAxisIterator, which may or may not be the same as this
+     *         iterator.
+     */
+    public DTMAxisIterator reset()
+    {
+
+      m_ancestorsPos = m_size - 1;
+
+      _currentNode = (m_ancestorsPos >= 0) ? m_ancestors[m_ancestorsPos]
+                                         : DTM.NULL;
+
+      return resetPosition();
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      int next = _currentNode;
+
+      int pos = --m_ancestorsPos;
+
+      _currentNode = (pos >= 0) ? m_ancestors[m_ancestorsPos]
+                                : DTM.NULL;
+
+      return returnNode(next);
+    }
+
+    public void setMark() {
+        m_markedPos = m_ancestorsPos;
+    }
+
+    public void gotoMark() {
+        m_ancestorsPos = m_markedPos;
+        _currentNode = m_ancestorsPos>=0 ? m_ancestors[m_ancestorsPos]
+                                         : DTM.NULL;
+    }
+  }  // end of AncestorIterator
+
+  /**
+   * Typed iterator that returns the ancestors of a given node.
+   */
+  public final class TypedAncestorIterator extends AncestorIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedAncestorIterator
+     *
+     *
+     * @param type The extended type ID being requested.
+     */
+    public TypedAncestorIterator(int type)
+    {
+      _nodeType = type;
+    }
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      m_realStartNode = node;
+
+      if (_isRestartable)
+      {
+        int nodeID = makeNodeIdentity(node);
+        m_size = 0;
+
+        if (nodeID == DTM.NULL) {
+          _currentNode = DTM.NULL;
+          m_ancestorsPos = 0;
+          return this;
+        }
+
+        final int nodeType = _nodeType;
+
+        if (!_includeSelf) {
+          nodeID = _parent2(nodeID);
+          node = makeNodeHandle(nodeID);
+        }
+
+        _startNode = node;
+
+        if (nodeType >= DTM.NTYPES) {
+          while (nodeID != END) {
+            int eType = _exptype2(nodeID);
+
+            if (eType == nodeType) {
+              if (m_size >= m_ancestors.length)
+              {
+              	int[] newAncestors = new int[m_size * 2];
+              	System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
+              	m_ancestors = newAncestors;
+              }
+              m_ancestors[m_size++] = makeNodeHandle(nodeID);
+            }
+            nodeID = _parent2(nodeID);
+          }
+        }
+        else {
+          while (nodeID != END) {
+            int eType = _exptype2(nodeID);
+
+            if ((eType < DTM.NTYPES && eType == nodeType)
+                || (eType >= DTM.NTYPES
+                    && m_extendedTypes[eType].getNodeType() == nodeType)) {
+              if (m_size >= m_ancestors.length)
+              {
+              	int[] newAncestors = new int[m_size * 2];
+              	System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
+              	m_ancestors = newAncestors;
+              }
+              m_ancestors[m_size++] = makeNodeHandle(nodeID);
+            }
+            nodeID = _parent2(nodeID);
+          }
+        }
+        m_ancestorsPos = m_size - 1;
+
+        _currentNode = (m_ancestorsPos>=0)
+                               ? m_ancestors[m_ancestorsPos]
+                               : DTM.NULL;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Return the node at the given position.
+     */
+    public int getNodeByPosition(int position)
+    {
+      if (position > 0 && position <= m_size) {
+        return m_ancestors[position-1];
+      }
+      else
+        return DTM.NULL;
+    }
+
+    /**
+     * Returns the position of the last node within the iteration, as
+     * defined by XPath.
+     */
+    public int getLast() {
+      return m_size;
+    }
+  }  // end of TypedAncestorIterator
+
+  /**
+   * Iterator that returns the descendants of a given node.
+   */
+  public class DescendantIterator extends InternalAxisIteratorBase
+  {
+
+    /**
+     * Set start to END should 'close' the iterator,
+     * i.e. subsequent call to next() should return END.
+     *
+     * @param node Sets the root of the iteration.
+     *
+     * @return A DTMAxisIterator set to the start of the iteration.
+     */
+    public DTMAxisIterator setStartNode(int node)
+    {
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+      if (node == DTMDefaultBase.ROOTNODE)
+        node = getDocument();
+      if (_isRestartable)
+      {
+        node = makeNodeIdentity(node);
+        _startNode = node;
+
+        if (_includeSelf)
+          node--;
+
+        _currentNode = node;
+
+        return resetPosition();
+      }
+
+      return this;
+    }
+
+    /**
+     * Tell if this node identity is a descendant.  Assumes that
+     * the node info for the element has already been obtained.
+     *
+     * This one-sided test works only if the parent has been
+     * previously tested and is known to be a descendent. It fails if
+     * the parent is the _startNode's next sibling, or indeed any node
+     * that follows _startNode in document order.  That may suffice
+     * for this iterator, but it's not really an isDescendent() test.
+     * %REVIEW% rename?
+     *
+     * @param identity The index number of the node in question.
+     * @return true if the index is a descendant of _startNode.
+     */
+    protected final boolean isDescendant(int identity)
+    {
+      return (_parent2(identity) >= _startNode) || (_startNode == identity);
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      final int startNode = _startNode;
+      if (startNode == NULL) {
+        return NULL;
+      }
+
+      if (_includeSelf && (_currentNode + 1) == startNode)
+          return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent);
+
+      int node = _currentNode;
+      int type;
+
+      // %OPT% If the startNode is the root node, do not need
+      // to do the isDescendant() check.
+      if (startNode == ROOTNODE) {
+        int eType;
+        do {
+          node++;
+          eType = _exptype2(node);
+
+          if (NULL == eType) {
+            _currentNode = NULL;
+            return END;
+          }
+        } while (eType == TEXT_NODE
+                 || (type = m_extendedTypes[eType].getNodeType()) == ATTRIBUTE_NODE
+                 || type == NAMESPACE_NODE);
+      }
+      else {
+        do {
+          node++;
+          type = _type2(node);
+
+          if (NULL == type ||!isDescendant(node)) {
+            _currentNode = NULL;
+            return END;
+          }
+        } while(ATTRIBUTE_NODE == type || TEXT_NODE == type
+                 || NAMESPACE_NODE == type);
+      }
+
+      _currentNode = node;
+      return returnNode(makeNodeHandle(node));  // make handle.
+    }
+
+    /**
+     * Reset.
+     *
+     */
+  public DTMAxisIterator reset()
+  {
+
+    final boolean temp = _isRestartable;
+
+    _isRestartable = true;
+
+    setStartNode(makeNodeHandle(_startNode));
+
+    _isRestartable = temp;
+
+    return this;
+  }
+
+  }  // end of DescendantIterator
+
+  /**
+   * Typed iterator that returns the descendants of a given node.
+   */
+  public final class TypedDescendantIterator extends DescendantIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedDescendantIterator
+     *
+     *
+     * @param nodeType Extended type ID being requested.
+     */
+    public TypedDescendantIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+      final int startNode = _startNode;
+      if (_startNode == NULL) {
+        return NULL;
+      }
+
+      int node = _currentNode;
+
+      int expType;
+      final int nodeType = _nodeType;
+
+      if (nodeType != DTM.ELEMENT_NODE)
+      {
+        do
+        {
+          node++;
+	  expType = _exptype2(node);
+
+          if (NULL == expType || _parent2(node) < startNode && startNode != node) {
+            _currentNode = NULL;
+            return END;
+          }
+        }
+        while (expType != nodeType);
+      }
+      // %OPT% If the start node is root (e.g. in the case of //node),
+      // we can save the isDescendant() check, because all nodes are
+      // descendants of root.
+      else if (startNode == DTMDefaultBase.ROOTNODE)
+      {
+	do
+	{
+	  node++;
+	  expType = _exptype2(node);
+
+	  if (NULL == expType) {
+	    _currentNode = NULL;
+	    return END;
+	  }
+	} while (expType < DTM.NTYPES
+	        || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE);
+      }
+      else
+      {
+        do
+        {
+          node++;
+	  expType = _exptype2(node);
+
+          if (NULL == expType || _parent2(node) < startNode && startNode != node) {
+            _currentNode = NULL;
+            return END;
+          }
+        }
+        while (expType < DTM.NTYPES
+	       || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE);
+      }
+
+      _currentNode = node;
+      return returnNode(makeNodeHandle(node));
+    }
+  }  // end of TypedDescendantIterator
+
+  /**
+   * Iterator that returns a given node only if it is of a given type.
+   */
+  public final class TypedSingletonIterator extends SingletonIterator
+  {
+
+    /** The extended type ID that was requested. */
+    private final int _nodeType;
+
+    /**
+     * Constructor TypedSingletonIterator
+     *
+     *
+     * @param nodeType The extended type ID being requested.
+     */
+    public TypedSingletonIterator(int nodeType)
+    {
+      _nodeType = nodeType;
+    }
+
+    /**
+     * Get the next node in the iteration.
+     *
+     * @return The next node handle in the iteration, or END.
+     */
+    public int next()
+    {
+
+      final int result = _currentNode;
+      if (result == END)
+        return DTM.NULL;
+
+      _currentNode = END;
+
+      if (_nodeType >= DTM.NTYPES) {
+        if (_exptype2(makeNodeIdentity(result)) == _nodeType) {
+          return returnNode(result);
+        }
+      }
+      else {
+        if (_type2(makeNodeIdentity(result)) == _nodeType) {
+          return returnNode(result);
+        }
+      }
+
+      return NULL;
+    }
+  }  // end of TypedSingletonIterator
+
+  /*******************************************************************
+   *                End of nested iterators
+   *******************************************************************/
+
+
+  // %OPT% Array references which are used to cache the map0 arrays in
+  // SuballocatedIntVectors. Using the cached arrays reduces the level
+  // of indirection and results in better performance than just calling
+  // SuballocatedIntVector.elementAt().
+  private int[] m_exptype_map0;
+  private int[] m_nextsib_map0;
+  private int[] m_firstch_map0;
+  private int[] m_parent_map0;
+
+  // Double array references to the map arrays in SuballocatedIntVectors.
+  private int[][] m_exptype_map;
+  private int[][] m_nextsib_map;
+  private int[][] m_firstch_map;
+  private int[][] m_parent_map;
+
+  // %OPT% Cache the array of extended types in this class
+  protected ExtendedType[] m_extendedTypes;
+
+  // A Vector which is used to store the values of attribute, namespace,
+  // comment and PI nodes.
+  //
+  // %OPT% These values are unlikely to be equal. Storing
+  // them in a plain Vector is more efficient than storing in the
+  // DTMStringPool because we can save the cost for hash calculation.
+  //
+  // %REVISIT% Do we need a custom class (e.g. StringVector) here?
+  protected Vector m_values;
+
+  // The current index into the m_values Vector.
+  private int m_valueIndex = 0;
+
+  // The maximum value of the current node index.
+  private int m_maxNodeIndex;
+
+  // Cache the shift and mask values for the SuballocatedIntVectors.
+  protected int m_SHIFT;
+  protected int m_MASK;
+  protected int m_blocksize;
+
+  /** %OPT% If the offset and length of a Text node are within certain limits,
+   * we store a bitwise encoded value into an int, using 10 bits (max. 1024)
+   * for length and 21 bits for offset. We can save two SuballocatedIntVector
+   * calls for each getStringValueX() and dispatchCharacterEvents() call by
+   * doing this.
+   */
+  // The number of bits for the length of a Text node.
+  protected final static int TEXT_LENGTH_BITS = 10;
+
+  // The number of bits for the offset of a Text node.
+  protected final static int TEXT_OFFSET_BITS = 21;
+
+  // The maximum length value
+  protected final static int TEXT_LENGTH_MAX = (1<<TEXT_LENGTH_BITS) - 1;
+
+  // The maximum offset value
+  protected final static int TEXT_OFFSET_MAX = (1<<TEXT_OFFSET_BITS) - 1;
+
+  // True if we want to build the ID index table.
+  protected boolean m_buildIdIndex = true;
+
+  // Constant for empty String
+  private static final String EMPTY_STR = "";
+
+  // Constant for empty XMLString
+  private static final XMLString EMPTY_XML_STR = new XMLStringDefault("");
+
+  /**
+   * Construct a SAX2DTM2 object using the default block size.
+   */
+  public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity,
+                 DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing)
+  {
+
+    this(mgr, source, dtmIdentity, whiteSpaceFilter,
+          xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, true, false);
+  }
+
+  /**
+   * Construct a SAX2DTM2 object using the given block size.
+   */
+  public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity,
+                 DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing,
+                 int blocksize,
+                 boolean usePrevsib,
+                 boolean buildIdIndex,
+                 boolean newNameTable)
+  {
+
+    super(mgr, source, dtmIdentity, whiteSpaceFilter,
+          xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
+
+    // Initialize the values of m_SHIFT and m_MASK.
+    int shift;
+    for(shift=0; (blocksize>>>=1) != 0; ++shift);
+
+    m_blocksize = 1<<shift;
+    m_SHIFT = shift;
+    m_MASK = m_blocksize - 1;
+
+    m_buildIdIndex = buildIdIndex;
+
+    // Some documents do not have attribute nodes. That is why
+    // we set the initial size of this Vector to be small and set
+    // the increment to a bigger number.
+    m_values = new Vector(32, 512);
+
+    m_maxNodeIndex = 1 << DTMManager.IDENT_DTM_NODE_BITS;
+
+    // Set the map0 values in the constructor.
+    m_exptype_map0 = m_exptype.getMap0();
+    m_nextsib_map0 = m_nextsib.getMap0();
+    m_firstch_map0 = m_firstch.getMap0();
+    m_parent_map0  = m_parent.getMap0();
+  }
+
+  /**
+   * Override DTMDefaultBase._exptype() by dropping the incremental code.
+   *
+   * <p>This one is less efficient than _exptype2. It is only used during
+   * DTM building. _exptype2 is used after the document is fully built.
+   */
+  public final int _exptype(int identity)
+  {
+    return m_exptype.elementAt(identity);
+  }
+
+  /************************************************************************
+   *             DTM base accessor interfaces
+   *
+   * %OPT% The code in the following interfaces (e.g. _exptype2, etc.) are
+   * very important to the DTM performance. To have the best performace,
+   * these several interfaces have direct access to the internal arrays of
+   * the SuballocatedIntVectors. The final modifier also has a noticeable
+   * impact on performance.
+   ***********************************************************************/
+
+  /**
+   * The optimized version of DTMDefaultBase._exptype().
+   *
+   * @param identity A node identity, which <em>must not</em> be equal to
+   *        <code>DTM.NULL</code>
+   */
+  public final int _exptype2(int identity)
+  {
+    //return m_exptype.elementAt(identity);
+
+    if (identity < m_blocksize)
+      return m_exptype_map0[identity];
+    else
+      return m_exptype_map[identity>>>m_SHIFT][identity&m_MASK];
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase._nextsib().
+   *
+   * @param identity A node identity, which <em>must not</em> be equal to
+   *        <code>DTM.NULL</code>
+   */
+  public final int _nextsib2(int identity)
+  {
+    //return m_nextsib.elementAt(identity);
+
+    if (identity < m_blocksize)
+      return m_nextsib_map0[identity];
+    else
+      return m_nextsib_map[identity>>>m_SHIFT][identity&m_MASK];
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase._firstch().
+   *
+   * @param identity A node identity, which <em>must not</em> be equal to
+   *        <code>DTM.NULL</code>
+   */
+  public final int _firstch2(int identity)
+  {
+    //return m_firstch.elementAt(identity);
+
+    if (identity < m_blocksize)
+      return m_firstch_map0[identity];
+    else
+      return m_firstch_map[identity>>>m_SHIFT][identity&m_MASK];
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase._parent().
+   *
+   * @param identity A node identity, which <em>must not</em> be equal to
+   *        <code>DTM.NULL</code>
+   */
+  public final int _parent2(int identity)
+  {
+    //return m_parent.elementAt(identity);
+
+    if (identity < m_blocksize)
+      return m_parent_map0[identity];
+    else
+      return m_parent_map[identity>>>m_SHIFT][identity&m_MASK];
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase._type().
+   *
+   * @param identity A node identity, which <em>must not</em> be equal to
+   *        <code>DTM.NULL</code>
+   */
+  public final int _type2(int identity)
+  {
+    //int eType = _exptype2(identity);
+    int eType;
+    if (identity < m_blocksize)
+      eType = m_exptype_map0[identity];
+    else
+      eType = m_exptype_map[identity>>>m_SHIFT][identity&m_MASK];
+
+    if (NULL != eType)
+      return m_extendedTypes[eType].getNodeType();
+    else
+      return NULL;
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase.getExpandedTypeID(int).
+   *
+   * <p>This one is only used by DOMAdapter.getExpandedTypeID(int), which
+   * is mostly called from the compiled translets.
+   */
+  public final int getExpandedTypeID2(int nodeHandle)
+  {
+    int nodeID = makeNodeIdentity(nodeHandle);
+
+    //return (nodeID != NULL) ? _exptype2(nodeID) : NULL;
+
+    if (nodeID != NULL) {
+      if (nodeID < m_blocksize)
+        return m_exptype_map0[nodeID];
+      else
+        return m_exptype_map[nodeID>>>m_SHIFT][nodeID&m_MASK];
+    }
+    else
+      return NULL;
+  }
+
+  /*************************************************************************
+   *                 END of DTM base accessor interfaces
+   *************************************************************************/
+
+
+  /**
+   * Return the node type from the expanded type
+   */
+  public final int _exptype2Type(int exptype)
+  {
+    if (NULL != exptype)
+      return m_extendedTypes[exptype].getNodeType();
+    else
+      return NULL;
+  }
+
+  /**
+   * Get a prefix either from the uri mapping, or just make
+   * one up!
+   *
+   * @param uri The namespace URI, which may be null.
+   *
+   * @return The prefix if there is one, or null.
+   */
+  public int getIdForNamespace(String uri)
+  {
+     int index = m_values.indexOf(uri);
+     if (index < 0)
+     {
+       m_values.addElement(uri);
+       return m_valueIndex++;
+     }
+     else
+       return index;
+  }
+
+  /**
+   * Override SAX2DTM.startElement()
+   *
+   * <p>Receive notification of the start of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the start of
+   * each element (such as allocating a new tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @param attributes The specified or defaulted attributes.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startElement
+   */
+  public void startElement(String uri, String localName, String qName, Attributes attributes)
+      throws SAXException
+  {
+
+    charactersFlush();
+
+    int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
+
+    int prefixIndex = (qName.length() != localName.length())
+                      ? m_valuesOrPrefixes.stringToIndex(qName) : 0;
+
+    int elemNode = addNode(DTM.ELEMENT_NODE, exName,
+                           m_parents.peek(), m_previous, prefixIndex, true);
+
+    if(m_indexing)
+      indexNode(exName, elemNode);
+
+    m_parents.push(elemNode);
+
+    int startDecls = m_contextIndexes.peek();
+    int nDecls = m_prefixMappings.size();
+    String prefix;
+
+    if(!m_pastFirstElement)
+    {
+      // SPECIAL CASE: Implied declaration at root element
+      prefix="xml";
+      String declURL = "http://www.w3.org/XML/1998/namespace";
+      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
+      m_values.addElement(declURL);
+      int val = m_valueIndex++;
+      addNode(DTM.NAMESPACE_NODE, exName, elemNode,
+                     DTM.NULL, val, false);
+      m_pastFirstElement=true;
+    }
+
+    for (int i = startDecls; i < nDecls; i += 2)
+    {
+      prefix = (String) m_prefixMappings.elementAt(i);
+
+      if (prefix == null)
+        continue;
+
+      String declURL = (String) m_prefixMappings.elementAt(i + 1);
+
+      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
+
+      m_values.addElement(declURL);
+      int val = m_valueIndex++;
+
+      addNode(DTM.NAMESPACE_NODE, exName, elemNode, DTM.NULL, val, false);
+    }
+
+    int n = attributes.getLength();
+
+    for (int i = 0; i < n; i++)
+    {
+      String attrUri = attributes.getURI(i);
+      String attrQName = attributes.getQName(i);
+      String valString = attributes.getValue(i);
+
+      int nodeType;
+
+      String attrLocalName = attributes.getLocalName(i);
+
+      if ((null != attrQName)
+              && (attrQName.equals("xmlns")
+                  || attrQName.startsWith("xmlns:")))
+      {
+        prefix = getPrefix(attrQName, attrUri);
+        if (declAlreadyDeclared(prefix))
+          continue;  // go to the next attribute.
+
+        nodeType = DTM.NAMESPACE_NODE;
+      }
+      else
+      {
+        nodeType = DTM.ATTRIBUTE_NODE;
+
+        if (m_buildIdIndex && attributes.getType(i).equalsIgnoreCase("ID"))
+          setIDAttribute(valString, elemNode);
+      }
+
+      // Bit of a hack... if somehow valString is null, stringToIndex will
+      // return -1, which will make things very unhappy.
+      if(null == valString)
+        valString = "";
+
+      m_values.addElement(valString);
+      int val = m_valueIndex++;
+
+      if (attrLocalName.length() != attrQName.length())
+      {
+
+        prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
+
+        int dataIndex = m_data.size();
+
+        m_data.addElement(prefixIndex);
+        m_data.addElement(val);
+
+        val = -dataIndex;
+      }
+
+      exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
+      addNode(nodeType, exName, elemNode, DTM.NULL, val,
+                     false);
+    }
+
+    if (null != m_wsfilter)
+    {
+      short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
+      boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
+                            ? getShouldStripWhitespace()
+                            : (DTMWSFilter.STRIP == wsv);
+
+      pushShouldStripWhitespace(shouldStrip);
+    }
+
+    m_previous = DTM.NULL;
+
+    m_contextIndexes.push(m_prefixMappings.size());  // for the children.
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * <p>By default, do nothing.  Application writers may override this
+   * method in a subclass to take specific actions at the end of
+   * each element (such as finalising a tree node or writing
+   * output to a file).</p>
+   *
+   * @param uri The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param qName The qualified XML 1.0 name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endElement
+   */
+  public void endElement(String uri, String localName, String qName)
+          throws SAXException
+  {
+    charactersFlush();
+
+    // If no one noticed, startPrefixMapping is a drag.
+    // Pop the context for the last child (the one pushed by startElement)
+    m_contextIndexes.quickPop(1);
+
+    // Do it again for this one (the one pushed by the last endElement).
+    int topContextIndex = m_contextIndexes.peek();
+    if (topContextIndex != m_prefixMappings.size()) {
+      m_prefixMappings.setSize(topContextIndex);
+    }
+
+    m_previous = m_parents.pop();
+
+    popShouldStripWhitespace();
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * <p>This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).</p>
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws SAXException The application may raise an exception.
+   */
+  public void comment(char ch[], int start, int length) throws SAXException
+  {
+
+    if (m_insideDTD)      // ignore comments if we're inside the DTD
+      return;
+
+    charactersFlush();
+
+    // %OPT% Saving the comment string in a Vector has a lower cost than
+    // saving it in DTMStringPool.
+    m_values.addElement(new String(ch, start, length));
+    int dataIndex = m_valueIndex++;
+
+    m_previous = addNode(DTM.COMMENT_NODE, DTM.COMMENT_NODE,
+                         m_parents.peek(), m_previous, dataIndex, false);
+  }
+
+  /**
+   * Receive notification of the beginning of the document.
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startDocument
+   */
+  public void startDocument() throws SAXException
+  {
+
+    int doc = addNode(DTM.DOCUMENT_NODE,
+                      DTM.DOCUMENT_NODE,
+                      DTM.NULL, DTM.NULL, 0, true);
+
+    m_parents.push(doc);
+    m_previous = DTM.NULL;
+
+    m_contextIndexes.push(m_prefixMappings.size());  // for the next element.
+  }
+
+  /**
+   * Receive notification of the end of the document.
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endDocument
+   */
+  public void endDocument() throws SAXException
+  {
+    super.endDocument();
+
+    // Add a NULL entry to the end of the node arrays as
+    // the end indication.
+    m_exptype.addElement(NULL);
+    m_parent.addElement(NULL);
+    m_nextsib.addElement(NULL);
+    m_firstch.addElement(NULL);
+
+    // Set the cached references after the document is built.
+    m_extendedTypes = m_expandedNameTable.getExtendedTypes();
+    m_exptype_map = m_exptype.getMap();
+    m_nextsib_map = m_nextsib.getMap();
+    m_firstch_map = m_firstch.getMap();
+    m_parent_map  = m_parent.getMap();
+  }
+
+  /**
+   * Construct the node map from the node.
+   *
+   * @param type raw type ID, one of DTM.XXX_NODE.
+   * @param expandedTypeID The expended type ID.
+   * @param parentIndex The current parent index.
+   * @param previousSibling The previous sibling index.
+   * @param dataOrPrefix index into m_data table, or string handle.
+   * @param canHaveFirstChild true if the node can have a first child, false
+   *                          if it is atomic.
+   *
+   * @return The index identity of the node that was added.
+   */
+  protected final int addNode(int type, int expandedTypeID,
+                        int parentIndex, int previousSibling,
+                        int dataOrPrefix, boolean canHaveFirstChild)
+  {
+    // Common to all nodes:
+    int nodeIndex = m_size++;
+
+    // Have we overflowed a DTM Identity's addressing range?
+    //if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
+    if (nodeIndex == m_maxNodeIndex)
+    {
+      addNewDTMID(nodeIndex);
+      m_maxNodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);
+    }
+
+    m_firstch.addElement(DTM.NULL);
+    m_nextsib.addElement(DTM.NULL);
+    m_parent.addElement(parentIndex);
+    m_exptype.addElement(expandedTypeID);
+    m_dataOrQName.addElement(dataOrPrefix);
+
+    if (m_prevsib != null) {
+      m_prevsib.addElement(previousSibling);
+    }
+
+    if (m_locator != null && m_useSourceLocationProperty) {
+      setSourceLocation();
+    }
+
+    // Note that nextSibling is not processed until charactersFlush()
+    // is called, to handle successive characters() events.
+
+    // Special handling by type: Declare namespaces, attach first child
+    switch(type)
+    {
+    case DTM.NAMESPACE_NODE:
+      declareNamespaceInContext(parentIndex,nodeIndex);
+      break;
+    case DTM.ATTRIBUTE_NODE:
+      break;
+    default:
+      if (DTM.NULL != previousSibling) {
+        m_nextsib.setElementAt(nodeIndex,previousSibling);
+      }
+      else if (DTM.NULL != parentIndex) {
+        m_firstch.setElementAt(nodeIndex,parentIndex);
+      }
+      break;
+    }
+
+    return nodeIndex;
+  }
+
+  /**
+   * Check whether accumulated text should be stripped; if not,
+   * append the appropriate flavor of text/cdata node.
+   */
+  protected final void charactersFlush()
+  {
+
+    if (m_textPendingStart >= 0)  // -1 indicates no-text-in-progress
+    {
+      int length = m_chars.size() - m_textPendingStart;
+      boolean doStrip = false;
+
+      if (getShouldStripWhitespace())
+      {
+        doStrip = m_chars.isWhitespace(m_textPendingStart, length);
+      }
+
+      if (doStrip) {
+        m_chars.setLength(m_textPendingStart);  // Discard accumulated text
+      } else {
+        // Guard against characters/ignorableWhitespace events that
+        // contained no characters.  They should not result in a node.
+        if (length > 0) {
+          // If the offset and length do not exceed the given limits
+          // (offset < 2^21 and length < 2^10), then save both the offset
+          // and length in a bitwise encoded value.
+          if (length <= TEXT_LENGTH_MAX
+                  && m_textPendingStart <= TEXT_OFFSET_MAX) {
+            m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
+                             m_parents.peek(), m_previous,
+                             length + (m_textPendingStart << TEXT_LENGTH_BITS),
+                             false);
+
+          } else {
+            // Store offset and length in the m_data array if one exceeds 
+            // the given limits. Use a negative dataIndex as an indication.
+            int dataIndex = m_data.size();
+            m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
+                               m_parents.peek(), m_previous, -dataIndex, false);
+
+            m_data.addElement(m_textPendingStart);
+            m_data.addElement(length);
+          }
+        }
+      }
+
+      // Reset for next text block
+      m_textPendingStart = -1;
+      m_textType = m_coalescedTextType = DTM.TEXT_NODE;
+    }
+  }
+
+  /**
+   * Override the processingInstruction() interface in SAX2DTM2.
+   * <p>
+   * %OPT% This one is different from SAX2DTM.processingInstruction()
+   * in that we do not use extended types for PI nodes. The name of
+   * the PI is saved in the DTMStringPool.
+   *
+   * Receive notification of a processing instruction.
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   */
+  public void processingInstruction(String target, String data)
+	  throws SAXException
+  {
+
+    charactersFlush();
+
+    int dataIndex = m_data.size();
+    m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE,
+			 DTM.PROCESSING_INSTRUCTION_NODE,
+			 m_parents.peek(), m_previous,
+			 -dataIndex, false);
+
+    m_data.addElement(m_valuesOrPrefixes.stringToIndex(target));
+    m_values.addElement(data);
+    m_data.addElement(m_valueIndex++);
+
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase.getFirstAttribute().
+   * <p>
+   * Given a node handle, get the index of the node's first attribute.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @return Handle of first attribute, or DTM.NULL to indicate none exists.
+   */
+  public final int getFirstAttribute(int nodeHandle)
+  {
+    int nodeID = makeNodeIdentity(nodeHandle);
+
+    if (nodeID == DTM.NULL)
+      return DTM.NULL;
+
+    int type = _type2(nodeID);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      // Assume that attributes and namespaces immediately follow the element.
+      while (true)
+      {
+        nodeID++;
+	// Assume this can not be null.
+	type = _type2(nodeID);
+
+	if (type == DTM.ATTRIBUTE_NODE)
+	{
+	  return makeNodeHandle(nodeID);
+	}
+	else if (DTM.NAMESPACE_NODE != type)
+	{
+	  break;
+	}
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase.getFirstAttributeIdentity(int).
+   * <p>
+   * Given a node identity, get the index of the node's first attribute.
+   *
+   * @param identity int identity of the node.
+   * @return Identity of first attribute, or DTM.NULL to indicate none exists.
+   */
+  protected int getFirstAttributeIdentity(int identity) {
+    if (identity == NULL) {
+        return NULL;
+    }
+    int type = _type2(identity);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      // Assume that attributes and namespaces immediately follow the element.
+      while (true)
+      {
+        identity++;
+
+        // Assume this can not be null.
+        type = _type2(identity);
+
+        if (type == DTM.ATTRIBUTE_NODE)
+        {
+          return identity;
+        }
+        else if (DTM.NAMESPACE_NODE != type)
+        {
+          break;
+        }
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase.getNextAttributeIdentity(int).
+   * <p>
+   * Given a node identity for an attribute, advance to the next attribute.
+   *
+   * @param identity int identity of the attribute node.  This
+   * <strong>must</strong> be an attribute node.
+   *
+   * @return int DTM node-identity of the resolved attr,
+   * or DTM.NULL to indicate none exists.
+   *
+   */
+  protected int getNextAttributeIdentity(int identity) {
+    // Assume that attributes and namespace nodes immediately follow the element
+    while (true) {
+      identity++;
+      int type = _type2(identity);
+
+      if (type == DTM.ATTRIBUTE_NODE) {
+        return identity;
+      } else if (type != DTM.NAMESPACE_NODE) {
+        break;
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * The optimized version of DTMDefaultBase.getTypedAttribute(int, int).
+   * <p>
+   * Given a node handle and an expanded type ID, get the index of the node's
+   * attribute of that type, if any.
+   *
+   * @param nodeHandle int Handle of the node.
+   * @param attType int expanded type ID of the required attribute.
+   * @return Handle of attribute of the required type, or DTM.NULL to indicate
+   * none exists.
+   */
+  protected final int getTypedAttribute(int nodeHandle, int attType)
+  {
+
+    int nodeID = makeNodeIdentity(nodeHandle);
+
+    if (nodeID == DTM.NULL)
+      return DTM.NULL;
+
+    int type = _type2(nodeID);
+
+    if (DTM.ELEMENT_NODE == type)
+    {
+      int expType;
+      while (true)
+      {
+	nodeID++;
+	expType = _exptype2(nodeID);
+
+	if (expType != DTM.NULL)
+	  type = m_extendedTypes[expType].getNodeType();
+	else
+	  return DTM.NULL;
+
+	if (type == DTM.ATTRIBUTE_NODE)
+	{
+	  if (expType == attType) return makeNodeHandle(nodeID);
+	}
+	else if (DTM.NAMESPACE_NODE != type)
+	{
+	  break;
+	}
+      }
+    }
+
+    return DTM.NULL;
+  }
+
+  /**
+   * Override SAX2DTM.getLocalName() in SAX2DTM2.
+   * <p>Processing for PIs is different.
+   *
+   * Given a node handle, return its XPath- style localname. (As defined in
+   * Namespaces, this is the portion of the name after any colon character).
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Local name of this node.
+   */
+  public String getLocalName(int nodeHandle)
+  {
+    int expType = _exptype(makeNodeIdentity(nodeHandle));
+
+    if (expType == DTM.PROCESSING_INSTRUCTION_NODE)
+    {
+      int dataIndex = _dataOrQName(makeNodeIdentity(nodeHandle));
+      dataIndex = m_data.elementAt(-dataIndex);
+      return m_valuesOrPrefixes.indexToString(dataIndex);
+    }
+    else
+      return m_expandedNameTable.getLocalName(expType);
+  }
+
+  /**
+   * The optimized version of SAX2DTM.getNodeNameX().
+   * <p>
+   * Given a node handle, return the XPath node name. This should be the name
+   * as described by the XPath data model, NOT the DOM- style name.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   */
+  public final String getNodeNameX(int nodeHandle)
+  {
+
+    int nodeID = makeNodeIdentity(nodeHandle);
+    int eType = _exptype2(nodeID);
+
+    if (eType == DTM.PROCESSING_INSTRUCTION_NODE)
+    {
+      int dataIndex = _dataOrQName(nodeID);
+      dataIndex = m_data.elementAt(-dataIndex);
+      return m_valuesOrPrefixes.indexToString(dataIndex);
+    }
+
+    final ExtendedType extType = m_extendedTypes[eType];
+
+    if (extType.getNamespace().length() == 0)
+    {
+      return extType.getLocalName();
+    }
+    else
+    {
+      int qnameIndex = m_dataOrQName.elementAt(nodeID);
+
+      if (qnameIndex == 0)
+        return extType.getLocalName();
+
+      if (qnameIndex < 0)
+      {
+	qnameIndex = -qnameIndex;
+	qnameIndex = m_data.elementAt(qnameIndex);
+      }
+
+      return m_valuesOrPrefixes.indexToString(qnameIndex);
+    }
+  }
+
+  /**
+   * The optimized version of SAX2DTM.getNodeName().
+   * <p>
+   * Given a node handle, return its DOM-style node name. This will include
+   * names such as #text or #document.
+   *
+   * @param nodeHandle the id of the node.
+   * @return String Name of this node, which may be an empty string.
+   * %REVIEW% Document when empty string is possible...
+   * %REVIEW-COMMENT% It should never be empty, should it?
+   */
+  public String getNodeName(int nodeHandle)
+  {
+
+    int nodeID = makeNodeIdentity(nodeHandle);
+    int eType = _exptype2(nodeID);
+
+    final ExtendedType extType = m_extendedTypes[eType];
+    if (extType.getNamespace().length() == 0)
+    {
+      int type = extType.getNodeType();
+
+      String localName = extType.getLocalName();
+      if (type == DTM.NAMESPACE_NODE)
+      {
+	if (localName.length() == 0)
+	  return "xmlns";
+	else
+	  return "xmlns:" + localName;
+      }
+      else if (type == DTM.PROCESSING_INSTRUCTION_NODE)
+      {
+	int dataIndex = _dataOrQName(nodeID);
+	dataIndex = m_data.elementAt(-dataIndex);
+	return m_valuesOrPrefixes.indexToString(dataIndex);
+      }
+      else if (localName.length() == 0)
+      {
+        return getFixedNames(type);
+      }
+      else
+	return localName;
+    }
+    else
+    {
+      int qnameIndex = m_dataOrQName.elementAt(nodeID);
+
+      if (qnameIndex == 0)
+        return extType.getLocalName();
+
+      if (qnameIndex < 0)
+      {
+	qnameIndex = -qnameIndex;
+	qnameIndex = m_data.elementAt(qnameIndex);
+      }
+
+      return m_valuesOrPrefixes.indexToString(qnameIndex);
+    }
+  }
+
+  /**
+   * Override SAX2DTM.getStringValue(int)
+   * <p>
+   * This method is only used by Xalan-J Interpretive. It is not used by XSLTC.
+   * <p>
+   * If the caller supplies an XMLStringFactory, the getStringValue() interface
+   * in SAX2DTM will be called. Otherwise just calls getStringValueX() and
+   * wraps the returned String in an XMLString.
+   *
+   * Get the string-value of a node as a String object
+   * (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public XMLString getStringValue(int nodeHandle)
+  {
+    int identity = makeNodeIdentity(nodeHandle);
+    if (identity == DTM.NULL)
+      return EMPTY_XML_STR;
+
+    int type= _type2(identity);
+
+    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
+    {
+      int startNode = identity;
+      identity = _firstch2(identity);
+      if (DTM.NULL != identity)
+      {
+	int offset = -1;
+	int length = 0;
+
+	do
+	{
+	  type = _exptype2(identity);
+
+	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
+	  {
+	    int dataIndex = m_dataOrQName.elementAt(identity);
+	    if (dataIndex >= 0)
+	    {
+	      if (-1 == offset)
+	      {
+                offset = dataIndex >>> TEXT_LENGTH_BITS;
+	      }
+
+	      length += dataIndex & TEXT_LENGTH_MAX;
+	    }
+	    else
+	    {
+	      if (-1 == offset)
+	      {
+                offset = m_data.elementAt(-dataIndex);
+	      }
+
+	      length += m_data.elementAt(-dataIndex + 1);
+	    }
+	  }
+
+	  identity++;
+	} while (_parent2(identity) >= startNode);
+
+	if (length > 0)
+	{
+	  if (m_xstrf != null)
+	    return m_xstrf.newstr(m_chars, offset, length);
+	  else
+	    return new XMLStringDefault(m_chars.getString(offset, length));
+	}
+	else
+	  return EMPTY_XML_STR;
+      }
+      else
+        return EMPTY_XML_STR;
+    }
+    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+      if (dataIndex >= 0)
+      {
+      	if (m_xstrf != null)
+      	  return m_xstrf.newstr(m_chars, dataIndex >>> TEXT_LENGTH_BITS,
+      	                 dataIndex & TEXT_LENGTH_MAX);
+      	else
+      	  return new XMLStringDefault(m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
+      	                              dataIndex & TEXT_LENGTH_MAX));
+      }
+      else
+      {
+        if (m_xstrf != null)
+          return m_xstrf.newstr(m_chars, m_data.elementAt(-dataIndex),
+                                m_data.elementAt(-dataIndex+1));
+        else
+          return new XMLStringDefault(m_chars.getString(m_data.elementAt(-dataIndex),
+                                   m_data.elementAt(-dataIndex+1)));
+      }
+    }
+    else
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+
+      if (dataIndex < 0)
+      {
+        dataIndex = -dataIndex;
+        dataIndex = m_data.elementAt(dataIndex + 1);
+      }
+
+      if (m_xstrf != null)
+        return m_xstrf.newstr((String)m_values.elementAt(dataIndex));
+      else
+        return new XMLStringDefault((String)m_values.elementAt(dataIndex));
+    }
+  }
+
+  /**
+   * The optimized version of SAX2DTM.getStringValue(int).
+   * <p>
+   * %OPT% This is one of the most often used interfaces. Performance is
+   * critical here. This one is different from SAX2DTM.getStringValue(int) in
+   * that it returns a String instead of a XMLString.
+   *
+   * Get the string- value of a node as a String object (see http: //www. w3.
+   * org/TR/xpath#data- model for the definition of a node's string- value).
+   *
+   * @param nodeHandle The node ID.
+   *
+   * @return A string object that represents the string-value of the given node.
+   */
+  public final String getStringValueX(final int nodeHandle)
+  {
+    int identity = makeNodeIdentity(nodeHandle);
+    if (identity == DTM.NULL)
+      return EMPTY_STR;
+
+    int type= _type2(identity);
+
+    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
+    {
+      int startNode = identity;
+      identity = _firstch2(identity);
+      if (DTM.NULL != identity)
+      {
+	int offset = -1;
+	int length = 0;
+
+	do
+	{
+	  type = _exptype2(identity);
+
+	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
+	  {
+	    int dataIndex = m_dataOrQName.elementAt(identity);
+	    if (dataIndex >= 0)
+	    {
+	      if (-1 == offset)
+	      {
+                offset = dataIndex >>> TEXT_LENGTH_BITS;
+	      }
+
+	      length += dataIndex & TEXT_LENGTH_MAX;
+	    }
+	    else
+	    {
+	      if (-1 == offset)
+	      {
+                offset = m_data.elementAt(-dataIndex);
+	      }
+
+	      length += m_data.elementAt(-dataIndex + 1);
+	    }
+	  }
+
+	  identity++;
+	} while (_parent2(identity) >= startNode);
+
+	if (length > 0)
+	{
+	  return m_chars.getString(offset, length);
+	}
+	else
+	  return EMPTY_STR;
+      }
+      else
+        return EMPTY_STR;
+    }
+    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+      if (dataIndex >= 0)
+      {
+      	return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
+      	                          dataIndex & TEXT_LENGTH_MAX);
+      }
+      else
+      {
+        return m_chars.getString(m_data.elementAt(-dataIndex),
+                                  m_data.elementAt(-dataIndex+1));
+      }
+    }
+    else
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+
+      if (dataIndex < 0)
+      {
+        dataIndex = -dataIndex;
+        dataIndex = m_data.elementAt(dataIndex + 1);
+      }
+
+      return (String)m_values.elementAt(dataIndex);
+    }
+  }
+
+  /**
+   * Returns the string value of the entire tree
+   */
+  public String getStringValue()
+  {
+    int child = _firstch2(ROOTNODE);
+    if (child == DTM.NULL) return EMPTY_STR;
+
+    // optimization: only create StringBuffer if > 1 child
+    if ((_exptype2(child) == DTM.TEXT_NODE) && (_nextsib2(child) == DTM.NULL))
+    {
+      int dataIndex = m_dataOrQName.elementAt(child);
+      if (dataIndex >= 0)
+        return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS, dataIndex & TEXT_LENGTH_MAX);
+      else
+        return m_chars.getString(m_data.elementAt(-dataIndex),
+                                  m_data.elementAt(-dataIndex + 1));
+    }
+    else
+      return getStringValueX(getDocument());
+
+  }
+
+  /**
+   * The optimized version of SAX2DTM.dispatchCharactersEvents(int, ContentHandler, boolean).
+   * <p>
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
+   * for the definition of a node's string-value). Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param nodeHandle The node ID.
+   * @param ch A non-null reference to a ContentHandler.
+   * @param normalize true if the content should be normalized according to
+   * the rules for the XPath
+   * <a href="http://www.w3.org/TR/xpath#function-normalize-space">normalize-space</a>
+   * function.
+   *
+   * @throws SAXException
+   */
+  public final void dispatchCharactersEvents(int nodeHandle, ContentHandler ch,
+                                             boolean normalize)
+          throws SAXException
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+
+    if (identity == DTM.NULL)
+      return;
+
+    int type = _type2(identity);
+
+    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
+    {
+      int startNode = identity;
+      identity = _firstch2(identity);
+      if (DTM.NULL != identity)
+      {
+	int offset = -1;
+	int length = 0;
+
+	do
+	{
+	  type = _exptype2(identity);
+
+	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
+	  {
+	    int dataIndex = m_dataOrQName.elementAt(identity);
+
+	    if (dataIndex >= 0)
+	    {
+	      if (-1 == offset)
+	      {
+                offset = dataIndex >>> TEXT_LENGTH_BITS;
+	      }
+
+	      length += dataIndex & TEXT_LENGTH_MAX;
+	    }
+	    else
+	    {
+	      if (-1 == offset)
+	      {
+                offset = m_data.elementAt(-dataIndex);
+	      }
+
+	      length += m_data.elementAt(-dataIndex + 1);
+	    }
+	  }
+
+	  identity++;
+	} while (_parent2(identity) >= startNode);
+
+	if (length > 0)
+	{
+          if(normalize)
+            m_chars.sendNormalizedSAXcharacters(ch, offset, length);
+          else
+	    m_chars.sendSAXcharacters(ch, offset, length);
+	}
+      }
+    }
+    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+
+      if (dataIndex >= 0)
+      {
+      	if (normalize)
+      	  m_chars.sendNormalizedSAXcharacters(ch, dataIndex >>> TEXT_LENGTH_BITS,
+      	                                      dataIndex & TEXT_LENGTH_MAX);
+      	else
+      	  m_chars.sendSAXcharacters(ch, dataIndex >>> TEXT_LENGTH_BITS,
+      	                            dataIndex & TEXT_LENGTH_MAX);
+      }
+      else
+      {
+        if (normalize)
+          m_chars.sendNormalizedSAXcharacters(ch, m_data.elementAt(-dataIndex),
+                                              m_data.elementAt(-dataIndex+1));
+        else
+          m_chars.sendSAXcharacters(ch, m_data.elementAt(-dataIndex),
+                                    m_data.elementAt(-dataIndex+1));
+      }
+    }
+    else
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+
+      if (dataIndex < 0)
+      {
+        dataIndex = -dataIndex;
+        dataIndex = m_data.elementAt(dataIndex + 1);
+      }
+
+      String str = (String)m_values.elementAt(dataIndex);
+
+      if(normalize)
+        FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
+                                                     0, str.length(), ch);
+      else
+        ch.characters(str.toCharArray(), 0, str.length());
+    }
+  }
+
+  /**
+   * Given a node handle, return its node value. This is mostly
+   * as defined by the DOM, but may ignore some conveniences.
+   * <p>
+   *
+   * @param nodeHandle The node id.
+   * @return String Value of this node, or null if not
+   * meaningful for this node type.
+   */
+  public String getNodeValue(int nodeHandle)
+  {
+
+    int identity = makeNodeIdentity(nodeHandle);
+    int type = _type2(identity);
+
+    if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
+    {
+      int dataIndex = _dataOrQName(identity);
+      if (dataIndex > 0)
+      {
+      	return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
+      	                          dataIndex & TEXT_LENGTH_MAX);
+      }
+      else
+      {
+        return m_chars.getString(m_data.elementAt(-dataIndex),
+                                  m_data.elementAt(-dataIndex+1));
+      }
+    }
+    else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type
+             || DTM.DOCUMENT_NODE == type)
+    {
+      return null;
+    }
+    else
+    {
+      int dataIndex = m_dataOrQName.elementAt(identity);
+
+      if (dataIndex < 0)
+      {
+        dataIndex = -dataIndex;
+        dataIndex = m_data.elementAt(dataIndex + 1);
+      }
+
+      return (String)m_values.elementAt(dataIndex);
+    }
+  }
+
+    /**
+     * Copy the String value of a Text node to a SerializationHandler
+     */
+    protected final void copyTextNode(final int nodeID, SerializationHandler handler)
+        throws SAXException
+    {
+        if (nodeID != DTM.NULL) {
+      	    int dataIndex = m_dataOrQName.elementAt(nodeID);
+            if (dataIndex >= 0) {
+                m_chars.sendSAXcharacters(handler,
+                                          dataIndex >>> TEXT_LENGTH_BITS,
+                                          dataIndex & TEXT_LENGTH_MAX);
+            } else {
+                m_chars.sendSAXcharacters(handler, m_data.elementAt(-dataIndex),
+                                          m_data.elementAt(-dataIndex+1));
+            }
+        }
+    }
+
+    /**
+     * Copy an Element node to a SerializationHandler.
+     *
+     * @param nodeID The node identity
+     * @param exptype The expanded type of the Element node
+     * @param handler The SerializationHandler
+     * @return The qualified name of the Element node.
+     */
+    protected final String copyElement(int nodeID, int exptype,
+                               SerializationHandler handler)
+        throws SAXException
+    {
+        final ExtendedType extType = m_extendedTypes[exptype];
+        String uri = extType.getNamespace();
+        String name = extType.getLocalName();
+
+        if (uri.length() == 0) {
+            handler.startElement(name);
+            return name;
+        }
+        else {
+            int qnameIndex = m_dataOrQName.elementAt(nodeID);
+
+            if (qnameIndex == 0) {
+                handler.startElement(name);
+                handler.namespaceAfterStartElement(EMPTY_STR, uri);
+                return name;
+            }
+
+            if (qnameIndex < 0) {
+    	        qnameIndex = -qnameIndex;
+    	        qnameIndex = m_data.elementAt(qnameIndex);
+            }
+
+            String qName = m_valuesOrPrefixes.indexToString(qnameIndex);
+            handler.startElement(qName);
+            int prefixIndex = qName.indexOf(':');
+            String prefix;
+            if (prefixIndex > 0) {
+                prefix = qName.substring(0, prefixIndex);
+            }
+            else {
+                prefix = null;
+            }
+            handler.namespaceAfterStartElement(prefix, uri);
+            return qName;
+        }
+
+    }
+
+    /**
+     * Copy  namespace nodes.
+     *
+     * @param nodeID The Element node identity
+     * @param handler The SerializationHandler
+     * @param inScope  true if all namespaces in scope should be copied,
+     *  false if only the namespace declarations should be copied.
+     */
+    protected final void copyNS(final int nodeID, SerializationHandler handler, boolean inScope)
+        throws SAXException
+    {
+        // %OPT% Optimization for documents which does not have any explicit
+        // namespace nodes. For these documents, there is an implicit
+        // namespace node (xmlns:xml="http://www.w3.org/XML/1998/namespace")
+        // declared on the root element node. In this case, there is no
+        // need to do namespace copying. We can safely return without
+        // doing anything.
+        if (m_namespaceDeclSetElements != null &&
+            m_namespaceDeclSetElements.size() == 1 &&
+            m_namespaceDeclSets != null &&
+            ((SuballocatedIntVector)m_namespaceDeclSets.elementAt(0))
+            .size() == 1)
+            return;
+
+        SuballocatedIntVector nsContext = null;
+        int nextNSNode;
+
+        // Find the first namespace node
+        if (inScope) {
+            nsContext = findNamespaceContext(nodeID);
+            if (nsContext == null || nsContext.size() < 1)
+                return;
+            else
+                nextNSNode = makeNodeIdentity(nsContext.elementAt(0));
+        }
+        else
+            nextNSNode = getNextNamespaceNode2(nodeID);
+
+        int nsIndex = 1;
+        while (nextNSNode != DTM.NULL) {
+            // Retrieve the name of the namespace node
+            int eType = _exptype2(nextNSNode);
+            String nodeName = m_extendedTypes[eType].getLocalName();
+
+            // Retrieve the node value of the namespace node
+            int dataIndex = m_dataOrQName.elementAt(nextNSNode);
+
+            if (dataIndex < 0) {
+                dataIndex = -dataIndex;
+                dataIndex = m_data.elementAt(dataIndex + 1);
+            }
+
+            String nodeValue = (String)m_values.elementAt(dataIndex);
+
+            handler.namespaceAfterStartElement(nodeName, nodeValue);
+
+            if (inScope) {
+                if (nsIndex < nsContext.size()) {
+                    nextNSNode = makeNodeIdentity(nsContext.elementAt(nsIndex));
+                    nsIndex++;
+                }
+                else
+                    return;
+            }
+            else
+                nextNSNode = getNextNamespaceNode2(nextNSNode);
+        }
+    }
+
+    /**
+     * Return the next namespace node following the given base node.
+     *
+     * @baseID The node identity of the base node, which can be an
+     * element, attribute or namespace node.
+     * @return The namespace node immediately following the base node.
+     */
+    protected final int getNextNamespaceNode2(int baseID) {
+        int type;
+        while ((type = _type2(++baseID)) == DTM.ATTRIBUTE_NODE);
+
+        if (type == DTM.NAMESPACE_NODE)
+            return baseID;
+        else
+            return NULL;
+    }
+
+    /**
+     * Copy  attribute nodes from an element .
+     *
+     * @param nodeID The Element node identity
+     * @param handler The SerializationHandler
+     */
+    protected final void copyAttributes(final int nodeID, SerializationHandler handler)
+        throws SAXException{
+
+       for(int current = getFirstAttributeIdentity(nodeID); current != DTM.NULL; current = getNextAttributeIdentity(current)){
+            int eType = _exptype2(current);
+            copyAttribute(current, eType, handler);
+       }
+    }
+
+
+
+    /**
+     * Copy an Attribute node to a SerializationHandler
+     *
+     * @param nodeID The node identity
+     * @param exptype The expanded type of the Element node
+     * @param handler The SerializationHandler
+     */
+    protected final void copyAttribute(int nodeID, int exptype,
+        SerializationHandler handler)
+        throws SAXException
+    {
+        /*
+            final String uri = getNamespaceName(node);
+            if (uri.length() != 0) {
+                final String prefix = getPrefix(node);
+                handler.namespaceAfterStartElement(prefix, uri);
+            }
+            handler.addAttribute(getNodeName(node), getNodeValue(node));
+        */
+        final ExtendedType extType = m_extendedTypes[exptype];
+        final String uri = extType.getNamespace();
+        final String localName = extType.getLocalName();
+
+        String prefix = null;
+        String qname = null;
+        int dataIndex = _dataOrQName(nodeID);
+        int valueIndex = dataIndex;
+            if (dataIndex <= 0) {
+                int prefixIndex = m_data.elementAt(-dataIndex);
+                valueIndex = m_data.elementAt(-dataIndex+1);
+                qname = m_valuesOrPrefixes.indexToString(prefixIndex);
+                int colonIndex = qname.indexOf(':');
+                if (colonIndex > 0) {
+                    prefix = qname.substring(0, colonIndex);
+                }
+            }
+            if (uri.length() != 0) {
+                handler.namespaceAfterStartElement(prefix, uri);
+            }
+
+        String nodeName = (prefix != null) ? qname : localName;
+        String nodeValue = (String)m_values.elementAt(valueIndex);
+
+        handler.addAttribute(nodeName, nodeValue);
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java
new file mode 100644
index 0000000..da04a06
--- /dev/null
+++ b/src/main/java/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java
@@ -0,0 +1,362 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SAX2RTFDTM.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.dtm.ref.sax2dtm;
+
+import javax.xml.transform.Source;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.IntVector;
+import org.apache.xml.utils.StringVector;
+import org.apache.xml.utils.XMLStringFactory;
+
+import org.xml.sax.SAXException;
+
+/**
+ * This is a subclass of SAX2DTM which has been modified to meet the needs of
+ * Result Tree Frameworks (RTFs). The differences are:
+ *
+ * 1) Multiple XML trees may be appended to the single DTM. This means
+ * that the root node of each document is _not_ node 0. Some code has
+ * had to be deoptimized to support this mode of operation, and an
+ * explicit mechanism for obtaining the Node Handle of the root node
+ * has been provided.
+ *
+ * 2) A stack of these documents is maintained, allowing us to "tail-prune" the
+ * most recently added trees off the end of the DTM as stylesheet elements 
+ * (and thus variable contexts) are exited.
+ *
+ * PLEASE NOTE that this class may be _heavily_ dependent upon the
+ * internals of the SAX2DTM superclass, and must be maintained in
+ * parallel with that code.  Arguably, they should be conditionals
+ * within a single class... but they have deen separated for
+ * performance reasons. (In fact, one could even argue about which is
+ * the superclass and which is the subclass; the current arrangement
+ * is as much about preserving stability of existing code during
+ * development as anything else.)
+ * 
+ * %REVIEW% In fact, since the differences are so minor, I think it
+ * may be possible/practical to fold them back into the base
+ * SAX2DTM. Consider that as a future code-size optimization.
+ * */
+public class SAX2RTFDTM extends SAX2DTM
+{
+  /** Set true to monitor SAX events and similar diagnostic info. */
+  private static final boolean DEBUG = false;
+  
+  /** Most recently started Document, or null if the DTM is empty.  */
+  private int m_currentDocumentNode=NULL;
+  
+  /** Tail-pruning mark: Number of nodes in use */
+  IntStack mark_size=new IntStack();
+  /** Tail-pruning mark: Number of data items in use */
+  IntStack mark_data_size=new IntStack();
+  /** Tail-pruning mark: Number of size-of-data fields in use */
+  IntStack mark_char_size=new IntStack();
+  /** Tail-pruning mark: Number of dataOrQName slots in use */
+  IntStack mark_doq_size=new IntStack();
+  /** Tail-pruning mark: Number of namespace declaration sets in use
+   * %REVIEW% I don't think number of NS sets is ever different from number
+   * of NS elements. We can probabably reduce these to a single stack and save
+   * some storage.
+   * */
+  IntStack mark_nsdeclset_size=new IntStack();
+  /** Tail-pruning mark: Number of naespace declaration elements in use
+   * %REVIEW% I don't think number of NS sets is ever different from number
+   * of NS elements. We can probabably reduce these to a single stack and save
+   * some storage.
+   */
+  IntStack mark_nsdeclelem_size=new IntStack();
+
+  /**
+   * Tail-pruning mark:  initial number of nodes in use
+   */
+  int m_emptyNodeCount;
+
+  /**
+   * Tail-pruning mark:  initial number of namespace declaration sets
+   */
+  int m_emptyNSDeclSetCount;
+
+  /**
+   * Tail-pruning mark:  initial number of namespace declaration elements
+   */
+  int m_emptyNSDeclSetElemsCount;
+
+  /**
+   * Tail-pruning mark:  initial number of data items in use
+   */
+  int m_emptyDataCount;
+
+  /**
+   * Tail-pruning mark:  initial number of characters in use
+   */
+  int m_emptyCharsCount;
+
+  /**
+   * Tail-pruning mark:  default initial number of dataOrQName slots in use
+   */
+  int m_emptyDataQNCount;
+  
+  public SAX2RTFDTM(DTMManager mgr, Source source, int dtmIdentity,
+                 DTMWSFilter whiteSpaceFilter,
+                 XMLStringFactory xstringfactory,
+                 boolean doIndexing)
+  {
+    super(mgr, source, dtmIdentity, whiteSpaceFilter, 
+          xstringfactory, doIndexing);
+          
+    // NEVER track source locators for RTFs; they aren't meaningful. I think.
+    // (If we did track them, we'd need to tail-prune these too.)
+    //org.apache.xalan.processor.TransformerFactoryImpl.m_source_location;
+    m_useSourceLocationProperty=false;
+    m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector()
+                                                     : null;
+    m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null;
+    m_sourceColumn = (m_useSourceLocationProperty) ? new IntVector() : null;
+
+    // Record initial sizes of fields that are pushed and restored
+    // for RTF tail-pruning.  More entries can be popped than pushed, so
+    // we need this to mark the primordial state of the DTM.
+    m_emptyNodeCount = m_size;
+    m_emptyNSDeclSetCount = (m_namespaceDeclSets == null)
+                                 ? 0 : m_namespaceDeclSets.size();
+    m_emptyNSDeclSetElemsCount = (m_namespaceDeclSetElements == null)
+                                      ? 0 : m_namespaceDeclSetElements.size();
+    m_emptyDataCount = m_data.size();
+    m_emptyCharsCount = m_chars.size();
+    m_emptyDataQNCount = m_dataOrQName.size();
+  }
+  
+  /**
+   * Given a DTM, find the owning document node. In the case of
+   * SAX2RTFDTM, which may contain multiple documents, this returns
+   * the <b>most recently started</b> document, or null if the DTM is
+   * empty or no document is currently under construction.
+   *
+   * %REVIEW% Should we continue to report the most recent after
+   * construction has ended? I think not, given that it may have been
+   * tail-pruned.
+   *
+   *  @return int Node handle of Document node, or null if this DTM does not
+   *  contain an "active" document.
+   * */
+  public int getDocument()
+  {
+    return makeNodeHandle(m_currentDocumentNode);
+  }
+
+  /**
+   * Given a node handle, find the owning document node, using DTM semantics
+   * (Document owns itself) rather than DOM semantics (Document has no owner).
+   *
+   * (I'm counting on the fact that getOwnerDocument() is implemented on top
+   * of this call, in the superclass, to avoid having to rewrite that one.
+   * Be careful if that code changes!)
+   *
+   * @param nodeHandle the id of the node.
+   * @return int Node handle of owning document
+   */
+  public int getDocumentRoot(int nodeHandle)
+  {
+    for (int id=makeNodeIdentity(nodeHandle); id!=NULL; id=_parent(id)) {
+      if (_type(id)==DTM.DOCUMENT_NODE) {
+        return makeNodeHandle(id);
+      }
+    }
+
+    return DTM.NULL; // Safety net; should never happen
+  }
+  
+  /**
+   * Given a node identifier, find the owning document node.  Unlike the DOM,
+   * this considers the owningDocument of a Document to be itself. Note that
+   * in shared DTMs this may not be zero.
+   *
+   * @param nodeIdentifier the id of the starting node.
+   * @return int Node identifier of the root of this DTM tree
+   */
+  protected int _documentRoot(int nodeIdentifier)
+  {
+    if(nodeIdentifier==NULL) return NULL;
+
+    for (int parent=_parent(nodeIdentifier);
+         parent!=NULL;
+         nodeIdentifier=parent,parent=_parent(nodeIdentifier))
+      ;
+   
+    return nodeIdentifier;
+  }
+
+  /**
+   * Receive notification of the beginning of a new RTF document.
+   *
+   * %REVIEW% Y'know, this isn't all that much of a deoptimization. We
+   * might want to consider folding the start/endDocument changes back
+   * into the main SAX2DTM so we don't have to expose so many fields
+   * (even as Protected) and carry the additional code.
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#startDocument
+   * */
+  public void startDocument() throws SAXException
+  {
+    // Re-initialize the tree append process
+    m_endDocumentOccured = false;
+    m_prefixMappings = new java.util.Vector();
+    m_contextIndexes = new IntStack();
+    m_parents = new IntStack();
+   
+    m_currentDocumentNode=m_size;
+    super.startDocument();
+  }
+ 
+  /**
+   * Receive notification of the end of the document.
+   *
+   * %REVIEW% Y'know, this isn't all that much of a deoptimization. We
+   * might want to consider folding the start/endDocument changes back
+   * into the main SAX2DTM so we don't have to expose so many fields
+   * (even as Protected).
+   *
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#endDocument
+   * */
+  public void endDocument() throws SAXException
+  {
+    charactersFlush();
+
+    m_nextsib.setElementAt(NULL,m_currentDocumentNode);
+
+    if (m_firstch.elementAt(m_currentDocumentNode) == NOTPROCESSED)
+      m_firstch.setElementAt(NULL,m_currentDocumentNode);
+
+    if (DTM.NULL != m_previous)
+      m_nextsib.setElementAt(DTM.NULL,m_previous);
+
+    m_parents = null;
+    m_prefixMappings = null;
+    m_contextIndexes = null;
+
+    m_currentDocumentNode= NULL; // no longer open
+    m_endDocumentOccured = true;
+  }
+ 
+
+  /** "Tail-pruning" support for RTFs.
+   *
+   * This function pushes information about the current size of the
+   * DTM's data structures onto a stack, for use by popRewindMark()
+   * (which see).
+   *
+   * %REVIEW% I have no idea how to rewind m_elemIndexes. However,
+   * RTFs will not be indexed, so I can simply panic if that case
+   * arises. Hey, it works...
+   * */
+  public void pushRewindMark()
+  {
+    if(m_indexing || m_elemIndexes!=null)
+      throw new java.lang.NullPointerException("Coding error; Don't try to mark/rewind an indexed DTM");
+
+    // Values from DTMDefaultBase
+    // %REVIEW% Can the namespace stack sizes ever differ? If not, save space!
+    mark_size.push(m_size);
+    mark_nsdeclset_size.push((m_namespaceDeclSets==null)
+                                   ? 0
+                                   : m_namespaceDeclSets.size());
+    mark_nsdeclelem_size.push((m_namespaceDeclSetElements==null)
+                                   ? 0
+                                   : m_namespaceDeclSetElements.size());
+   
+    // Values from SAX2DTM
+    mark_data_size.push(m_data.size());
+    mark_char_size.push(m_chars.size());
+    mark_doq_size.push(m_dataOrQName.size());
+  }
+ 
+  /** "Tail-pruning" support for RTFs.
+   *
+   * This function pops the information previously saved by
+   * pushRewindMark (which see) and uses it to discard all nodes added
+   * to the DTM after that time. We expect that this will allow us to
+   * reuse storage more effectively.
+   *
+   * This is _not_ intended to be called while a document is still being
+   * constructed -- only between endDocument and the next startDocument
+   *
+   * %REVIEW% WARNING: This is the first use of some of the truncation
+   * methods.  If Xalan blows up after this is called, that's a likely
+   * place to check.
+   *
+   * %REVIEW% Our original design for DTMs permitted them to share
+   * string pools.  If there any risk that this might be happening, we
+   * can _not_ rewind and recover the string storage. One solution
+   * might to assert that DTMs used for RTFs Must Not take advantage
+   * of that feature, but this seems excessively fragile. Another, much
+   * less attractive, would be to just let them leak... Nah.
+   *
+   * @return true if and only if the pop completely emptied the
+   * RTF. That response is used when determining how to unspool
+   * RTF-started-while-RTF-open situations.
+   * */
+  public boolean popRewindMark()
+  {
+    boolean top=mark_size.empty();
+   
+    m_size=top ? m_emptyNodeCount : mark_size.pop();
+    m_exptype.setSize(m_size);
+    m_firstch.setSize(m_size);
+    m_nextsib.setSize(m_size);
+    m_prevsib.setSize(m_size);
+    m_parent.setSize(m_size);
+
+    m_elemIndexes=null;
+
+    int ds= top ? m_emptyNSDeclSetCount : mark_nsdeclset_size.pop();
+    if (m_namespaceDeclSets!=null) {
+      m_namespaceDeclSets.setSize(ds);
+    }
+
+    int ds1= top ? m_emptyNSDeclSetElemsCount : mark_nsdeclelem_size.pop();
+    if (m_namespaceDeclSetElements!=null) {
+      m_namespaceDeclSetElements.setSize(ds1);
+    }
+ 
+    // Values from SAX2DTM - m_data always has a reserved entry
+    m_data.setSize(top ? m_emptyDataCount : mark_data_size.pop());
+    m_chars.setLength(top ? m_emptyCharsCount : mark_char_size.pop());
+    m_dataOrQName.setSize(top ? m_emptyDataQNCount : mark_doq_size.pop());
+
+    // Return true iff DTM now empty
+    return m_size==0;
+  }
+ 
+  /** @return true if a DTM tree is currently under construction.
+   * */
+  public boolean isTreeIncomplete()
+  {
+    return !m_endDocumentOccured;
+  }
+}
diff --git a/src/main/java/org/apache/xml/res/XMLErrorResources.java b/src/main/java/org/apache/xml/res/XMLErrorResources.java
new file mode 100644
index 0000000..ef036f2
--- /dev/null
+++ b/src/main/java/org/apache/xml/res/XMLErrorResources.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLErrorResources.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.res;
+
+
+import java.util.ListResourceBundle;
+
+/**
+ * Set up error messages.
+ * We build a two dimensional array of message keys and
+ * message strings. In order to add a new message here,
+ * you need to first add a String constant. And you need
+ * to enter key, value pair as part of the contents
+ * array. You also need to update MAX_CODE for error strings
+ * and MAX_WARNING for warnings ( Needed for only information
+ * purpose )
+ */
+public class XMLErrorResources extends ListResourceBundle
+{
+
+/*
+ * This file contains error and warning messages related to Xalan Error
+ * Handling.
+ *
+ *  General notes to translators:
+ *
+ *  1) Xalan (or more properly, Xalan-interpretive) and XSLTC are names of
+ *     components.
+ *     XSLT is an acronym for "XML Stylesheet Language: Transformations".
+ *     XSLTC is an acronym for XSLT Compiler.
+ *
+ *  2) A stylesheet is a description of how to transform an input XML document
+ *     into a resultant XML document (or HTML document or text).  The
+ *     stylesheet itself is described in the form of an XML document.
+ *
+ *  3) A template is a component of a stylesheet that is used to match a
+ *     particular portion of an input document and specifies the form of the
+ *     corresponding portion of the output document.
+ *
+ *  4) An element is a mark-up tag in an XML document; an attribute is a
+ *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+ *     "elem" is an element name, "attr" and "attr2" are attribute names with
+ *     the values "val" and "val2", respectively.
+ *
+ *  5) A namespace declaration is a special attribute that is used to associate
+ *     a prefix with a URI (the namespace).  The meanings of element names and
+ *     attribute names that use that prefix are defined with respect to that
+ *     namespace.
+ *
+ *  6) "Translet" is an invented term that describes the class file that
+ *     results from compiling an XML stylesheet into a Java class.
+ *
+ *  7) XPath is a specification that describes a notation for identifying
+ *     nodes in a tree-structured representation of an XML document.  An
+ *     instance of that notation is referred to as an XPath expression.
+ *
+ */
+
+  /* 
+   * Message keys
+   */
+  public static final String ER_FUNCTION_NOT_SUPPORTED = "ER_FUNCTION_NOT_SUPPORTED";
+  public static final String ER_CANNOT_OVERWRITE_CAUSE = "ER_CANNOT_OVERWRITE_CAUSE";
+  public static final String ER_NO_DEFAULT_IMPL = "ER_NO_DEFAULT_IMPL";
+  public static final String ER_CHUNKEDINTARRAY_NOT_SUPPORTED = "ER_CHUNKEDINTARRAY_NOT_SUPPORTED";
+  public static final String ER_OFFSET_BIGGER_THAN_SLOT = "ER_OFFSET_BIGGER_THAN_SLOT";
+  public static final String ER_COROUTINE_NOT_AVAIL = "ER_COROUTINE_NOT_AVAIL";
+  public static final String ER_COROUTINE_CO_EXIT = "ER_COROUTINE_CO_EXIT";
+  public static final String ER_COJOINROUTINESET_FAILED = "ER_COJOINROUTINESET_FAILED";
+  public static final String ER_COROUTINE_PARAM = "ER_COROUTINE_PARAM";
+  public static final String ER_PARSER_DOTERMINATE_ANSWERS = "ER_PARSER_DOTERMINATE_ANSWERS";
+  public static final String ER_NO_PARSE_CALL_WHILE_PARSING = "ER_NO_PARSE_CALL_WHILE_PARSING";
+  public static final String ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED = "ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED";
+  public static final String ER_ITERATOR_AXIS_NOT_IMPLEMENTED = "ER_ITERATOR_AXIS_NOT_IMPLEMENTED";
+  public static final String ER_ITERATOR_CLONE_NOT_SUPPORTED = "ER_ITERATOR_CLONE_NOT_SUPPORTED";
+  public static final String ER_UNKNOWN_AXIS_TYPE = "ER_UNKNOWN_AXIS_TYPE";
+  public static final String ER_AXIS_NOT_SUPPORTED = "ER_AXIS_NOT_SUPPORTED";
+  public static final String ER_NO_DTMIDS_AVAIL = "ER_NO_DTMIDS_AVAIL";
+  public static final String ER_NOT_SUPPORTED = "ER_NOT_SUPPORTED";
+  public static final String ER_NODE_NON_NULL = "ER_NODE_NON_NULL";
+  public static final String ER_COULD_NOT_RESOLVE_NODE = "ER_COULD_NOT_RESOLVE_NODE";
+  public static final String ER_STARTPARSE_WHILE_PARSING = "ER_STARTPARSE_WHILE_PARSING";
+  public static final String ER_STARTPARSE_NEEDS_SAXPARSER = "ER_STARTPARSE_NEEDS_SAXPARSER";
+  public static final String ER_COULD_NOT_INIT_PARSER = "ER_COULD_NOT_INIT_PARSER";
+  public static final String ER_EXCEPTION_CREATING_POOL = "ER_EXCEPTION_CREATING_POOL";
+  public static final String ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE = "ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE";
+  public static final String ER_SCHEME_REQUIRED = "ER_SCHEME_REQUIRED";
+  public static final String ER_NO_SCHEME_IN_URI = "ER_NO_SCHEME_IN_URI";
+  public static final String ER_NO_SCHEME_INURI = "ER_NO_SCHEME_INURI";
+  public static final String ER_PATH_INVALID_CHAR = "ER_PATH_INVALID_CHAR";
+  public static final String ER_SCHEME_FROM_NULL_STRING = "ER_SCHEME_FROM_NULL_STRING";
+  public static final String ER_SCHEME_NOT_CONFORMANT = "ER_SCHEME_NOT_CONFORMANT";
+  public static final String ER_HOST_ADDRESS_NOT_WELLFORMED = "ER_HOST_ADDRESS_NOT_WELLFORMED";
+  public static final String ER_PORT_WHEN_HOST_NULL = "ER_PORT_WHEN_HOST_NULL";
+  public static final String ER_INVALID_PORT = "ER_INVALID_PORT";
+  public static final String ER_FRAG_FOR_GENERIC_URI ="ER_FRAG_FOR_GENERIC_URI";
+  public static final String ER_FRAG_WHEN_PATH_NULL = "ER_FRAG_WHEN_PATH_NULL";
+  public static final String ER_FRAG_INVALID_CHAR = "ER_FRAG_INVALID_CHAR";
+  public static final String ER_PARSER_IN_USE = "ER_PARSER_IN_USE";
+  public static final String ER_CANNOT_CHANGE_WHILE_PARSING = "ER_CANNOT_CHANGE_WHILE_PARSING";
+  public static final String ER_SELF_CAUSATION_NOT_PERMITTED = "ER_SELF_CAUSATION_NOT_PERMITTED";
+  public static final String ER_NO_USERINFO_IF_NO_HOST = "ER_NO_USERINFO_IF_NO_HOST";
+  public static final String ER_NO_PORT_IF_NO_HOST = "ER_NO_PORT_IF_NO_HOST";
+  public static final String ER_NO_QUERY_STRING_IN_PATH = "ER_NO_QUERY_STRING_IN_PATH";
+  public static final String ER_NO_FRAGMENT_STRING_IN_PATH = "ER_NO_FRAGMENT_STRING_IN_PATH";
+  public static final String ER_CANNOT_INIT_URI_EMPTY_PARMS = "ER_CANNOT_INIT_URI_EMPTY_PARMS";
+  public static final String ER_METHOD_NOT_SUPPORTED ="ER_METHOD_NOT_SUPPORTED";
+  public static final String ER_INCRSAXSRCFILTER_NOT_RESTARTABLE = "ER_INCRSAXSRCFILTER_NOT_RESTARTABLE";
+  public static final String ER_XMLRDR_NOT_BEFORE_STARTPARSE = "ER_XMLRDR_NOT_BEFORE_STARTPARSE";
+  public static final String ER_AXIS_TRAVERSER_NOT_SUPPORTED = "ER_AXIS_TRAVERSER_NOT_SUPPORTED";
+  public static final String ER_ERRORHANDLER_CREATED_WITH_NULL_PRINTWRITER = "ER_ERRORHANDLER_CREATED_WITH_NULL_PRINTWRITER";
+  public static final String ER_SYSTEMID_UNKNOWN = "ER_SYSTEMID_UNKNOWN";
+  public static final String ER_LOCATION_UNKNOWN = "ER_LOCATION_UNKNOWN";
+  public static final String ER_PREFIX_MUST_RESOLVE = "ER_PREFIX_MUST_RESOLVE";
+  public static final String ER_CREATEDOCUMENT_NOT_SUPPORTED = "ER_CREATEDOCUMENT_NOT_SUPPORTED";  
+  public static final String ER_CHILD_HAS_NO_OWNER_DOCUMENT = "ER_CHILD_HAS_NO_OWNER_DOCUMENT";
+  public static final String ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT = "ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT";  
+  public static final String ER_CANT_OUTPUT_TEXT_BEFORE_DOC = "ER_CANT_OUTPUT_TEXT_BEFORE_DOC";  
+  public static final String ER_CANT_HAVE_MORE_THAN_ONE_ROOT = "ER_CANT_HAVE_MORE_THAN_ONE_ROOT";  
+  public static final String ER_ARG_LOCALNAME_NULL = "ER_ARG_LOCALNAME_NULL";  
+  public static final String ER_ARG_LOCALNAME_INVALID = "ER_ARG_LOCALNAME_INVALID";  
+  public static final String ER_ARG_PREFIX_INVALID = "ER_ARG_PREFIX_INVALID";  
+  public static final String ER_NAME_CANT_START_WITH_COLON = "ER_NAME_CANT_START_WITH_COLON";
+
+  /*
+   * Now fill in the message text.
+   * Then fill in the message text for that message code in the
+   * array. Use the new error code as the index into the array.
+   */
+
+  // Error messages...
+
+  /**
+   * Get the lookup table for error messages
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][] {
+
+  /** Error message ID that has a null message, but takes in a single object.    */
+    {"ER0000" , "{0}" },
+ 
+    { ER_FUNCTION_NOT_SUPPORTED, 
+      "Function not supported!"},
+
+    { ER_CANNOT_OVERWRITE_CAUSE,
+      "Cannot overwrite cause"},
+
+    { ER_NO_DEFAULT_IMPL,
+      "No default implementation found "},
+
+    { ER_CHUNKEDINTARRAY_NOT_SUPPORTED,
+      "ChunkedIntArray({0}) not currently supported"},
+
+    { ER_OFFSET_BIGGER_THAN_SLOT,
+      "Offset bigger than slot"},
+
+    { ER_COROUTINE_NOT_AVAIL,
+      "Coroutine not available, id={0}"},
+    
+    { ER_COROUTINE_CO_EXIT,
+      "CoroutineManager received co_exit() request"},
+
+    { ER_COJOINROUTINESET_FAILED,
+      "co_joinCoroutineSet() failed"},
+
+    { ER_COROUTINE_PARAM,
+      "Coroutine parameter error ({0})"},
+
+    { ER_PARSER_DOTERMINATE_ANSWERS,
+      "\nUNEXPECTED: Parser doTerminate answers {0}"},
+
+    { ER_NO_PARSE_CALL_WHILE_PARSING,
+      "parse may not be called while parsing"},
+
+    { ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED,
+      "Error: typed iterator for axis  {0} not implemented"},
+
+    { ER_ITERATOR_AXIS_NOT_IMPLEMENTED,
+      "Error: iterator for axis {0} not implemented "},
+
+    { ER_ITERATOR_CLONE_NOT_SUPPORTED,
+      "Iterator clone not supported"},
+
+    { ER_UNKNOWN_AXIS_TYPE,
+      "Unknown axis traversal type: {0}"},
+
+    { ER_AXIS_NOT_SUPPORTED,
+      "Axis traverser not supported: {0}"},
+
+    { ER_NO_DTMIDS_AVAIL,
+      "No more DTM IDs are available"},
+
+    { ER_NOT_SUPPORTED,
+      "Not supported: {0}"},
+    
+    { ER_NODE_NON_NULL,
+      "Node must be non-null for getDTMHandleFromNode"},
+
+    { ER_COULD_NOT_RESOLVE_NODE,
+      "Could not resolve the node to a handle"},
+
+    { ER_STARTPARSE_WHILE_PARSING,
+       "startParse may not be called while parsing"},
+
+    { ER_STARTPARSE_NEEDS_SAXPARSER,
+       "startParse needs a non-null SAXParser"},
+
+    { ER_COULD_NOT_INIT_PARSER,
+       "could not initialize parser with"},
+
+    { ER_EXCEPTION_CREATING_POOL,
+       "exception creating new instance for pool"},
+
+    { ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+       "Path contains invalid escape sequence"},
+
+    { ER_SCHEME_REQUIRED,
+       "Scheme is required!"},
+    
+    { ER_NO_SCHEME_IN_URI,
+       "No scheme found in URI: {0}"},
+
+    { ER_NO_SCHEME_INURI,
+       "No scheme found in URI"},
+
+    { ER_PATH_INVALID_CHAR,
+       "Path contains invalid character: {0}"},
+
+    { ER_SCHEME_FROM_NULL_STRING,
+       "Cannot set scheme from null string"},
+
+    { ER_SCHEME_NOT_CONFORMANT,
+       "The scheme is not conformant."},
+
+    { ER_HOST_ADDRESS_NOT_WELLFORMED,
+       "Host is not a well formed address"},
+
+    { ER_PORT_WHEN_HOST_NULL,
+       "Port cannot be set when host is null"},
+
+    { ER_INVALID_PORT,
+       "Invalid port number"},
+
+    { ER_FRAG_FOR_GENERIC_URI,
+       "Fragment can only be set for a generic URI"},
+
+    { ER_FRAG_WHEN_PATH_NULL,
+       "Fragment cannot be set when path is null"},
+
+    { ER_FRAG_INVALID_CHAR,
+       "Fragment contains invalid character"},
+
+    { ER_PARSER_IN_USE,
+      "Parser is already in use"},
+
+    { ER_CANNOT_CHANGE_WHILE_PARSING,
+      "Cannot change {0} {1} while parsing"},
+   
+    { ER_SELF_CAUSATION_NOT_PERMITTED,
+      "Self-causation not permitted"},
+
+    { ER_NO_USERINFO_IF_NO_HOST,
+      "Userinfo may not be specified if host is not specified"},
+
+    { ER_NO_PORT_IF_NO_HOST,
+      "Port may not be specified if host is not specified"},
+
+    { ER_NO_QUERY_STRING_IN_PATH, 
+      "Query string cannot be specified in path and query string"},
+
+    { ER_NO_FRAGMENT_STRING_IN_PATH,
+      "Fragment cannot be specified in both the path and fragment"},
+
+    { ER_CANNOT_INIT_URI_EMPTY_PARMS, 
+      "Cannot initialize URI with empty parameters"},
+
+    { ER_METHOD_NOT_SUPPORTED,
+      "Method not yet supported "},
+    
+    { ER_INCRSAXSRCFILTER_NOT_RESTARTABLE,
+      "IncrementalSAXSource_Filter not currently restartable"},
+
+    { ER_XMLRDR_NOT_BEFORE_STARTPARSE,
+      "XMLReader not before startParse request"},
+
+    { ER_AXIS_TRAVERSER_NOT_SUPPORTED,
+      "Axis traverser not supported: {0}"},
+
+    { ER_ERRORHANDLER_CREATED_WITH_NULL_PRINTWRITER,
+      "ListingErrorHandler created with null PrintWriter!"},
+
+    { ER_SYSTEMID_UNKNOWN,
+      "SystemId Unknown"},
+
+    { ER_LOCATION_UNKNOWN,
+      "Location of error unknown"},
+
+    { ER_PREFIX_MUST_RESOLVE,
+      "Prefix must resolve to a namespace: {0}"},
+
+    { ER_CREATEDOCUMENT_NOT_SUPPORTED,
+      "createDocument() not supported in XPathContext!"},
+
+    { ER_CHILD_HAS_NO_OWNER_DOCUMENT,
+      "Attribute child does not have an owner document!"},
+
+    { ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
+      "Attribute child does not have an owner document element!"},
+
+    { ER_CANT_OUTPUT_TEXT_BEFORE_DOC,
+      "Warning: can't output text before document element!  Ignoring..."},
+
+    { ER_CANT_HAVE_MORE_THAN_ONE_ROOT,
+      "Can't have more than one root on a DOM!"},
+
+    { ER_ARG_LOCALNAME_NULL,
+       "Argument 'localName' is null"},
+ 
+    // Note to translators:  A QNAME has the syntactic form [NCName:]NCName
+    // The localname is the portion after the optional colon; the message indicates
+    // that there is a problem with that part of the QNAME.
+    { ER_ARG_LOCALNAME_INVALID,
+       "Localname in QNAME should be a valid NCName"},
+
+    // Note to translators:  A QNAME has the syntactic form [NCName:]NCName
+    // The prefix is the portion before the optional colon; the message indicates
+    // that there is a problem with that part of the QNAME.
+    { ER_ARG_PREFIX_INVALID,
+       "Prefix in QNAME should be a valid NCName"},
+       
+    { ER_NAME_CANT_START_WITH_COLON,
+      "Name cannot start with a colon"},
+       
+    { "BAD_CODE", "Parameter to createMessage was out of bounds"},
+    { "FORMAT_FAILED", "Exception thrown during messageFormat call"},
+    { "line", "Line #"},
+    { "column","Column #"}
+  
+  
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/res/XMLMessages.java b/src/main/java/org/apache/xml/res/XMLMessages.java
new file mode 100644
index 0000000..9a2412e
--- /dev/null
+++ b/src/main/java/org/apache/xml/res/XMLMessages.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLMessages.java 468653 2006-10-28 07:07:05Z minchau $
+ */
+package org.apache.xml.res;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * A utility class for issuing XML error messages.
+ * @xsl.usage internal
+ */
+public class XMLMessages
+{
+
+  /** The local object to use.  */
+  protected Locale fLocale = Locale.getDefault();
+
+  /** The language specific resource object for XML messages.  */
+  private static ListResourceBundle XMLBundle = new XMLErrorResources(); // android-changed
+
+  /** String to use if a bad message code is used. */
+  protected static final String BAD_CODE = "BAD_CODE";
+
+  /** String to use if the message format operation failed.  */
+  protected static final String FORMAT_FAILED = "FORMAT_FAILED";
+    
+  /**
+   * Set the Locale object to use.
+   * 
+   * @param locale non-null reference to Locale object.
+   */
+   public void setLocale(Locale locale)
+  {
+    fLocale = locale;
+  }
+
+  /**
+   * Get the Locale object that is being used.
+   * 
+   * @return non-null reference to Locale object.
+   */
+  public Locale getLocale()
+  {
+    return fLocale;
+  }
+    
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param msgKey    The key for the message text.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted message string.
+   */
+  public static final String createXMLMessage(String msgKey, Object args[])
+  {
+      // BEGIN android-changed
+      //     don't localize exceptions
+      return createMsg(XMLBundle, msgKey, args);
+      // END android-changed
+  }
+
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param fResourceBundle The resource bundle to use.
+   * @param msgKey  The message key to use.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted message string.
+   */
+  public static final String createMsg(ListResourceBundle fResourceBundle,
+	String msgKey, Object args[])  //throws Exception
+  {
+
+    String fmsg = null;
+    boolean throwex = false;
+    String msg = null;
+
+    if (msgKey != null)
+      msg = fResourceBundle.getString(msgKey);
+
+    if (msg == null)
+    {
+      msg = fResourceBundle.getString(BAD_CODE);
+      throwex = true;
+    }
+
+    if (args != null)
+    {
+      try
+      {
+
+        // Do this to keep format from crying.
+        // This is better than making a bunch of conditional
+        // code all over the place.
+        int n = args.length;
+
+        for (int i = 0; i < n; i++)
+        {
+          if (null == args[i])
+            args[i] = "";
+        }
+
+        fmsg = java.text.MessageFormat.format(msg, args);
+      }
+      catch (Exception e)
+      {
+        fmsg = fResourceBundle.getString(FORMAT_FAILED);
+        fmsg += " " + msg;
+      }
+    }
+    else
+      fmsg = msg;
+
+    if (throwex)
+    {
+      throw new RuntimeException(fmsg);
+    }
+
+    return fmsg;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/AttributesImplSerializer.java b/src/main/java/org/apache/xml/serializer/AttributesImplSerializer.java
new file mode 100644
index 0000000..440d4c9
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/AttributesImplSerializer.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AttributesImplSerializer.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer;
+
+import java.util.Hashtable;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class extends org.xml.sax.helpers.AttributesImpl which implements org.
+ * xml.sax.Attributes. But for optimization this class adds a Hashtable for
+ * faster lookup of an index by qName, which is commonly done in the stream
+ * serializer.
+ * 
+ * @see org.xml.sax.Attributes
+ * 
+ * @xsl.usage internal
+ */
+public final class AttributesImplSerializer extends AttributesImpl
+{
+    /**
+     * Hash table of qName/index values to quickly lookup the index
+     * of an attributes qName.  qNames are in uppercase in the hash table
+     * to make the search case insensitive.
+     * 
+     * The keys to the hashtable to find the index are either
+     * "prefix:localName"  or "{uri}localName".
+     */
+    private final Hashtable m_indexFromQName = new Hashtable();
+    
+    private final StringBuffer m_buff = new StringBuffer();
+    
+    /**
+     * This is the number of attributes before switching to the hash table,
+     * and can be tuned, but 12 seems good for now - Brian M.
+     */
+    private static final int MAX = 12;
+    
+    /**
+     * One less than the number of attributes before switching to
+     * the Hashtable.
+     */
+    private static final int MAXMinus1 = MAX - 1;
+
+    /**
+     * This method gets the index of an attribute given its qName.
+     * @param qname the qualified name of the attribute, e.g. "prefix1:locName1"
+     * @return the integer index of the attribute.
+     * @see org.xml.sax.Attributes#getIndex(String)
+     */
+    public final int getIndex(String qname)
+    {
+        int index;
+
+        if (super.getLength() < MAX)
+        {
+            // if we haven't got too many attributes let the
+            // super class look it up
+            index = super.getIndex(qname);
+            return index;
+        }
+        // we have too many attributes and the super class is slow
+        // so find it quickly using our Hashtable.
+        Integer i = (Integer)m_indexFromQName.get(qname);
+        if (i == null)
+            index = -1;
+        else
+            index = i.intValue();
+        return index;
+    }
+    /**
+     * This method adds the attribute, but also records its qName/index pair in
+     * the hashtable for fast lookup by getIndex(qName).
+     * @param uri the URI of the attribute
+     * @param local the local name of the attribute
+     * @param qname the qualified name of the attribute
+     * @param type the type of the attribute
+     * @param val the value of the attribute
+     *
+     * @see org.xml.sax.helpers.AttributesImpl#addAttribute(String, String, String, String, String)
+     * @see #getIndex(String)
+     */
+    public final void addAttribute(
+        String uri,
+        String local,
+        String qname,
+        String type,
+        String val)
+    {
+        int index = super.getLength();
+        super.addAttribute(uri, local, qname, type, val);
+        // (index + 1) is now the number of attributes
+        // so either compare (index+1) to MAX, or compare index to (MAX-1)
+
+        if (index < MAXMinus1)
+        {
+            return;
+        }
+        else if (index == MAXMinus1)
+        {
+            switchOverToHash(MAX);
+        }
+        else
+        {
+            /* add the key with the format of "prefix:localName" */
+            /* we have just added the attibute, its index is the old length */
+            Integer i = new Integer(index);
+            m_indexFromQName.put(qname, i);
+            
+            /* now add with key of the format "{uri}localName" */
+            m_buff.setLength(0);
+            m_buff.append('{').append(uri).append('}').append(local);
+            String key = m_buff.toString();
+            m_indexFromQName.put(key, i);
+        }
+        return;
+    }
+
+    /**
+     * We are switching over to having a hash table for quick look
+     * up of attributes, but up until now we haven't kept any
+     * information in the Hashtable, so we now update the Hashtable.
+     * Future additional attributes will update the Hashtable as
+     * they are added.
+     * @param numAtts
+     */
+    private void switchOverToHash(int numAtts)
+    {
+        for (int index = 0; index < numAtts; index++)
+        {
+            String qName = super.getQName(index);
+            Integer i = new Integer(index);
+            m_indexFromQName.put(qName, i);
+            
+            // Add quick look-up to find with uri/local name pair
+            String uri = super.getURI(index);
+            String local = super.getLocalName(index);
+            m_buff.setLength(0);
+            m_buff.append('{').append(uri).append('}').append(local);
+            String key = m_buff.toString();
+            m_indexFromQName.put(key, i);
+        }
+    }
+
+    /**
+     * This method clears the accumulated attributes.
+     *
+     * @see org.xml.sax.helpers.AttributesImpl#clear()
+     */
+    public final void clear()
+    {
+
+        int len = super.getLength();
+        super.clear();
+        if (MAX <= len)
+        {
+            // if we have had enough attributes and are
+            // using the Hashtable, then clear the Hashtable too.
+            m_indexFromQName.clear();
+        }
+
+    }
+
+    /**
+     * This method sets the attributes, previous attributes are cleared,
+     * it also keeps the hashtable up to date for quick lookup via
+     * getIndex(qName).
+     * @param atts the attributes to copy into these attributes.
+     * @see org.xml.sax.helpers.AttributesImpl#setAttributes(Attributes)
+     * @see #getIndex(String)
+     */
+    public final void setAttributes(Attributes atts)
+    {
+
+        super.setAttributes(atts);
+
+        // we've let the super class add the attributes, but
+        // we need to keep the hash table up to date ourselves for the
+        // potentially new qName/index pairs for quick lookup. 
+        int numAtts = atts.getLength();
+        if (MAX <= numAtts)
+            switchOverToHash(numAtts);
+
+    }
+    
+    /**
+     * This method gets the index of an attribute given its uri and locanName.
+     * @param uri the URI of the attribute name.
+     * @param localName the local namer (after the ':' ) of the attribute name.
+     * @return the integer index of the attribute.
+     * @see org.xml.sax.Attributes#getIndex(String)
+     */
+    public final int getIndex(String uri, String localName)
+    {
+        int index;
+
+        if (super.getLength() < MAX)
+        {
+            // if we haven't got too many attributes let the
+            // super class look it up
+            index = super.getIndex(uri,localName);
+            return index;
+        }
+        // we have too many attributes and the super class is slow
+        // so find it quickly using our Hashtable.
+        // Form the key of format "{uri}localName"
+        m_buff.setLength(0);
+        m_buff.append('{').append(uri).append('}').append(localName);
+        String key = m_buff.toString();
+        Integer i = (Integer)m_indexFromQName.get(key);
+        if (i == null)
+            index = -1;
+        else
+            index = i.intValue();
+        return index;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/CharInfo.java b/src/main/java/org/apache/xml/serializer/CharInfo.java
new file mode 100644
index 0000000..ef5e449
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/CharInfo.java
@@ -0,0 +1,807 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: CharInfo.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.SystemIDResolver;
+import org.apache.xml.serializer.utils.Utils;
+import org.apache.xml.serializer.utils.WrappedRuntimeException;
+
+/**
+ * This class provides services that tell if a character should have
+ * special treatement, such as entity reference substitution or normalization
+ * of a newline character.  It also provides character to entity reference
+ * lookup.
+ *
+ * DEVELOPERS: See Known Issue in the constructor.
+ * 
+ * @xsl.usage internal
+ */
+final class CharInfo
+{
+    /** Given a character, lookup a String to output (e.g. a decorated entity reference). */
+    private HashMap m_charToString;
+
+    /**
+     * The name of the HTML entities file.
+     * If specified, the file will be resource loaded with the default class loader.
+     */
+    public static final String HTML_ENTITIES_RESOURCE = 
+                SerializerBase.PKG_NAME+".HTMLEntities";
+
+    /**
+     * The name of the XML entities file.
+     * If specified, the file will be resource loaded with the default class loader.
+     */
+    public static final String XML_ENTITIES_RESOURCE = 
+                SerializerBase.PKG_NAME+".XMLEntities";
+
+    /** The horizontal tab character, which the parser should always normalize. */
+    static final char S_HORIZONAL_TAB = 0x09;
+
+    /** The linefeed character, which the parser should always normalize. */
+    static final char S_LINEFEED = 0x0A;
+
+    /** The carriage return character, which the parser should always normalize. */
+    static final char S_CARRIAGERETURN = 0x0D;
+    static final char S_SPACE = 0x20;
+    static final char S_QUOTE = 0x22;
+    static final char S_LT = 0x3C;
+    static final char S_GT = 0x3E;
+    static final char S_NEL = 0x85;    
+    static final char S_LINE_SEPARATOR = 0x2028;
+    
+    /** This flag is an optimization for HTML entities. It false if entities 
+     * other than quot (34), amp (38), lt (60) and gt (62) are defined
+     * in the range 0 to 127.
+     * @xsl.usage internal
+     */    
+    boolean onlyQuotAmpLtGt;
+    
+    /** Copy the first 0,1 ... ASCII_MAX values into an array */
+    static final int ASCII_MAX = 128;
+    
+    /** Array of values is faster access than a set of bits 
+     * to quickly check ASCII characters in attribute values,
+     * the value is true if the character in an attribute value
+     * should be mapped to a String. 
+     */
+    private final boolean[] shouldMapAttrChar_ASCII;
+    
+    /** Array of values is faster access than a set of bits 
+     * to quickly check ASCII characters in text nodes, 
+     * the value is true if the character in a text node
+     * should be mapped to a String. 
+     */
+    private final boolean[] shouldMapTextChar_ASCII;
+
+    /** An array of bits to record if the character is in the set.
+     * Although information in this array is complete, the
+     * isSpecialAttrASCII array is used first because access to its values
+     * is common and faster.
+     */   
+    private final int array_of_bits[];
+     
+    
+    // 5 for 32 bit words,  6 for 64 bit words ...
+    /*
+     * This constant is used to shift an integer to quickly
+     * calculate which element its bit is stored in.
+     * 5 for 32 bit words (int) ,  6 for 64 bit words (long)
+     */
+    private static final int SHIFT_PER_WORD = 5;
+    
+    /*
+     * A mask to get the low order bits which are used to
+     * calculate the value of the bit within a given word,
+     * that will represent the presence of the integer in the 
+     * set.
+     * 
+     * 0x1F for 32 bit words (int),
+     * or 0x3F for 64 bit words (long) 
+     */
+    private static final int LOW_ORDER_BITMASK = 0x1f;
+    
+    /*
+     * This is used for optimizing the lookup of bits representing
+     * the integers in the set. It is the index of the first element
+     * in the array array_of_bits[] that is not used.
+     */
+    private int firstWordNotUsed;
+
+
+    /**
+     * A base constructor just to explicitly create the fields,
+     * with the exception of m_charToString which is handled
+     * by the constructor that delegates base construction to this one.
+     * <p>
+     * m_charToString is not created here only for performance reasons,
+     * to avoid creating a Hashtable that will be replaced when
+     * making a mutable copy, {@link #mutableCopyOf(CharInfo)}. 
+     *
+     */
+    private CharInfo() 
+    {
+    	this.array_of_bits = createEmptySetOfIntegers(65535);
+    	this.firstWordNotUsed = 0;
+    	this.shouldMapAttrChar_ASCII = new boolean[ASCII_MAX];
+    	this.shouldMapTextChar_ASCII = new boolean[ASCII_MAX];
+    	this.m_charKey = new CharKey();
+    	
+    	// Not set here, but in a constructor that uses this one
+    	// this.m_charToString =  new Hashtable();  
+    	
+    	this.onlyQuotAmpLtGt = true;
+    	
+
+    	return;
+    }
+    
+    private CharInfo(String entitiesResource, String method, boolean internal)
+    {
+    	// call the default constructor to create the fields
+    	this();
+    	m_charToString = new HashMap();
+
+        ResourceBundle entities = null;
+        boolean noExtraEntities = true;
+
+        // Make various attempts to interpret the parameter as a properties
+        // file or resource file, as follows:
+        //
+        //   1) attempt to load .properties file using ResourceBundle
+        //   2) try using the class loader to find the specified file a resource
+        //      file
+        //   3) try treating the resource a URI
+
+        if (internal) { 
+            try {
+                // Load entity property files by using PropertyResourceBundle,
+                // cause of security issure for applets
+                entities = PropertyResourceBundle.getBundle(entitiesResource);
+            } catch (Exception e) {}
+        }
+
+        if (entities != null) {
+            Enumeration keys = entities.getKeys();
+            while (keys.hasMoreElements()){
+                String name = (String) keys.nextElement();
+                String value = entities.getString(name);
+                int code = Integer.parseInt(value);
+                boolean extra = defineEntity(name, (char) code);
+                if (extra)
+                    noExtraEntities = false;
+            }
+        } else {
+            InputStream is = null;
+
+            // Load user specified resource file by using URL loading, it
+            // requires a valid URI as parameter
+            try {
+                if (internal) {
+                    is = CharInfo.class.getResourceAsStream(entitiesResource);
+                } else {
+                    ClassLoader cl = ObjectFactory.findClassLoader();
+                    if (cl == null) {
+                        is = ClassLoader.getSystemResourceAsStream(entitiesResource);
+                    } else {
+                        is = cl.getResourceAsStream(entitiesResource);
+                    }
+
+                    if (is == null) {
+                        try {
+                            URL url = new URL(entitiesResource);
+                            is = url.openStream();
+                        } catch (Exception e) {}
+                    }
+                }
+
+                if (is == null) {
+                    throw new RuntimeException(
+                        Utils.messages.createMessage(
+                            MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                            new Object[] {entitiesResource, entitiesResource}));
+                }
+
+                // Fix Bugzilla#4000: force reading in UTF-8
+                //  This creates the de facto standard that Xalan's resource 
+                //  files must be encoded in UTF-8. This should work in all
+                // JVMs.
+                //
+                // %REVIEW% KNOWN ISSUE: IT FAILS IN MICROSOFT VJ++, which
+                // didn't implement the UTF-8 encoding. Theoretically, we should
+                // simply let it fail in that case, since the JVM is obviously
+                // broken if it doesn't support such a basic standard.  But
+                // since there are still some users attempting to use VJ++ for
+                // development, we have dropped in a fallback which makes a
+                // second attempt using the platform's default encoding. In VJ++
+                // this is apparently ASCII, which is subset of UTF-8... and
+                // since the strings we'll be reading here are also primarily
+                // limited to the 7-bit ASCII range (at least, in English
+                // versions of Xalan), this should work well enough to keep us
+                // on the air until we're ready to officially decommit from
+                // VJ++.
+
+                BufferedReader reader;
+                try {
+                    reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    reader = new BufferedReader(new InputStreamReader(is));
+                }
+
+                String line = reader.readLine();
+
+                while (line != null) {
+                    if (line.length() == 0 || line.charAt(0) == '#') {
+                        line = reader.readLine();
+
+                        continue;
+                    }
+
+                    int index = line.indexOf(' ');
+
+                    if (index > 1) {
+                        String name = line.substring(0, index);
+
+                        ++index;
+
+                        if (index < line.length()) {
+                            String value = line.substring(index);
+                            index = value.indexOf(' ');
+
+                            if (index > 0) {
+                                value = value.substring(0, index);
+                            }
+
+                            int code = Integer.parseInt(value);
+
+                            boolean extra = defineEntity(name, (char) code);
+                            if (extra)
+                                noExtraEntities = false;
+                        }
+                    }
+
+                    line = reader.readLine();
+                }
+
+                is.close();
+            } catch (Exception e) {
+                throw new RuntimeException(
+                    Utils.messages.createMessage(
+                        MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                        new Object[] { entitiesResource,
+                                       e.toString(),
+                                       entitiesResource,
+                                       e.toString()}));
+            } finally {
+                if (is != null) {
+                    try {
+                        is.close();
+                    } catch (Exception except) {}
+                }
+            }
+        }
+
+        onlyQuotAmpLtGt = noExtraEntities;
+            
+        /* Now that we've used get(ch) just above to initialize the
+         * two arrays we will change by adding a tab to the set of 
+         * special chars for XML (but not HTML!).
+         * We do this because a tab is always a
+         * special character in an XML attribute, 
+         * but only a special character in XML text 
+         * if it has an entity defined for it.
+         * This is the reason for this delay.
+         */
+        if (Method.XML.equals(method)) 
+        {       
+            // We choose not to escape the quotation mark as &quot; in text nodes
+            shouldMapTextChar_ASCII[S_QUOTE] = false;
+        }
+        
+        if (Method.HTML.equals(method)) {
+        	// The XSLT 1.0 recommendation says 
+        	// "The html output method should not escape < characters occurring in attribute values."
+        	// So we don't escape '<' in an attribute for HTML
+        	shouldMapAttrChar_ASCII['<'] = false;    
+        	
+        	// We choose not to escape the quotation mark as &quot; in text nodes.
+            shouldMapTextChar_ASCII[S_QUOTE] = false;
+        }
+    }
+
+    /**
+     * Defines a new character reference. The reference's name and value are
+     * supplied. Nothing happens if the character reference is already defined.
+     * <p>Unlike internal entities, character references are a string to single
+     * character mapping. They are used to map non-ASCII characters both on
+     * parsing and printing, primarily for HTML documents. '&amp;lt;' is an
+     * example of a character reference.</p>
+     *
+     * @param name The entity's name
+     * @param value The entity's value
+     * @return true if the mapping is not one of:
+     * <ul>
+     * <li> '<' to "&lt;"
+     * <li> '>' to "&gt;"
+     * <li> '&' to "&amp;"
+     * <li> '"' to "&quot;"
+     * </ul>
+     */
+    private boolean defineEntity(String name, char value)
+    {
+        StringBuffer sb = new StringBuffer("&");
+        sb.append(name);
+        sb.append(';');
+        String entityString = sb.toString();
+        
+        boolean extra = defineChar2StringMapping(entityString, value);
+        return extra;
+    }
+
+    /**
+     * A utility object, just used to map characters to output Strings,
+     * needed because a HashMap needs to map an object as a key, not a 
+     * Java primitive type, like a char, so this object gets around that
+     * and it is reusable.
+     */
+    private final CharKey m_charKey;
+
+    /**
+     * Map a character to a String. For example given
+     * the character '>' this method would return the fully decorated
+     * entity name "&lt;".
+     * Strings for entity references are loaded from a properties file,
+     * but additional mappings defined through calls to defineChar2String()
+     * are possible. Such entity reference mappings could be over-ridden.
+     *
+     * This is reusing a stored key object, in an effort to avoid
+     * heap activity. Unfortunately, that introduces a threading risk.
+     * Simplest fix for now is to make it a synchronized method, or to give
+     * up the reuse; I see very little performance difference between them.
+     * Long-term solution would be to replace the hashtable with a sparse array
+     * keyed directly from the character's integer value; see DTM's
+     * string pool for a related solution.
+     *
+     * @param value The character that should be resolved to
+     * a String, e.g. resolve '>' to  "&lt;".
+     *
+     * @return The String that the character is mapped to, or null if not found.
+     * @xsl.usage internal
+     */
+    String getOutputStringForChar(char value)
+    {
+        // CharKey m_charKey = new CharKey(); //Alternative to synchronized
+        m_charKey.setChar(value);
+        return (String) m_charToString.get(m_charKey);
+    }
+    
+    /**
+     * Tell if the character argument that is from
+     * an attribute value has a mapping to a String.
+     * 
+     * @param value the value of a character that is in an attribute value
+     * @return true if the character should have any special treatment, 
+     * such as when writing out entity references.
+     * @xsl.usage internal
+     */
+    final boolean shouldMapAttrChar(int value)
+    {
+        // for performance try the values in the boolean array first,
+        // this is faster access than the BitSet for common ASCII values
+
+        if (value < ASCII_MAX)
+            return shouldMapAttrChar_ASCII[value];
+
+        // rather than java.util.BitSet, our private
+        // implementation is faster (and less general).
+        return get(value);
+    }    
+
+    /**
+     * Tell if the character argument that is from a 
+     * text node has a mapping to a String, for example
+     * to map '<' to "&lt;".
+     * 
+     * @param value the value of a character that is in a text node
+     * @return true if the character has a mapping to a String, 
+     * such as when writing out entity references.
+     * @xsl.usage internal
+     */
+    final boolean shouldMapTextChar(int value)
+    {
+        // for performance try the values in the boolean array first,
+        // this is faster access than the BitSet for common ASCII values
+
+        if (value < ASCII_MAX)
+            return shouldMapTextChar_ASCII[value];
+
+        // rather than java.util.BitSet, our private
+        // implementation is faster (and less general).
+        return get(value);
+    }
+    
+
+     
+    private static CharInfo getCharInfoBasedOnPrivilege(
+        final String entitiesFileName, final String method, 
+        final boolean internal){
+            return (CharInfo) AccessController.doPrivileged(
+                new PrivilegedAction() {
+                        public Object run() {
+                            return new CharInfo(entitiesFileName, 
+                              method, internal);}
+            });            
+    }
+     
+    /**
+     * Factory that reads in a resource file that describes the mapping of
+     * characters to entity references.
+     *
+     * Resource files must be encoded in UTF-8 and have a format like:
+     * <pre>
+     * # First char # is a comment
+     * Entity numericValue
+     * quot 34
+     * amp 38
+     * </pre>
+     * (Note: Why don't we just switch to .properties files? Oct-01 -sc)
+     *
+     * @param entitiesResource Name of entities resource file that should
+     * be loaded, which describes that mapping of characters to entity references.
+     * @param method the output method type, which should be one of "xml", "html", "text"...
+     * 
+     * @xsl.usage internal
+     */
+    static CharInfo getCharInfo(String entitiesFileName, String method)
+    {
+        CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName);
+        if (charInfo != null) {
+        	return mutableCopyOf(charInfo);
+        }
+
+        // try to load it internally - cache
+        try {
+            charInfo = getCharInfoBasedOnPrivilege(entitiesFileName, 
+                                        method, true);
+            // Put the common copy of charInfo in the cache, but return
+            // a copy of it.
+            m_getCharInfoCache.put(entitiesFileName, charInfo);
+            return mutableCopyOf(charInfo);
+        } catch (Exception e) {}
+
+        // try to load it externally - do not cache
+        try {
+            return getCharInfoBasedOnPrivilege(entitiesFileName, 
+                                method, false);
+        } catch (Exception e) {}
+
+        String absoluteEntitiesFileName;
+
+        if (entitiesFileName.indexOf(':') < 0) {
+            absoluteEntitiesFileName =
+                SystemIDResolver.getAbsoluteURIFromRelative(entitiesFileName);
+        } else {
+            try {
+                absoluteEntitiesFileName =
+                    SystemIDResolver.getAbsoluteURI(entitiesFileName, null);
+            } catch (TransformerException te) {
+                throw new WrappedRuntimeException(te);
+            }
+        }
+
+        return getCharInfoBasedOnPrivilege(entitiesFileName, 
+                                method, false);
+    }
+
+    /**
+     * Create a mutable copy of the cached one.
+     * @param charInfo The cached one.
+     * @return
+     */
+    private static CharInfo mutableCopyOf(CharInfo charInfo) {
+    	CharInfo copy = new CharInfo();
+    	
+    	int max = charInfo.array_of_bits.length;
+    	System.arraycopy(charInfo.array_of_bits,0,copy.array_of_bits,0,max);
+    	
+    	copy.firstWordNotUsed = charInfo.firstWordNotUsed;
+    	
+    	max = charInfo.shouldMapAttrChar_ASCII.length;
+    	System.arraycopy(charInfo.shouldMapAttrChar_ASCII,0,copy.shouldMapAttrChar_ASCII,0,max);
+    	
+    	max = charInfo.shouldMapTextChar_ASCII.length;
+    	System.arraycopy(charInfo.shouldMapTextChar_ASCII,0,copy.shouldMapTextChar_ASCII,0,max);
+    	
+    	// utility field copy.m_charKey is already created in the default constructor 
+    	
+    	copy.m_charToString = (HashMap) charInfo.m_charToString.clone();
+    	
+    	copy.onlyQuotAmpLtGt = charInfo.onlyQuotAmpLtGt;
+    	    	
+		return copy;
+	}
+
+	/** 
+	 * Table of user-specified char infos.
+	 * The table maps entify file names (the name of the
+	 * property file without the .properties extension)
+	 * to CharInfo objects populated with entities defined in 
+	 * corresponding property file.  
+	 */
+    private static Hashtable m_getCharInfoCache = new Hashtable();
+
+    /**
+     * Returns the array element holding the bit value for the
+     * given integer
+     * @param i the integer that might be in the set of integers
+     * 
+     */
+    private static int arrayIndex(int i) {
+        return (i >> SHIFT_PER_WORD);
+    }
+
+    /**
+     * For a given integer in the set it returns the single bit
+     * value used within a given word that represents whether
+     * the integer is in the set or not.
+     */
+    private static int bit(int i) {
+        int ret = (1 << (i & LOW_ORDER_BITMASK));
+        return ret;
+    }
+
+    /**
+     * Creates a new empty set of integers (characters)
+     * @param max the maximum integer to be in the set.
+     */
+    private int[] createEmptySetOfIntegers(int max) {
+        firstWordNotUsed = 0; // an optimization 
+
+        int[] arr = new int[arrayIndex(max - 1) + 1];
+            return arr;
+ 
+    }
+
+    /**
+     * Adds the integer (character) to the set of integers.
+     * @param i the integer to add to the set, valid values are 
+     * 0, 1, 2 ... up to the maximum that was specified at
+     * the creation of the set.
+     */
+    private final void set(int i) {   
+        setASCIItextDirty(i);
+        setASCIIattrDirty(i); 
+             
+        int j = (i >> SHIFT_PER_WORD); // this word is used
+        int k = j + 1;       
+        
+        if(firstWordNotUsed < k) // for optimization purposes.
+            firstWordNotUsed = k;
+            
+        array_of_bits[j] |= (1 << (i & LOW_ORDER_BITMASK));
+    }
+
+
+    /**
+     * Return true if the integer (character)is in the set of integers.
+     * 
+     * This implementation uses an array of integers with 32 bits per
+     * integer.  If a bit is set to 1 the corresponding integer is 
+     * in the set of integers.
+     * 
+     * @param i an integer that is tested to see if it is the
+     * set of integers, or not.
+     */
+    private final boolean get(int i) {
+
+        boolean in_the_set = false;
+        int j = (i >> SHIFT_PER_WORD); // wordIndex(i)
+        // an optimization here, ... a quick test to see
+        // if this integer is beyond any of the words in use
+        if(j < firstWordNotUsed)
+            in_the_set = (array_of_bits[j] & 
+                          (1 << (i & LOW_ORDER_BITMASK))
+            ) != 0;  // 0L for 64 bit words
+        return in_the_set;
+    }
+    
+    /**
+     * This method returns true if there are some non-standard mappings to
+     * entities other than quot, amp, lt, gt, and its only purpose is for
+     * performance.
+     * @param charToMap The value of the character that is mapped to a String
+     * @param outputString The String to which the character is mapped, usually
+     * an entity reference such as "&lt;".
+     * @return true if the mapping is not one of:
+     * <ul>
+     * <li> '<' to "&lt;"
+     * <li> '>' to "&gt;"
+     * <li> '&' to "&amp;"
+     * <li> '"' to "&quot;"
+     * </ul>
+     */
+    private boolean extraEntity(String outputString, int charToMap)
+    {
+        boolean extra = false;
+        if (charToMap < ASCII_MAX)
+        {
+            switch (charToMap)
+            {
+                case '"' : // quot
+                	if (!outputString.equals("&quot;"))
+                		extra = true;  
+                	break;
+                case '&' : // amp
+                	if (!outputString.equals("&amp;"))
+                		extra = true;
+                	break;
+                case '<' : // lt
+                	if (!outputString.equals("&lt;"))
+                		extra = true;
+                	break;
+                case '>' : // gt
+                	if (!outputString.equals("&gt;"))
+                		extra = true;
+                    break;
+                default : // other entity in range 0 to 127  
+                    extra = true;
+            }
+        }
+        return extra;
+    }    
+    
+    /**
+     * If the character is in the ASCII range then
+     * mark it as needing replacement with
+     * a String on output if it occurs in a text node.
+     * @param ch
+     */
+    private void setASCIItextDirty(int j) 
+    {
+        if (0 <= j && j < ASCII_MAX) 
+        {
+            shouldMapTextChar_ASCII[j] = true;
+        } 
+    }
+    
+    /**
+     * If the character is in the ASCII range then
+     * mark it as needing replacement with
+     * a String on output if it occurs in a attribute value.
+     * @param ch
+     */
+    private void setASCIIattrDirty(int j) 
+    {
+        if (0 <= j && j < ASCII_MAX) 
+        {
+            shouldMapAttrChar_ASCII[j] = true;
+        } 
+    }
+
+    
+    /**
+     * Call this method to register a char to String mapping, for example
+     * to map '<' to "&lt;".
+     * @param outputString The String to map to.
+     * @param inputChar The char to map from.
+     * @return true if the mapping is not one of:
+     * <ul>
+     * <li> '<' to "&lt;"
+     * <li> '>' to "&gt;"
+     * <li> '&' to "&amp;"
+     * <li> '"' to "&quot;"
+     * </ul>
+     */
+    boolean defineChar2StringMapping(String outputString, char inputChar) 
+    {
+        CharKey character = new CharKey(inputChar);
+        m_charToString.put(character, outputString);
+        set(inputChar);  // mark the character has having a mapping to a String
+        
+        boolean extraMapping = extraEntity(outputString, inputChar);
+        return extraMapping;
+        	
+    }
+
+    /**
+     * Simple class for fast lookup of char values, when used with
+     * hashtables.  You can set the char, then use it as a key.
+     *  
+     * @xsl.usage internal
+     */
+    private static class CharKey extends Object
+    {
+
+      /** String value          */
+      private char m_char;
+
+      /**
+       * Constructor CharKey
+       *
+       * @param key char value of this object.
+       */
+      public CharKey(char key)
+      {
+        m_char = key;
+      }
+  
+      /**
+       * Default constructor for a CharKey.
+       *
+       * @param key char value of this object.
+       */
+      public CharKey()
+      {
+      }
+  
+      /**
+       * Get the hash value of the character.  
+       *
+       * @return hash value of the character.
+       */
+      public final void setChar(char c)
+      {
+        m_char = c;
+      }
+
+
+
+      /**
+       * Get the hash value of the character.  
+       *
+       * @return hash value of the character.
+       */
+      public final int hashCode()
+      {
+        return (int)m_char;
+      }
+
+      /**
+       * Override of equals() for this object 
+       *
+       * @param obj to compare to
+       *
+       * @return True if this object equals this string value 
+       */
+      public final boolean equals(Object obj)
+      {
+        return ((CharKey)obj).m_char == m_char;
+      }
+    }
+   
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/DOM3Serializer.java b/src/main/java/org/apache/xml/serializer/DOM3Serializer.java
new file mode 100644
index 0000000..df0e1fd
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/DOM3Serializer.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.LSSerializerFilter;
+
+/**
+ * This interface is not intended to be used
+ * by an end user, but rather by an XML parser that is implementing the DOM 
+ * Level 3 Load and Save APIs.
+ * <p>
+ * 
+ * See the DOM Level 3 Load and Save interface at <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSSerializer">LSSeializer</a>.
+ * 
+ * For a list of configuration parameters for DOM Level 3 see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration">DOMConfiguration</a>.
+ * For additional configuration parameters available with the DOM Level 3 Load and Save API LSSerializer see
+ * <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSSerializer-config">LSerializer config</a>.
+ * <p>
+ * The following example uses a DOM3Serializer indirectly, through an an XML
+ * parser that uses this class as part of its implementation of the DOM Level 3
+ * Load and Save APIs, and is the prefered way to serialize with DOM Level 3 APIs.
+ * <p>
+ * Example:
+ * <pre>
+ *    public class TestDOM3 {
+ *
+ *    public static void main(String args[]) throws Exception {
+ *        // Get document to serialize
+ *        TestDOM3 test = new TestDOM3();
+ *        
+ *        // Serialize using standard DOM Level 3 Load/Save APIs        
+ *        System.out.println(test.testDOM3LS());
+ *    }
+ *
+ *    public org.w3c.dom.Document getDocument() throws Exception {
+ *        // Create a simple DOM Document.
+ *        javax.xml.parsers.DocumentBuilderFactory factory = 
+ *            javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ *        javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
+ *        byte[] bytes = "<parent><child/></parent>".getBytes();
+ *        java.io.InputStream is = new java.io.ByteArrayInputStream(bytes);
+ *        org.w3c.dom.Document doc = builder.parse(is);
+ *        return doc;
+ *    }
+ *    
+ *    //
+ *    // This method uses standard DOM Level 3 Load Save APIs:
+ *    //   org.w3c.dom.bootstrap.DOMImplementationRegistry
+ *    //   org.w3c.dom.ls.DOMImplementationLS
+ *    //   org.w3c.dom.ls.DOMImplementationLS
+ *    //   org.w3c.dom.ls.LSSerializer
+ *    //   org.w3c.dom.DOMConfiguration
+ *    //   
+ *    // The only thing non-standard in this method is the value set for the
+ *    // name of the class implementing the DOM Level 3 Load Save APIs,
+ *    // which in this case is:
+ *    //   org.apache.xerces.dom.DOMImplementationSourceImpl
+ *    //
+ *
+ *    public String testDOM3LS() throws Exception {
+ *        
+ *        // Get a simple DOM Document that will be serialized.
+ *        org.w3c.dom.Document docToSerialize = getDocument();
+ *
+ *        // Get a factory (DOMImplementationLS) for creating a Load and Save object.
+ *        org.w3c.dom.ls.DOMImplementationLS impl = 
+ *            (org.w3c.dom.ls.DOMImplementationLS) 
+ *            org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance().getDOMImplementation("LS");
+ *
+ *        // Use the factory to create an object (LSSerializer) used to 
+ *        // write out or save the document.
+ *        org.w3c.dom.ls.LSSerializer writer = impl.createLSSerializer();
+ *        org.w3c.dom.DOMConfiguration config = writer.getDomConfig();
+ *        config.setParameter("format-pretty-print", Boolean.TRUE);
+ *        
+ *        // Use the LSSerializer to write out or serialize the document to a String.
+ *        String serializedXML = writer.writeToString(docToSerialize);
+ *        return serializedXML;
+ *    }
+ *    
+ *    }  // end of class TestDOM3
+ * </pre>
+ * 
+ * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration">DOMConfiguration</a>
+ * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSSerializer-config">LSSerializer</a>
+ * @see org.apache.xml.serializer.Serializer
+ * @see org.apache.xml.serializer.DOMSerializer
+ * 
+ * @xsl.usage advanced
+ *
+ */
+public interface DOM3Serializer {
+    /**
+     * Serializes the Level 3 DOM node. Throws an exception only if an I/O
+     * exception occured while serializing.
+     * 
+     * This interface is a public API.
+     *
+     * @param node the Level 3 DOM node to serialize
+     * @throws IOException if an I/O exception occured while serializing
+     */
+    public void serializeDOM3(Node node) throws IOException;
+
+    /**
+     * Sets a DOMErrorHandler on the DOM Level 3 Serializer.
+     * 
+     * This interface is a public API.
+     *
+     * @param handler the Level 3 DOMErrorHandler
+     */
+    public void setErrorHandler(DOMErrorHandler handler);
+
+    /**
+     * Returns a DOMErrorHandler set on the DOM Level 3 Serializer.
+     * 
+     * This interface is a public API.
+     *
+     * @return A Level 3 DOMErrorHandler
+     */
+    public DOMErrorHandler getErrorHandler();
+
+    /**
+     * Sets a LSSerializerFilter on the DOM Level 3 Serializer to filter nodes
+     * during serialization.
+     * 
+     * This interface is a public API.
+     *
+     * @param filter the Level 3 LSSerializerFilter
+     */
+    public void setNodeFilter(LSSerializerFilter filter);
+
+    /**
+     * Returns a LSSerializerFilter set on the DOM Level 3 Serializer to filter nodes
+     * during serialization.
+     * 
+     * This interface is a public API.
+     *
+     * @return The Level 3 LSSerializerFilter
+     */
+    public LSSerializerFilter getNodeFilter();
+
+    /**
+     * Sets the end-of-line sequence of characters to be used during serialization
+     * @param newLine The end-of-line sequence of characters to be used during serialization
+     */
+    public void setNewLine(char[] newLine);
+}
diff --git a/src/main/java/org/apache/xml/serializer/DOMSerializer.java b/src/main/java/org/apache/xml/serializer/DOMSerializer.java
new file mode 100644
index 0000000..86752b6
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/DOMSerializer.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOMSerializer.java 475350 2006-11-15 18:39:15Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+import org.w3c.dom.Node;
+
+/**
+ * Interface for a DOM serializer implementation.
+ * <p>
+ * The DOMSerializer is a facet of a serializer and is obtained from the
+ * asDOMSerializer() method of the ({@link Serializer}) interface. 
+ * A serializer may or may not support a DOM serializer, if it does not then the 
+ * return value from asDOMSerializer() is null.
+ * <p>
+ * Example:
+ * <pre>
+ * // Create a document to be serialized
+ * org.w3c.dom.Document doc = ...;
+ * 
+ * // Create a Serializer that will be used
+ * // to serialize the document  
+ * org.apache.xml.serializer.Serializer ser = ...;
+ *
+ * // Set the Writer to write output to, and 
+ * // serialize the DOM using that Serializer
+ * java.io.StringWriter sw = new java.io.StringWriter();
+ * ser.setWriter(sw);
+ * DOMSerialzier dser = ser.asDOMSerializer();
+ * dser.serialize(doc);
+ * 
+ * // Write out the serialized XML in the String.
+ * System.out.println(sw.toString());
+ * </pre>
+ * 
+ * @see OutputPropertiesFactory
+ * @see SerializerFactory
+ * @see Serializer
+ * 
+ * @xsl.usage general
+ *
+ */
+public interface DOMSerializer
+{
+    /**
+     * Serializes the DOM node. Throws an exception only if an I/O
+     * exception occured while serializing.
+     * 
+     * This interface is a public API.
+     *
+     * @param node the DOM node to serialize
+     * @throws IOException if an I/O exception occured while serializing
+     */
+    public void serialize(Node node) throws IOException;
+}
diff --git a/src/main/java/org/apache/xml/serializer/ElemContext.java b/src/main/java/org/apache/xml/serializer/ElemContext.java
new file mode 100644
index 0000000..0461645
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ElemContext.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemContext.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+/**
+ * This class is a stack frame that consists of 
+ * information about the element currently being processed 
+ * by a serializer. Consider this example:
+ * <pre>
+ *   <A>
+ *     <B1>
+ *     </B1>
+ *     <B2>
+ *     </B2>
+ *   <A>
+ * </pre> 
+ * 
+ * A stack frame will be pushed for "A" at depth 1, 
+ * then another one for "B1" at depth 2.
+ * Then "B1" stackframe is popped.  When the stack frame for "B2" is 
+ * pushed, this implementation re-uses the old stack fram object used
+ * by "B1" to be efficient at not creating too many of these object.
+ * 
+ * This is by no means a public class, and neither are its fields or methods,
+ * they are all helper fields for a serializer.
+ * 
+ * The purpose of this class is to be more consistent with pushing information
+ * when a new element is being serialized and more quickly restoring the old
+ * information about the parent element with a simple pop() when the
+ * child element is done.  Previously there was some redundant and error-prone
+ * calculations going on to retore information.
+ * 
+ * @xsl.usage internal
+ */
+final class ElemContext
+{
+    // Fields that form the context of the element
+
+    /**
+     * The nesting depth of the element inside other elements.
+     */
+    final int m_currentElemDepth;
+
+    /** HTML field, the element description of the HTML element */
+    ElemDesc m_elementDesc = null;
+
+    /**
+     * The local name of the element.
+     */
+    String m_elementLocalName = null;
+
+    /**
+     * The fully qualified name of the element (with prefix, if any).
+     */
+    String m_elementName = null;
+
+    /**
+     * The URI of the element.
+     * If this value is null it means that the URI is not yet determined
+     * for the element. Valid values are the empty string "", meaning
+     * that it is in no namespace, or a string of non-zero length.
+     */
+    String m_elementURI = null;
+
+    /** If the element is in the cdata-section-names list
+     * then the value is true. If it is true the text children of the element
+     * should be output in CDATA section blocks. 
+     */
+    boolean m_isCdataSection;
+
+    /** True if the current element has output escaping disabled.
+     * This is true for SCRIPT and STYLE elements. 
+     */
+    boolean m_isRaw = false;
+
+    /** The next element "stack frame". This value will only be
+     * set once as deeper stack frames are not deleted when popped off,
+     * but are rather re-used when a push is required.
+     * 
+     * This makes for very fast pushing and popping of stack frames 
+     * because very few stack frame objects are ever created, they are
+     * mostly re-used.  This re-use saves object creation but it also means
+     * that connections between the frames via m_next and m_prev
+     * never changes either. Just the contents of the frames change
+     * as they are re-used. Only the reference to the current stack frame, which
+     * is held by the serializer is changed via a quick pop() or push().
+     */
+    private ElemContext m_next;
+
+    /** The previous element "stack frame". */
+    final ElemContext m_prev;
+
+    /**
+     * Set to true when a start tag is started, or open, but not all the
+     * attributes or namespace information is yet collected.
+     */
+    boolean m_startTagOpen = false;
+
+    /**
+     * Constructor to create the root of the element contexts. 
+     *
+     */
+    ElemContext()
+    {
+        // this assignment means can never pop this context off
+        m_prev = this;
+        // depth 0 because it doesn't correspond to any element
+        m_currentElemDepth = 0;
+    }
+
+    /**
+     * Constructor to create the "stack frame" for a given element depth.
+     * 
+     * This implementation will re-use the context at each depth. If
+     * a documents deepest element depth is N then there will be (N+1)
+     * such objects created, no more than that.
+     * 
+     * @param previous The "stack frame" corresponding to the new
+     * elements parent element.
+     */
+    private ElemContext(final ElemContext previous)
+    {
+        m_prev = previous;
+        m_currentElemDepth = previous.m_currentElemDepth + 1;
+    }
+
+    /**
+     * Pop the current "stack frame".
+     * @return Returns the parent "stack frame" of the one popped.
+     */
+    final ElemContext pop()
+    {
+        /* a very simple pop.  No clean up is done of the deeper
+         * stack frame.  All deeper stack frames are still attached
+         * but dormant, just waiting to be re-used.
+         */
+        return this.m_prev;
+    }
+
+    /**
+     * This method pushes an element "stack frame" 
+     * but with no initialization of values in that frame.
+     * This method is used for optimization purposes, like when pushing
+     * a stack frame for an HTML "IMG" tag which has no children and
+     * the stack frame will almost immediately be popped.
+     */
+    final ElemContext push()
+    {
+        ElemContext frame = this.m_next;
+        if (frame == null)
+        {
+            /* We have never been at this depth yet, and there is no
+             * stack frame to re-use, so we now make a new one.
+             */
+            frame = new ElemContext(this);
+            this.m_next = frame;
+        }
+        /*
+         * We shouldn't need to set this true because we should just
+         * be pushing a dummy stack frame that will be instantly popped.
+         * Yet we need to be ready in case this element does have
+         * unexpected children.
+         */
+        frame.m_startTagOpen = true;
+        return frame;
+    }
+    
+    /**
+     * Push an element context on the stack. This context keeps track of
+     * information gathered about the element.
+     * @param uri The URI for the namespace for the element name, 
+     * can be null if it is not yet known.
+     * @param localName The local name of the element (no prefix),  
+     * can be null.
+     * @param qName The qualified name (with prefix, if any) 
+     * of the element, this parameter is required.
+     */
+    final ElemContext push(
+        final String uri,
+        final String localName,
+        final String qName)
+    {
+        ElemContext frame = this.m_next;
+        if (frame == null)
+        {
+            /* We have never been at this depth yet, and there is no
+             * stack frame to re-use, so we now make a new one.
+             */
+            frame = new ElemContext(this);
+            this.m_next = frame;
+        }
+
+        // Initialize, or reset values in the new or re-used stack frame.
+        frame.m_elementName = qName;
+        frame.m_elementLocalName = localName;
+        frame.m_elementURI = uri;
+        frame.m_isCdataSection = false;
+        frame.m_startTagOpen = true;
+
+        // is_Raw is already set in the HTML startElement() method
+        // frame.m_isRaw = false; 
+        return frame;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ElemDesc.java b/src/main/java/org/apache/xml/serializer/ElemDesc.java
new file mode 100644
index 0000000..f551210
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ElemDesc.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ElemDesc.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import org.apache.xml.serializer.utils.StringToIntTable;
+
+/**
+ * This class has a series of flags (bit values) that describe an HTML element
+ * <p>
+ * This class is not a public API.
+ * It is public because it is used outside of this package.
+ * 
+ * @xsl.usage internal
+ */
+public final class ElemDesc
+{
+    /** Bit flags to tell about this element type. */
+    private int m_flags;
+
+    /**
+     * Table of attribute names to integers, which contain bit flags telling about
+     *  the attributes.
+     */
+    private StringToIntTable m_attrs = null;
+
+    /** Bit position if this element type is empty. */
+    static final int EMPTY = (1 << 1);
+
+    /** Bit position if this element type is a flow. */
+    private static final int FLOW = (1 << 2);
+
+    /** Bit position if this element type is a block. */
+    static final int BLOCK = (1 << 3);
+
+    /** Bit position if this element type is a block form. */
+    static final int BLOCKFORM = (1 << 4);
+
+    /** Bit position if this element type is a block form field set. */
+    static final int BLOCKFORMFIELDSET = (1 << 5);
+
+    /** Bit position if this element type is CDATA. */
+    private static final int CDATA = (1 << 6);
+
+    /** Bit position if this element type is PCDATA. */
+    private static final int PCDATA = (1 << 7);
+
+    /** Bit position if this element type is should be raw characters. */
+    static final int RAW = (1 << 8);
+
+    /** Bit position if this element type should be inlined. */
+    private static final int INLINE = (1 << 9);
+
+    /** Bit position if this element type is INLINEA. */
+    private static final int INLINEA = (1 << 10);
+
+    /** Bit position if this element type is an inline label. */
+    static final int INLINELABEL = (1 << 11);
+
+    /** Bit position if this element type is a font style. */
+    static final int FONTSTYLE = (1 << 12);
+
+    /** Bit position if this element type is a phrase. */
+    static final int PHRASE = (1 << 13);
+
+    /** Bit position if this element type is a form control. */
+    static final int FORMCTRL = (1 << 14);
+
+    /** Bit position if this element type is ???. */
+    static final int SPECIAL = (1 << 15);
+
+    /** Bit position if this element type is ???. */
+    static final int ASPECIAL = (1 << 16);
+
+    /** Bit position if this element type is an odd header element. */
+    static final int HEADMISC = (1 << 17);
+
+    /** Bit position if this element type is a head element (i.e. H1, H2, etc.) */
+    static final int HEAD = (1 << 18);
+
+    /** Bit position if this element type is a list. */
+    static final int LIST = (1 << 19);
+
+    /** Bit position if this element type is a preformatted type. */
+    static final int PREFORMATTED = (1 << 20);
+
+    /** Bit position if this element type is whitespace sensitive. */
+    static final int WHITESPACESENSITIVE = (1 << 21);
+
+    /** Bit position if this element type is a header element (i.e. HEAD). */
+    static final int HEADELEM = (1 << 22);
+    
+    /** Bit position if this element is the "HTML" element */
+    static final int HTMLELEM = (1 << 23);
+
+    /** Bit position if this attribute type is a URL. */
+    public static final int ATTRURL = (1 << 1);
+
+    /** Bit position if this attribute type is an empty type. */
+    public static final int ATTREMPTY = (1 << 2);
+
+    /**
+     * Construct an ElemDesc from a set of bit flags.
+     *
+     *
+     * @param flags Bit flags that describe the basic properties of this element type.
+     */
+    ElemDesc(int flags)
+    {
+        m_flags = flags;
+    }
+
+    /**
+     * Tell if this element type has the basic bit properties that are passed
+     * as an argument.
+     *
+     * @param flags Bit flags that describe the basic properties of interest.
+     *
+     * @return true if any of the flag bits are true.
+     */
+    private boolean is(int flags)
+    {
+
+        // int which = (m_flags & flags);
+        return (m_flags & flags) != 0;
+    }
+
+    int getFlags() {
+        return m_flags;
+    }
+
+    /**
+     * Set an attribute name and it's bit properties.
+     *
+     *
+     * @param name non-null name of attribute, in upper case.
+     * @param flags flag bits.
+     */
+    void setAttr(String name, int flags)
+    {
+
+        if (null == m_attrs)
+            m_attrs = new StringToIntTable();
+
+        m_attrs.put(name, flags);
+    }
+
+    /**
+     * Tell if any of the bits of interest are set for a named attribute type.
+     *
+     * @param name non-null reference to attribute name, in any case.
+     * @param flags flag mask.
+     *
+     * @return true if any of the flags are set for the named attribute.
+     */
+    public boolean isAttrFlagSet(String name, int flags)
+    {
+        return (null != m_attrs)
+            ? ((m_attrs.getIgnoreCase(name) & flags) != 0)
+            : false;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/EncodingInfo.java b/src/main/java/org/apache/xml/serializer/EncodingInfo.java
new file mode 100644
index 0000000..60465d4
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/EncodingInfo.java
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: EncodingInfo.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+
+/**
+ * Holds information about a given encoding, which is the Java name for the
+ * encoding, the equivalent ISO name.
+ * <p>
+ * An object of this type has two useful methods
+ * <pre>
+ * isInEncoding(char ch);
+ * </pre>
+ * which can be called if the character is not the high one in
+ * a surrogate pair and:
+ * <pre>
+ * isInEncoding(char high, char low);
+ * </pre>
+ * which can be called if the two characters from a high/low surrogate pair.
+ * <p>
+ * An EncodingInfo object is a node in a binary search tree. Such a node
+ * will answer if a character is in the encoding, and do so for a given
+ * range of unicode values (<code>m_first</code> to
+ * <code>m_last</code>). It will handle a certain range of values
+ * explicitly (<code>m_explFirst</code> to <code>m_explLast</code>).
+ * If the unicode point is before that explicit range, that is it
+ * is in the range <code>m_first <= value < m_explFirst</code>, then it will delegate to another EncodingInfo object for The root
+ * of such a tree, m_before.  Likewise for values in the range 
+ * <code>m_explLast < value <= m_last</code>, but delgating to <code>m_after</code>
+ * <p>
+ * Actually figuring out if a code point is in the encoding is expensive. So the
+ * purpose of this tree is to cache such determinations, and not to build the
+ * entire tree of information at the start, but only build up as much of the 
+ * tree as is used during the transformation.
+ * <p>
+ * This Class is not a public API, and should only be used internally within
+ * the serializer.
+ * <p>
+ * This class is not a public API.
+ * @xsl.usage internal
+ */
+public final class EncodingInfo extends Object
+{
+
+    /**
+     * Not all characters in an encoding are in on contiguous group,
+     * however there is a lowest contiguous group starting at '\u0001'
+     * and working up to m_highCharInContiguousGroup.
+     * <p>
+     * This is the char for which chars at or below this value are 
+     * definately in the encoding, although for chars
+     * above this point they might be in the encoding.
+     * This exists for performance, especially for ASCII characters
+     * because for ASCII all chars in the range '\u0001' to '\u007F' 
+     * are in the encoding.
+     * 
+     */
+    private final char m_highCharInContiguousGroup;
+
+    /**
+     * The ISO encoding name.
+     */
+    final String name;
+
+    /**
+     * The name used by the Java convertor.
+     */
+    final String javaName;
+    
+    /**
+     * A helper object that we can ask if a
+     * single char, or a surrogate UTF-16 pair
+     * of chars that form a single character,
+     * is in this encoding.
+     */
+    private InEncoding m_encoding;
+    
+    /**
+     * This is not a public API. It returns true if the
+     * char in question is in the encoding.
+     * @param ch the char in question.
+     * <p>
+     * This method is not a public API.
+     * @xsl.usage internal
+     */
+    public boolean isInEncoding(char ch) {
+        if (m_encoding == null) {
+            m_encoding = new EncodingImpl();
+            
+            // One could put alternate logic in here to
+            // instantiate another object that implements the
+            // InEncoding interface. For example if the JRE is 1.4 or up
+            // we could have an object that uses JRE 1.4 methods
+        }
+        return m_encoding.isInEncoding(ch); 
+    }
+    
+    /**
+     * This is not a public API. It returns true if the
+     * character formed by the high/low pair is in the encoding.
+     * @param high a char that the a high char of a high/low surrogate pair.
+     * @param low a char that is the low char of a high/low surrogate pair.
+     * <p>
+     * This method is not a public API.
+     * @xsl.usage internal
+     */
+    public boolean isInEncoding(char high, char low) {
+        if (m_encoding == null) {
+            m_encoding = new EncodingImpl();
+            
+            // One could put alternate logic in here to
+            // instantiate another object that implements the
+            // InEncoding interface. For example if the JRE is 1.4 or up
+            // we could have an object that uses JRE 1.4 methods
+        }
+        return m_encoding.isInEncoding(high, low); 
+    }
+
+    /**
+     * Create an EncodingInfo object based on the ISO name and Java name.
+     * If both parameters are null any character will be considered to
+     * be in the encoding. This is useful for when the serializer is in
+     * temporary output state, and has no assciated encoding.
+     *
+     * @param name reference to the ISO name.
+     * @param javaName reference to the Java encoding name.
+     * @param highChar The char for which characters at or below this value are 
+     * definately in the
+     * encoding, although for characters above this point they might be in the encoding.
+     */
+    public EncodingInfo(String name, String javaName, char highChar)
+    {
+
+        this.name = name;
+        this.javaName = javaName;
+        this.m_highCharInContiguousGroup = highChar;
+    }
+    
+    
+    
+    /**
+     * A simple interface to isolate the implementation.
+     * We could also use some new JRE 1.4 methods in another implementation
+     * provided we use reflection with them.
+     * <p>
+     * This interface is not a public API,
+     * and should only be used internally within the serializer. 
+     * @xsl.usage internal
+     */
+    private interface InEncoding {
+        /**
+         * Returns true if the char is in the encoding
+         */
+        public boolean isInEncoding(char ch);
+        /**
+         * Returns true if the high/low surrogate pair forms
+         * a character that is in the encoding.
+         */
+        public boolean isInEncoding(char high, char low);
+    }
+
+    /**
+     * This class implements the 
+     */
+    private class EncodingImpl implements InEncoding {
+        
+
+
+        public boolean isInEncoding(char ch1) {
+            final boolean ret;
+            int codePoint = Encodings.toCodePoint(ch1);
+            if (codePoint < m_explFirst) {
+                // The unicode value is before the range
+                // that we explictly manage, so we delegate the answer.
+                
+                // If we don't have an m_before object to delegate to, make one.
+                if (m_before == null)
+                    m_before =
+                        new EncodingImpl(
+                            m_encoding,
+                            m_first,
+                            m_explFirst - 1,
+                            codePoint);
+                ret = m_before.isInEncoding(ch1);
+            } else if (m_explLast < codePoint) {
+                // The unicode value is after the range
+                // that we explictly manage, so we delegate the answer.
+                
+                // If we don't have an m_after object to delegate to, make one.
+                if (m_after == null)
+                    m_after =
+                        new EncodingImpl(
+                            m_encoding,
+                            m_explLast + 1,
+                            m_last,
+                            codePoint);
+                ret = m_after.isInEncoding(ch1);
+            } else {
+                // The unicode value is in the range we explitly handle
+                final int idx = codePoint - m_explFirst;
+                
+                // If we already know the answer, just return it.
+                if (m_alreadyKnown[idx])
+                    ret = m_isInEncoding[idx];
+                else {
+                    // We don't know the answer, so find out,
+                    // which may be expensive, then cache the answer 
+                    ret = inEncoding(ch1, m_encoding);
+                    m_alreadyKnown[idx] = true;
+                    m_isInEncoding[idx] = ret;
+                }
+            }
+            return ret;
+        }
+
+        public boolean isInEncoding(char high, char low) {
+            final boolean ret;
+            int codePoint = Encodings.toCodePoint(high,low);
+            if (codePoint < m_explFirst) {
+                // The unicode value is before the range
+                // that we explictly manage, so we delegate the answer.
+                
+                // If we don't have an m_before object to delegate to, make one.
+                if (m_before == null)
+                    m_before =
+                        new EncodingImpl(
+                            m_encoding,
+                            m_first,
+                            m_explFirst - 1,
+                            codePoint);
+                ret = m_before.isInEncoding(high,low);
+            } else if (m_explLast < codePoint) {
+                // The unicode value is after the range
+                // that we explictly manage, so we delegate the answer.
+                
+                // If we don't have an m_after object to delegate to, make one.
+                if (m_after == null)
+                    m_after =
+                        new EncodingImpl(
+                            m_encoding,
+                            m_explLast + 1,
+                            m_last,
+                            codePoint);
+                ret = m_after.isInEncoding(high,low);
+            } else {
+                // The unicode value is in the range we explitly handle
+                final int idx = codePoint - m_explFirst;
+                
+                // If we already know the answer, just return it.
+                if (m_alreadyKnown[idx])
+                    ret = m_isInEncoding[idx];
+                else {
+                    // We don't know the answer, so find out,
+                    // which may be expensive, then cache the answer 
+                    ret = inEncoding(high, low, m_encoding);
+                    m_alreadyKnown[idx] = true;
+                    m_isInEncoding[idx] = ret;
+                }
+            }
+            return ret;
+        }
+
+        /**
+         * The encoding.
+         */
+        final private String m_encoding;
+        /**
+         * m_first through m_last is the range of unicode
+         * values that this object will return an answer on.
+         * It may delegate to a similar object with a different
+         * range
+         */
+        final private int m_first;
+        
+        /**
+         * m_explFirst through m_explLast is the range of unicode
+         * value that this object handles explicitly and does not
+         * delegate to a similar object.
+         */
+        final private int m_explFirst;
+        final private int m_explLast;
+        final private int m_last;
+
+        /**
+         * The object, of the same type as this one,
+         * that handles unicode values in a range before
+         * the range explictly handled by this object, and
+         * to which this object may delegate.
+         */
+        private InEncoding m_before;
+        /**
+         * The object, of the same type as this one,
+         * that handles unicode values in a range after
+         * the range explictly handled by this object, and
+         * to which this object may delegate.
+         */
+        private InEncoding m_after;
+        
+        /**
+         * The number of unicode values explicitly handled
+         * by a single EncodingInfo object. This value is 
+         * tuneable, but is set to 128 because that covers the
+         * entire low range of ASCII type chars within a single
+         * object.
+         */
+        private static final int RANGE = 128;
+
+        /**
+         * A flag to record if we already know the answer
+         * for the given unicode value.
+         */
+        final private boolean m_alreadyKnown[] = new boolean[RANGE];
+        /**
+         * A table holding the answer on whether the given unicode
+         * value is in the encoding.
+         */
+        final private boolean m_isInEncoding[] = new boolean[RANGE];
+        
+        private EncodingImpl() {
+            // This object will answer whether any unicode value
+            // is in the encoding, it handles values 0 through Integer.MAX_VALUE
+            this(javaName, 0, Integer.MAX_VALUE, (char) 0);
+        }
+
+        private EncodingImpl(String encoding, int first, int last, int codePoint) {
+            // Set the range of unicode values that this object manages
+            // either explicitly or implicitly.
+            m_first = first;
+            m_last = last;  
+                      
+            // Set the range of unicode values that this object 
+            // explicitly manages
+            m_explFirst = codePoint;
+            m_explLast = codePoint + (RANGE-1);  
+            
+            m_encoding = encoding;
+            
+            if (javaName != null)
+            {
+                // Some optimization.
+                if (0 <= m_explFirst && m_explFirst <= 127) {
+                    // This particular EncodingImpl explicitly handles
+                    // characters in the low range.
+                    if ("UTF8".equals(javaName)
+                        || "UTF-16".equals(javaName)
+                        || "ASCII".equals(javaName)
+                        || "US-ASCII".equals(javaName)
+                        || "Unicode".equals(javaName)
+                        || "UNICODE".equals(javaName)
+                        || javaName.startsWith("ISO8859")) {
+                        
+                        // Not only does this EncodingImpl object explicitly
+                        // handle chracters in the low range, it is
+                        // also one that we know something about, without
+                        // needing to call inEncoding(char ch, String encoding)
+                        // for this low range
+                        //
+                        // By initializing the table ahead of time
+                        // for these low values, we prevent the expensive
+                        // inEncoding(char ch, String encoding)
+                        // from being called, at least for these common
+                        // encodings.
+                        for (int unicode = 1; unicode < 127; unicode++) {
+                            final int idx = unicode - m_explFirst;
+                            if (0 <= idx && idx < RANGE) {
+                                m_alreadyKnown[idx] = true;
+                                m_isInEncoding[idx] = true;
+                            }
+                        }
+                    }
+                }
+
+                /* A little bit more than optimization.
+                 * 
+                 * We will say that any character is in the encoding if
+                 * we don't have an encoding.
+                 * This is meaningful when the serializer is being used
+                 * in temporary output state, where we are not writing to
+                 * the final output tree.  It is when writing to the
+                 * final output tree that we need to worry about the output
+                 * encoding
+                 */
+                if (javaName == null) {
+                    for (int idx = 0; idx < m_alreadyKnown.length; idx++) {
+                        m_alreadyKnown[idx] = true;
+                        m_isInEncoding[idx] = true;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * This is heart of the code that determines if a given character
+     * is in the given encoding. This method is probably expensive,
+     * and the answer should be cached.
+     * <p>
+     * This method is not a public API,
+     * and should only be used internally within the serializer.
+     * @param ch the char in question, that is not a high char of
+     * a high/low surrogate pair.
+     * @param encoding the Java name of the enocding.
+     * 
+     * @xsl.usage internal
+     * 
+     */
+    private static boolean inEncoding(char ch, String encoding) {
+        boolean isInEncoding;
+        try {
+            char cArray[] = new char[1];
+            cArray[0] = ch;
+            // Construct a String from the char 
+            String s = new String(cArray);
+            // Encode the String into a sequence of bytes 
+            // using the given, named charset. 
+            byte[] bArray = s.getBytes(encoding);
+            isInEncoding = inEncoding(ch, bArray);
+
+        } catch (Exception e) {
+            isInEncoding = false;
+            
+            // If for some reason the encoding is null, e.g.
+            // for a temporary result tree, we should just
+            // say that every character is in the encoding.
+            if (encoding == null)
+            	isInEncoding = true;
+        }
+        return isInEncoding;
+    }
+    
+    /**
+     * This is heart of the code that determines if a given high/low
+     * surrogate pair forms a character that is in the given encoding.
+     * This method is probably expensive, and the answer should be cached. 
+     * <p>
+     * This method is not a public API,
+     * and should only be used internally within the serializer.
+     * @param high the high char of
+     * a high/low surrogate pair.
+     * @param low the low char of a high/low surrogate pair.
+     * @param encoding the Java name of the encoding.
+     * 
+     * @xsl.usage internal
+     * 
+     */ 
+    private static boolean inEncoding(char high, char low, String encoding) {
+        boolean isInEncoding;
+        try {
+            char cArray[] = new char[2];
+            cArray[0] = high;
+            cArray[1] = low;
+            // Construct a String from the char 
+            String s = new String(cArray);
+            // Encode the String into a sequence of bytes 
+            // using the given, named charset. 
+            byte[] bArray = s.getBytes(encoding);
+            isInEncoding = inEncoding(high,bArray);
+        } catch (Exception e) {
+            isInEncoding = false;
+        }
+        
+        return isInEncoding;
+    } 
+    
+    /**
+     * This method is the core of determining if character
+     * is in the encoding. The method is not foolproof, because
+     * s.getBytes(encoding) has specified behavior only if the
+     * characters are in the specified encoding. However this
+     * method tries it's best.
+     * @param ch the char that was converted using getBytes, or
+     * the first char of a high/low pair that was converted.
+     * @param data the bytes written out by the call to s.getBytes(encoding);
+     * @return true if the character is in the encoding.
+     */
+    private static boolean inEncoding(char ch, byte[] data) {
+        final boolean isInEncoding;
+        // If the string written out as data is not in the encoding,
+        // the output is not specified according to the documentation
+        // on the String.getBytes(encoding) method,
+        // but we do our best here.        
+        if (data==null || data.length == 0) {
+            isInEncoding = false;
+        }
+        else {
+            if (data[0] == 0)
+                isInEncoding = false;
+            else if (data[0] == '?' && ch != '?')
+                isInEncoding = false;
+            /*
+             * else if (isJapanese) {
+             *   // isJapanese is really 
+             *   //   (    "EUC-JP".equals(javaName) 
+             *   //    ||  "EUC_JP".equals(javaName)
+             *  //     ||  "SJIS".equals(javaName)   )
+             * 
+             *   // Work around some bugs in JRE for Japanese
+             *   if(data[0] == 0x21)
+             *     isInEncoding = false;
+             *   else if (ch == 0xA5)
+             *     isInEncoding = false;
+             *   else
+             *     isInEncoding = true;
+             * }
+             */ 
+                
+            else {
+                // We don't know for sure, but it looks like it is in the encoding
+                isInEncoding = true; 
+            }
+        }
+        return isInEncoding;
+    }
+    
+    /**
+     * This method exists for performance reasons.
+     * <p>
+     * Except for '\u0000', if a char is less than or equal to the value
+     * returned by this method then it in the encoding.
+     * <p>
+     * The characters in an encoding are not contiguous, however
+     * there is a lowest group of chars starting at '\u0001' upto and
+     * including the char returned by this method that are all in the encoding.
+     * So the char returned by this method essentially defines the lowest
+     * contiguous group.
+     * <p>
+     * chars above the value returned might be in the encoding, but 
+     * chars at or below the value returned are definately in the encoding.
+     * <p>
+     * In any case however, the isInEncoding(char) method can be used
+     * regardless of the value of the char returned by this method.
+     * <p>
+     * If the value returned is '\u0000' it means that every character must be tested
+     * with an isInEncoding method {@link #isInEncoding(char)} or {@link #isInEncoding(char, char)} 
+     * for surrogate pairs.
+     * <p>
+     * This method is not a public API.
+     * @xsl.usage internal
+     */
+    public final char getHighChar() {
+        return m_highCharInContiguousGroup;
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/Encodings.java b/src/main/java/org/apache/xml/serializer/Encodings.java
new file mode 100644
index 0000000..0831ef5
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Encodings.java
@@ -0,0 +1,497 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Encodings.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+
+/**
+ * Provides information about encodings. Depends on the Java runtime
+ * to provides writers for the different encodings.
+ * <p>
+ * This class is not a public API. It is only public because it
+ * is used outside of this package.
+ * 
+ * @xsl.usage internal
+ */
+
+public final class Encodings extends Object
+{
+    /**
+     * Standard filename for properties file with encodings data.
+     */
+    private static final String ENCODINGS_FILE = SerializerBase.PKG_PATH+"/Encodings.properties";
+
+    /**
+     * Returns a writer for the specified encoding based on
+     * an output stream.
+     * <p>
+     * This is not a public API.
+     * @param output The output stream
+     * @param encoding The encoding MIME name, not a Java name for the encoding.
+     * @return A suitable writer
+     * @throws UnsupportedEncodingException There is no convertor
+     *  to support this encoding
+     * @xsl.usage internal
+     */
+    static Writer getWriter(OutputStream output, String encoding)
+        throws UnsupportedEncodingException
+    {
+
+        for (int i = 0; i < _encodings.length; ++i)
+        {
+            if (_encodings[i].name.equalsIgnoreCase(encoding))
+            {
+                try
+                {
+                    String javaName = _encodings[i].javaName;
+                	OutputStreamWriter osw = new OutputStreamWriter(output,javaName);
+                    return osw; 
+                }
+                catch (java.lang.IllegalArgumentException iae) // java 1.1.8
+                {
+                    // keep trying
+                }
+                catch (UnsupportedEncodingException usee)
+                {
+
+                    // keep trying
+                }
+            }
+        }
+
+        try
+        {
+            return new OutputStreamWriter(output, encoding);
+        }
+        catch (java.lang.IllegalArgumentException iae) // java 1.1.8
+        {
+            throw new UnsupportedEncodingException(encoding);
+        }
+    }
+
+    /**
+     * Returns the EncodingInfo object for the specified
+     * encoding, never null, although the encoding name 
+     * inside the returned EncodingInfo object will be if
+     * we can't find a "real" EncodingInfo for the encoding.
+     * <p>
+     * This is not a public API.
+     *
+     * @param encoding The encoding
+     * @return The object that is used to determine if 
+     * characters are in the given encoding.
+     * @xsl.usage internal
+     */
+    static EncodingInfo getEncodingInfo(String encoding)
+    {
+        EncodingInfo ei;
+
+        String normalizedEncoding = toUpperCaseFast(encoding);
+        ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding);
+        if (ei == null)
+            ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding);
+        if (ei == null) {
+            // We shouldn't have to do this, but just in case.
+            ei = new EncodingInfo(null,null, '\u0000');
+        }
+
+        return ei;
+    }
+ 
+    /**
+     * Determines if the encoding specified was recognized by the
+     * serializer or not.
+     *
+     * @param encoding The encoding
+     * @return boolean - true if the encoding was recognized else false
+     */
+    public static boolean isRecognizedEncoding(String encoding)
+    {
+        EncodingInfo ei;
+
+        String normalizedEncoding = encoding.toUpperCase();
+        ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding);
+        if (ei == null)
+            ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding);
+        if (ei != null)
+            return true;
+        return false;
+    }
+    
+    /**
+     * A fast and cheap way to uppercase a String that is
+     * only made of printable ASCII characters.
+     * <p>
+     * This is not a public API.
+     * @param s a String of ASCII characters
+     * @return an uppercased version of the input String,
+     * possibly the same String.
+     * @xsl.usage internal
+     */
+    static private String toUpperCaseFast(final String s) {
+
+    	boolean different = false;
+    	final int mx = s.length();
+		char[] chars = new char[mx];
+    	for (int i=0; i < mx; i++) {
+    		char ch = s.charAt(i);
+            // is the character a lower case ASCII one?
+    		if ('a' <= ch && ch <= 'z') {
+                // a cheap and fast way to uppercase that is good enough
+    			ch = (char) (ch + ('A' - 'a'));
+    			different = true; // the uppercased String is different
+    		}
+    		chars[i] = ch;
+    	}
+    	
+    	// A little optimization, don't call String.valueOf() if
+    	// the uppercased string is the same as the input string.
+    	final String upper;
+    	if (different) 
+    		upper = String.valueOf(chars);
+    	else
+    		upper = s;
+    		
+    	return upper;
+    }
+
+    /** The default encoding, ISO style, ISO style.   */
+    static final String DEFAULT_MIME_ENCODING = "UTF-8";
+
+    /**
+     * Get the proper mime encoding.  From the XSLT recommendation: "The encoding
+     * attribute specifies the preferred encoding to use for outputting the result
+     * tree. XSLT processors are required to respect values of UTF-8 and UTF-16.
+     * For other values, if the XSLT processor does not support the specified
+     * encoding it may signal an error; if it does not signal an error it should
+     * use UTF-8 or UTF-16 instead. The XSLT processor must not use an encoding
+     * whose name does not match the EncName production of the XML Recommendation
+     * [XML]. If no encoding attribute is specified, then the XSLT processor should
+     * use either UTF-8 or UTF-16."
+     * <p>
+     * This is not a public API.
+     *
+     * @param encoding Reference to java-style encoding string, which may be null,
+     * in which case a default will be found.
+     *
+     * @return The ISO-style encoding string, or null if failure.
+     * @xsl.usage internal
+     */
+    static String getMimeEncoding(String encoding)
+    {
+
+        if (null == encoding)
+        {
+            try
+            {
+
+                // Get the default system character encoding.  This may be
+                // incorrect if they passed in a writer, but right now there
+                // seems to be no way to get the encoding from a writer.
+                encoding = System.getProperty("file.encoding", "UTF8");
+
+                if (null != encoding)
+                {
+
+                    /*
+                    * See if the mime type is equal to UTF8.  If you don't
+                    * do that, then  convertJava2MimeEncoding will convert
+                    * 8859_1 to "ISO-8859-1", which is not what we want,
+                    * I think, and I don't think I want to alter the tables
+                    * to convert everything to UTF-8.
+                    */
+                    String jencoding =
+                        (encoding.equalsIgnoreCase("Cp1252")
+                            || encoding.equalsIgnoreCase("ISO8859_1")
+                            || encoding.equalsIgnoreCase("8859_1")
+                            || encoding.equalsIgnoreCase("UTF8"))
+                            ? DEFAULT_MIME_ENCODING
+                            : convertJava2MimeEncoding(encoding);
+
+                    encoding =
+                        (null != jencoding) ? jencoding : DEFAULT_MIME_ENCODING;
+                }
+                else
+                {
+                    encoding = DEFAULT_MIME_ENCODING;
+                }
+            }
+            catch (SecurityException se)
+            {
+                encoding = DEFAULT_MIME_ENCODING;
+            }
+        }
+        else
+        {
+            encoding = convertJava2MimeEncoding(encoding);
+        }
+
+        return encoding;
+    }
+
+    /**
+     * Try the best we can to convert a Java encoding to a XML-style encoding.
+     * <p>
+     * This is not a public API.
+     * @param encoding non-null reference to encoding string, java style.
+     *
+     * @return ISO-style encoding string.
+     * @xsl.usage internal
+     */
+    private static String convertJava2MimeEncoding(String encoding)
+    {
+        EncodingInfo enc =
+            (EncodingInfo) _encodingTableKeyJava.get(toUpperCaseFast(encoding));
+        if (null != enc)
+            return enc.name;
+        return encoding;
+    }
+
+    /**
+     * Try the best we can to convert a Java encoding to a XML-style encoding.
+     * <p>
+     * This is not a public API.
+     *
+     * @param encoding non-null reference to encoding string, java style.
+     *
+     * @return ISO-style encoding string.
+     * <p>
+     * This method is not a public API.
+     * @xsl.usage internal
+     */
+    public static String convertMime2JavaEncoding(String encoding)
+    {
+
+        for (int i = 0; i < _encodings.length; ++i)
+        {
+            if (_encodings[i].name.equalsIgnoreCase(encoding))
+            {
+                return _encodings[i].javaName;
+            }
+        }
+
+        return encoding;
+    }
+
+    /**
+     * Load a list of all the supported encodings.
+     *
+     * System property "encodings" formatted using URL syntax may define an
+     * external encodings list. Thanks to Sergey Ushakov for the code
+     * contribution!
+     * @xsl.usage internal
+     */
+    private static EncodingInfo[] loadEncodingInfo()
+    {
+        try
+        {
+            final InputStream is; 
+                
+            SecuritySupport ss = SecuritySupport.getInstance();
+            is = ss.getResourceAsStream(ObjectFactory.findClassLoader(),
+                                            ENCODINGS_FILE);
+
+            Properties props = new Properties();
+            if (is != null) {
+                props.load(is);
+                is.close();
+            } else {
+                // Seems to be no real need to force failure here, let the
+                // system do its best... The issue is not really very critical,
+                // and the output will be in any case _correct_ though maybe not
+                // always human-friendly... :)
+                // But maybe report/log the resource problem?
+                // Any standard ways to report/log errors (in static context)?
+            }
+
+            int totalEntries = props.size();
+
+            List encodingInfo_list = new ArrayList();
+            Enumeration keys = props.keys();
+            for (int i = 0; i < totalEntries; ++i)
+            {
+                String javaName = (String) keys.nextElement();
+                String val = props.getProperty(javaName);
+                int len = lengthOfMimeNames(val);
+
+                String mimeName;
+                char highChar;
+                if (len == 0)
+                {
+                    // There is no property value, only the javaName, so try and recover
+                    mimeName = javaName;
+                    highChar = '\u0000'; // don't know the high code point, will need to test every character
+                }
+                else
+                {
+                    try {
+                        // Get the substring after the Mime names
+                        final String highVal = val.substring(len).trim();
+                        highChar = (char) Integer.decode(highVal).intValue();
+                    }
+                    catch( NumberFormatException e) {
+                        highChar = 0;
+                    }
+                    String mimeNames = val.substring(0, len);
+                    StringTokenizer st =
+                        new StringTokenizer(mimeNames, ",");
+                    for (boolean first = true;
+                        st.hasMoreTokens();
+                        first = false)
+                    {
+                        mimeName = st.nextToken();
+                        EncodingInfo ei = new EncodingInfo(mimeName, javaName, highChar);
+                        encodingInfo_list.add(ei);
+                        _encodingTableKeyMime.put(mimeName.toUpperCase(), ei);
+                        if (first)
+                            _encodingTableKeyJava.put(javaName.toUpperCase(), ei);
+                    }
+                }
+            }
+            // Convert the Vector of EncodingInfo objects into an array of them,
+            // as that is the kind of thing this method returns.
+            EncodingInfo[] ret_ei = new EncodingInfo[encodingInfo_list.size()];
+            encodingInfo_list.toArray(ret_ei);
+            return ret_ei;
+        }
+        catch (java.net.MalformedURLException mue)
+        {
+            throw new org.apache.xml.serializer.utils.WrappedRuntimeException(mue);
+        }
+        catch (java.io.IOException ioe)
+        {
+            throw new org.apache.xml.serializer.utils.WrappedRuntimeException(ioe);
+        }
+    }
+    
+    /**
+     * Get the length of the Mime names within the property value
+     * @param val The value of the property, which should contain a comma
+     * separated list of Mime names, followed optionally by a space and the
+     * high char value
+     * @return
+     */
+    private static int lengthOfMimeNames(String val) {
+        // look for the space preceding the optional high char
+        int len = val.indexOf(' ');
+        // If len is zero it means the optional part is not there, so
+        // the value must be all Mime names, so set the length appropriately
+        if (len < 0)  
+            len = val.length();
+        
+        return len;
+    }
+
+    /**
+     * Return true if the character is the high member of a surrogate pair.
+     * <p>
+     * This is not a public API.
+     * @param ch the character to test
+     * @xsl.usage internal
+     */
+    static boolean isHighUTF16Surrogate(char ch) {
+        return ('\uD800' <= ch && ch <= '\uDBFF');
+    }
+    /**
+     * Return true if the character is the low member of a surrogate pair.
+     * <p>
+     * This is not a public API.
+     * @param ch the character to test
+     * @xsl.usage internal
+     */
+    static boolean isLowUTF16Surrogate(char ch) {
+        return ('\uDC00' <= ch && ch <= '\uDFFF');
+    }
+    /**
+     * Return the unicode code point represented by the high/low surrogate pair.
+     * <p>
+     * This is not a public API.
+     * @param highSurrogate the high char of the high/low pair
+     * @param lowSurrogate the low char of the high/low pair
+     * @xsl.usage internal
+     */
+    static int toCodePoint(char highSurrogate, char lowSurrogate) {
+        int codePoint =
+            ((highSurrogate - 0xd800) << 10)
+                + (lowSurrogate - 0xdc00)
+                + 0x10000;
+        return codePoint;
+    }
+    /**
+     * Return the unicode code point represented by the char.
+     * A bit of a dummy method, since all it does is return the char,
+     * but as an int value.
+     * <p>
+     * This is not a public API.
+     * @param ch the char.
+     * @xsl.usage internal
+     */
+    static int toCodePoint(char ch) {
+        int codePoint = ch;
+        return codePoint;
+    }
+    
+    /**
+     * Characters with values at or below the high code point are
+     * in the encoding. Code point values above this one may or may
+     * not be in the encoding, but lower ones certainly are.
+     * <p>
+     * This is for performance.
+     *
+     * @param encoding The encoding
+     * @return The code point for which characters at or below this code point
+     * are in the encoding. Characters with higher code point may or may not be
+     * in the encoding. A value of zero is returned if the high code point is unknown.
+     * <p>
+     * This method is not a public API.
+     * @xsl.usage internal
+     */
+    static public char getHighChar(String encoding)
+    {
+        final char highCodePoint;
+        EncodingInfo ei;
+
+        String normalizedEncoding = toUpperCaseFast(encoding);
+        ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding);
+        if (ei == null)
+            ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding);
+        if (ei != null)
+            highCodePoint =  ei.getHighChar();
+        else
+            highCodePoint = 0;
+        return highCodePoint;
+    }
+
+    private static final Hashtable _encodingTableKeyJava = new Hashtable();
+    private static final Hashtable _encodingTableKeyMime = new Hashtable();
+    private static final EncodingInfo[] _encodings = loadEncodingInfo();
+}
diff --git a/src/main/java/org/apache/xml/serializer/Encodings.properties b/src/main/java/org/apache/xml/serializer/Encodings.properties
new file mode 100644
index 0000000..71ebde8
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Encodings.properties
@@ -0,0 +1,260 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: Encodings.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# Each entry in this properties file is:
+# 1) The Java name for the encoding
+# 2) A comma separated list of the MIME names for the encoding,
+#    with the first one being the preferred MIME name.
+# 3) An optional high char. Characters at or below this value are
+#    definately in the encoding, but characters above it may or may not be.
+#    This value is given only for performance reasons.
+#    A value of zero is the same as no value at all.
+#
+# For example this line in this file:
+#              ASCII ASCII,US-ASCII 0x007F
+# Means the Java name for the encoding is "ASCII". The MIME names for this
+# encoding which may appear in a stylesheet are "ASCII" or "US-ASCII"
+# and the optional high code point value is given, and it is 0X007F
+# which means that the contiguous block of chars from
+# 0x0001 to 0x007F ( 127 in base 10) are all in the encoding.
+# Higher values above this char might be in the encoding, although in the 
+# case of this particular encoding there are no higher chars.
+#
+#
+# <JAVA name encoding>, <PREFERRED name MIME>
+#
+#
+ASCII      ASCII,US-ASCII                         0x007F
+#
+# Big5, Traditional Chinese 
+Big5       BIG5,csBig5                            0x007F
+#Big5 with Hong Kong extensions, Traditional Chinese (incorporating 2001 revision) 
+Big5_HKSCS BIG5-HKSCS                             0x007F
+# USA, Canada (Bilingual, French), Netherlands, Portugal, Brazil, Australia
+Cp037      EBCDIC-CP-US,EBCDIC-CP-CA,EBCDIC-CP-WT,EBCDIC-CP-NL,IBM037 0x0019
+# IBM Austria, Germany 
+Cp273      IBM273,csIBM273                        0x0019
+Cp274      csIBM274,EBCDIC-BE
+Cp275      csIBM275,EBCDIC-BR
+# IBM Denmark, Norway 
+Cp277      EBCDIC-CP-DK,EBCDIC-CP-NO,IBM277,csIBM277    0x0019
+# IBM Finland, Sweden 
+Cp278      EBCDIC-CP-FI,EBCDIC-CP-SE,IBM278,csIBM278    0x0019
+# IBM Italy
+Cp280      EBCDIC-CP-IT,IBM280,csIBM280           0x0019
+Cp281      EBCDIC-JP-E,csIBM281
+# IBM Catalan/Spain, Spanish Latin America 
+Cp284      EBCDIC-CP-ES,IBM284,csIBM284           0x0019
+# IBM United Kingdom, Ireland
+Cp285      EBCDIC-CP-GB,IBM284,csIBM285           0x0019
+Cp290      EBCDIC-JP-kana,IBM290,csIBM290         0x0019
+# IBM France
+Cp297      EBCDIC-CP-FR,IBM297,csIBM297           0x0019
+# IBM Arabic
+Cp420      EBCDIC-CP-AR1,IBM420,csIBM420          0x0019
+Cp423      EBCDIC-CP-GR,IBM423,csIBM423
+# IBM Hebrew
+Cp424      EBCDIC-CP-HE,IBM424,csIBM424           0x0019
+Cp437      437,IBM437,csPC8CodePage437            0x007F
+# EBCDIC 500V1
+Cp500      EBCDIC-CP-CH,EBCDIC-CP-BE,IBM500,csIBM500    0x0019
+# PC Baltic
+Cp775      IBM775,csPC775Baltic                   0x007F
+# IBM Thailand extended SBCS 
+Cp838      IBM-Thai,838,csIBMThai                 0x0019
+# MS-DOS Latin-1
+Cp850      850,csPC850Multilingual,IBM850         0x007F
+Cp851      851,IBM851,csIBM851
+# MS-DOS Latin-2
+Cp852      IBM852,852,csPCp852                    0x007F
+# IBM Cyrillic
+Cp855      IBM855,855,csIBM855                    0x007F
+# IBM Turkish
+Cp857      IBM857,857,csIBM857                    0x007F
+# Variant of Cp850 with Euro character 
+Cp858      IBM00858                               0x007F
+# MS-DOS Portuguese
+Cp860      860,csIBM860,IBM860                    0x007F
+# MS-DOS Icelandic
+Cp861      IBM861,861,csIBM861,cp-is              0x007F
+#
+Cp862      IBM862,862,csPCi62LatinHebrew          0x007F
+# MS-DOS Canadian French
+Cp863      IBM863,863,csIBM863                    0x007F
+# PC Arabic 
+Cp864      IBM864,864,csIBM864                    0x007F
+# MS-DOS Nordic 
+Cp865      IBM865,865,csIBM865                    0x007F
+# MS-DOS Russian 
+Cp866      IBM866,866,csIBM866                    0x007F
+# MS-DOS Pakistan 
+Cp868      IBM868,cp-ar,csIBM868                  0x007F
+# IBM Modern Greek 
+Cp869      IBM869,869,cp-gr,csIBM869              0x007F
+# IBM Multilingual Latin-2 
+Cp870      EBCDIC-CP-ROECE,EBCDIC-CP-YU,IBM870,csIBM870 0x0019
+# IBM Iceland 
+Cp871      EBCDIC-CP-IS,IBM871,csIBM871           0x0019
+Cp880      EBCDIC-Cyrillic,IBM880,csIBM880
+Cp891      IBM891,csIBM891
+Cp903      IBM903,csIBM903
+Cp904      IBM904,csIBM904
+Cp905      IBM905,csIBM905,EBCDIC-CP-TR
+# IBM Pakistan (Urdu)
+Cp918      EBCDIC-CP-AR2,IBM918,csIBM918          0x0019
+# GBK, Simplified Chinese 
+Cp936      GBK,MS936,WINDOWS-936
+# IBM Latin-5, Turkey 
+Cp1026     IBM1026,csIBM1026                      0x0019
+# Latin-1 character set for EBCDIC hosts 
+Cp1047     IBM1047,IBM-1047                       0x0019
+# Variant of Cp037 with Euro character 
+Cp1140     IBM01140                               0x0019
+# Variant of Cp273 with Euro character 
+Cp1141     IBM01141                               0x0019
+# Variant of Cp277 with Euro character 
+Cp1142     IBM01142                               0x0019
+# Variant of Cp278 with Euro character 
+Cp1143     IBM01143                               0x0019
+# Variant of Cp280 with Euro character 
+Cp1144     IBM01144                               0x0019
+# Variant of Cp284 with Euro character 
+Cp1145     IBM01145                               0x0019
+# Variant of Cp285 with Euro character 
+Cp1146     IBM01146                               0x0019
+# Variant of Cp297 with Euro character 
+Cp1147     IBM01147                               0x0019
+# Variant of Cp500 with Euro character 
+Cp1148     IBM01148                               0x0019
+# Variant of Cp871 with Euro character 
+Cp1149     IBM01149                               0x0019
+Cp1250     WINDOWS-1250                           0x007F
+Cp1251     WINDOWS-1251                           0x007F
+Cp1252     WINDOWS-1252                           0x007F
+Cp1253     WINDOWS-1253                           0x007F
+Cp1254     WINDOWS-1254                           0x007F
+# Windows Hebrew 
+Cp1255     WINDOWS-1255                           0x007F
+# Windows Arabic
+Cp1256     WINDOWS-1256                           0x007F
+Cp1257     WINDOWS-1257                           0x007F
+# Windows Vietnamese
+Cp1258     WINDOWS-1258                           0x007F
+EUC-CN     EUC-CN                                 0x007F
+EUC_CN     EUC-CN                                 0x007F
+#
+#JISX 0201, 0208 and 0212, EUC encoding Japanese
+EUC-JP     EUC-JP                                 0x007F
+EUC_JP     EUC-JP                                 0x007F
+# KS C 5601, EUC encoding, Korean 
+EUC-KR     EUC-KR                                 0x007F
+EUC_KR     EUC-KR                                 0x007F
+# CNS11643 (Plane 1-7,15), EUC encoding, Traditional Chinese
+EUC-TW     EUC-TW                                 0x007F
+EUC_TW     EUC-TW,x-EUC-TW                        0x007F
+EUCJIS     EUC-JP                                 0x007F
+#
+# GB2312, EUC encoding, Simplified Chinese 
+GB2312     GB2312                                 0x007F
+
+# GB2312 and CNS11643 in ISO 2022 CN form, Simplified and Traditional Chinese (conversion to Unicode only) 
+ISO2022CN  ISO-2022-CN
+# JIS X 0201, 0208, in ISO 2022 form, Japanese 
+ISO2022JP  ISO-2022-JP
+# ISO 2022 KR, Korean 
+ISO2022KR  ISO-2022-KR                            0x007F
+#
+#
+ISO8859-1  ISO-8859-1                             0x00FF
+ISO8859_1  ISO-8859-1                             0x00FF
+8859-1     ISO-8859-1                             0x00FF
+8859_1     ISO-8859-1                             0x00FF
+#
+ISO8859-2  ISO-8859-2                             0x00A0
+ISO8859_2  ISO-8859-2                             0x00A0
+8859-2     ISO-8859-2                             0x00A0
+8859_2     ISO-8859-2                             0x00A0
+#
+# Latin Alphabet No. 3 
+ISO8859-3  ISO-8859-3                             0x00A0
+ISO8859_3  ISO-8859-3                             0x00A0
+8859-3     ISO-8859-3                             0x00A0
+8859_3     ISO-8859-3                             0x00A0
+#
+ISO8859-4  ISO-8859-4                             0x00A0
+ISO8859_4  ISO-8859-4                             0x00A0
+8859-4     ISO-8859-4                             0x00A0
+8859_4     ISO-8859-4                             0x00A0
+#
+ISO8859-5  ISO-8859-5                             0x00A0
+ISO8859_5  ISO-8859-5                             0x00A0
+8859-5     ISO-8859-5                             0x00A0
+8859_5     ISO-8859-5                             0x00A0
+#
+# Latin/Arabic Alphabet 
+ISO8859-6  ISO-8859-6                             0x00A0
+ISO8859_6  ISO-8859-6                             0x00A0
+8859-6     ISO-8859-6                             0x00A0
+8859_6     ISO-8859-6                             0x00A0
+#
+ISO8859-7  ISO-8859-7                             0x00A0
+ISO8859_7  ISO-8859-7                             0x00A0
+8859-7     ISO-8859-7                             0x00A0
+8859_7     ISO-8859-7                             0x00A0
+#
+ISO8859-8  ISO-8859-8                             0x00A0
+ISO8859_8  ISO-8859-8                             0x00A0
+8859-8     ISO-8859-8                             0x00A0
+8859_8     ISO-8859-8                             0x00A0
+#
+ISO8859-9  ISO-8859-9                             0x00CF
+ISO8859_9  ISO-8859-9                             0x00CF
+8859-9     ISO-8859-9                             0x00CF
+8859_9     ISO-8859-9                             0x00CF
+#
+ISO8859-10 ISO-8859-10                            0x007E
+ISO8859_10 ISO-8859-10                            0x007E
+ISO8859-11 ISO-8859-11                            0x007E
+ISO8859_11 ISO-8859-11                            0x007E
+ISO8859-12 ISO-8859-12                            0x007F
+ISO8859_12 ISO-8859-12                            0x007F
+ISO8859-13 ISO-8859-13                            0x00A0
+ISO8859_13 ISO-8859-13                            0x00A0
+ISO8859-14 ISO-8859-14                            0x007E
+ISO8859_14 ISO-8859-14                            0x007E
+ISO8859-15 ISO-8859-15                            0x00A3
+ISO8859_15 ISO-8859-15                            0x00A3
+JIS        ISO-2022-JP                            0x007F
+KOI8_R     KOI8-R                                 0x007F
+KSC5601    EUC-KR                                 0x007F
+KS_C_5601-1987 KS_C_5601-1987,iso-ir-149,KS_C_5601-1989,KSC_5601,csKSC56011987  0x007F
+MacTEC     MacRoman
+# Windows Japanese
+MS932      windows-31j
+# Shift-JIS, Japanese 
+SJIS       SHIFT_JIS                              0x007F
+# TIS620, Thai
+TIS620     TIS-620
+UTF8       UTF-8                                  0xFFFF
+Unicode    UNICODE,UTF-16                         0xFFFF
+
+# note that more character set names and their aliases
+# can be found at http://www.iana.org/assignments/character-sets
+
diff --git a/src/main/java/org/apache/xml/serializer/ExtendedContentHandler.java b/src/main/java/org/apache/xml/serializer/ExtendedContentHandler.java
new file mode 100644
index 0000000..a811228
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ExtendedContentHandler.java
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtendedContentHandler.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import javax.xml.transform.SourceLocator;
+
+import org.xml.sax.SAXException;
+
+/**
+ * This interface describes extensions to the SAX ContentHandler interface.
+ * It is intended to be used by a serializer. The methods on this interface will
+ * implement SAX- like behavior. This allows the gradual collection of
+ * information rather than having it all up front. For example the call
+ * <pre>
+ * startElement(namespaceURI,localName,qName,atts)
+ * </pre>
+ * could be replaced with the calls
+ * <pre>
+ * startElement(namespaceURI,localName,qName)
+ * addAttributes(atts)
+ * </pre>
+ * If there are no attributes the second call can be dropped. If attributes are
+ * to be added one at a time with calls to
+ * <pre>
+ * addAttribute(namespaceURI, localName, qName, type, value)
+ * </pre>
+ * @xsl.usage internal
+ */
+public interface ExtendedContentHandler extends org.xml.sax.ContentHandler
+{
+    /**
+     * Add at attribute to the current element
+     * @param uri the namespace URI of the attribute name
+     * @param localName the local name of the attribute (without prefix)
+     * @param rawName the qualified name of the attribute
+     * @param type the attribute type typically character data (CDATA)
+     * @param value the value of the attribute
+     * @param XSLAttribute true if the added attribute is coming from an xsl:attribute element
+     * @throws SAXException
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+        throws SAXException;
+    /**
+     * Add attributes to the current element
+     * @param atts the attributes to add.
+     * @throws SAXException
+     */
+    public void addAttributes(org.xml.sax.Attributes atts)
+        throws org.xml.sax.SAXException;
+    /**
+     * Add an attribute to the current element. The namespace URI of the
+     * attribute will be calculated from the prefix of qName. The local name
+     * will be derived from qName and the type will be assumed to be "CDATA".
+     * @param qName
+     * @param value
+     */
+    public void addAttribute(String qName, String value);
+    
+    /**
+     * This method is used to notify of a character event, but passing the data
+     * as a character String rather than the standard character array.
+     * @param chars the character data
+     * @throws SAXException
+     */
+    public void characters(String chars) throws SAXException;
+    
+    /**
+     * This method is used to notify of a character event, but passing the data
+     * as a DOM Node rather than the standard character array.
+     * @param node a DOM Node containing text.
+     * @throws SAXException
+     */    
+    public void characters(org.w3c.dom.Node node) throws org.xml.sax.SAXException;
+    /**
+     * This method is used to notify that an element has ended. Unlike the
+     * standard SAX method
+     * <pre>
+     * endElement(namespaceURI,localName,qName)
+     * </pre>
+     * only the last parameter is passed. If needed the serializer can derive
+     * the localName from the qualified name and derive the namespaceURI from
+     * its implementation.
+     * @param elemName the fully qualified element name.
+     * @throws SAXException
+     */
+    public void endElement(String elemName) throws SAXException;
+
+    /**
+     * This method is used to notify that an element is starting.
+     * This method is just like the standard SAX method
+     * <pre>
+     * startElement(uri,localName,qname,atts)
+     * </pre>
+     * but without the attributes.
+     * @param uri the namespace URI of the element
+     * @param localName the local name (without prefix) of the element
+     * @param qName the qualified name of the element
+     * 
+     * @throws SAXException
+     */
+    public void startElement(String uri, String localName, String qName)
+        throws org.xml.sax.SAXException;
+
+    /**
+     * This method is used to notify of the start of an element
+     * @param qName the fully qualified name of the element
+     * @throws SAXException
+     */
+    public void startElement(String qName) throws SAXException;
+    /**
+     * This method is used to notify that a prefix mapping is to start, but
+     * after an element is started. The SAX method call
+     * <pre>
+     * startPrefixMapping(prefix,uri)
+     * </pre>
+     * is used just before an element starts and applies to the element to come,
+     * not to the current element.  This method applies to the current element.
+     * For example one could make the calls in this order:
+     * <pre>
+     * startElement("prfx8:elem9")
+     * namespaceAfterStartElement("http://namespace8","prfx8")
+     * </pre>
+     * 
+     * @param uri the namespace URI being declared
+     * @param prefix the prefix that maps to the given namespace
+     * @throws SAXException
+     */
+    public void namespaceAfterStartElement(String uri, String prefix)
+        throws SAXException;
+
+    /**
+     * This method is used to notify that a prefix maping is to start, which can
+     * be for the current element, or for the one to come.
+     * @param prefix the prefix that maps to the given URI
+     * @param uri the namespace URI of the given prefix
+     * @param shouldFlush if true this call is like the SAX
+     * startPrefixMapping(prefix,uri) call and the mapping applies to the
+     * element to come.  If false the mapping applies to the current element.
+     * @return boolean false if the prefix mapping was already in effect (in
+     * other words we are just re-declaring), true if this is a new, never
+     * before seen mapping for the element.
+     * @throws SAXException
+     */
+    public boolean startPrefixMapping(
+        String prefix,
+        String uri,
+        boolean shouldFlush)
+        throws SAXException;
+    /**
+     * Notify of an entity reference.
+     * @param entityName the name of the entity
+     * @throws SAXException
+     */
+    public void entityReference(String entityName) throws SAXException;
+
+    /**
+     * This method returns an object that has the current namespace mappings in
+     * effect.
+     * 
+     * @return NamespaceMappings an object that has the current namespace
+     * mappings in effect.
+     */
+    public NamespaceMappings getNamespaceMappings();
+    /**
+     * This method returns the prefix that currently maps to the given namespace
+     * URI.
+     * @param uri the namespace URI
+     * @return String the prefix that currently maps to the given URI.
+     */
+    public String getPrefix(String uri);
+    /**
+     * This method gets the prefix associated with a current element or
+     * attribute name.
+     * @param name the qualified name of an element, or attribute
+     * @param isElement true if it is an element name, false if it is an
+     * atttribute name
+     * @return String the namespace URI associated with the element or
+     * attribute.
+     */
+    public String getNamespaceURI(String name, boolean isElement);
+    /**
+     * This method returns the namespace URI currently associated with the
+     * prefix.
+     * @param prefix a prefix of an element or attribute.
+     * @return String the namespace URI currently associated with the prefix.
+     */
+    public String getNamespaceURIFromPrefix(String prefix);
+
+    /**
+     * This method is used to set the source locator, which might be used to
+     * generated an error message.
+     * @param locator the source locator
+     */
+    public void setSourceLocator(SourceLocator locator);
+
+    // Bit constants for addUniqueAttribute().
+    
+    // The attribute value contains no bad characters. A "bad" character is one which
+    // is greater than 126 or it is one of '<', '>', '&' or '"'.
+    public static final int NO_BAD_CHARS = 0x1;
+    
+    // An HTML empty attribute (e.g. <OPTION selected>).
+    public static final int HTML_ATTREMPTY = 0x2;
+    
+    // An HTML URL attribute
+    public static final int HTML_ATTRURL = 0x4;
+
+    /**
+     * Add a unique attribute to the current element.
+     * The attribute is guaranteed to be unique here. The serializer can write
+     * it out immediately without saving it in a table first. The integer
+     * flag contains information about the attribute, which helps the serializer
+     * to decide whether a particular processing is needed.
+     *
+     * @param qName the fully qualified attribute name.
+     * @param value the attribute value
+     * @param flags a bitwise flag
+     */
+    public void addUniqueAttribute(String qName, String value, int flags)
+        throws SAXException;
+    
+    /**
+     * Add an attribute from an xsl:attribute element.
+     * @param qName the qualified attribute name (prefix:localName)
+     * @param value the attributes value
+     * @param uri the uri that the prefix of the qName is mapped to.
+     */    
+    public void addXSLAttribute(String qName, final String value, final String uri);
+    
+    /**
+     * Add at attribute to the current element, not from an xsl:attribute
+     * element.
+     * @param uri the namespace URI of the attribute name
+     * @param localName the local name of the attribute (without prefix)
+     * @param rawName the qualified name of the attribute
+     * @param type the attribute type typically character data (CDATA)
+     * @param value the value of the attribute
+     * @throws SAXException
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value)
+        throws SAXException;
+}
diff --git a/src/main/java/org/apache/xml/serializer/ExtendedLexicalHandler.java b/src/main/java/org/apache/xml/serializer/ExtendedLexicalHandler.java
new file mode 100644
index 0000000..a825604
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ExtendedLexicalHandler.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtendedLexicalHandler.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import org.xml.sax.SAXException;
+
+/**
+ * This interface has extensions to the standard SAX LexicalHandler interface.
+ * This interface is intended to be used by a serializer.
+ * @xsl.usage internal
+ */
+public interface ExtendedLexicalHandler extends org.xml.sax.ext.LexicalHandler
+{
+    /**
+     * This method is used to notify of a comment
+     * @param comment the comment, but unlike the SAX comment() method this
+     * method takes a String rather than a character array.
+     * @throws SAXException
+     */
+    public void comment(String comment) throws SAXException;
+}
diff --git a/src/main/java/org/apache/xml/serializer/HTMLEntities.properties b/src/main/java/org/apache/xml/serializer/HTMLEntities.properties
new file mode 100644
index 0000000..2de4df6
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/HTMLEntities.properties
@@ -0,0 +1,311 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: HTMLEntities.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# @version $Revision: 468654 $ $Date: 2006-10-28 00:09:23 -0700 (Sat, 28 Oct 2006) $
+# This file must be encoded in UTF-8; see CharInfo.java
+#
+# Character entity references for markup-significant
+#
+quot=34
+amp=38
+lt=60
+gt=62
+nbsp=160
+#
+# Character entity references for ISO 8859-1 characters
+#
+iexcl=161
+cent=162
+pound=163
+curren=164
+yen=165
+brvbar=166
+sect=167
+uml=168
+copy=169
+ordf=170
+laquo=171
+not=172
+shy=173
+reg=174
+macr=175
+deg=176
+plusmn=177
+sup2=178
+sup3=179
+acute=180
+micro=181
+para=182
+middot=183
+cedil=184
+sup1=185
+ordm=186
+raquo=187
+frac14=188
+frac12=189
+frac34=190
+iquest=191
+Agrave=192
+Aacute=193
+Acirc=194
+Atilde=195
+Auml=196
+Aring=197
+AElig=198
+Ccedil=199
+Egrave=200
+Eacute=201
+Ecirc=202
+Euml=203
+Igrave=204
+Iacute=205
+Icirc=206
+Iuml=207
+ETH=208
+Ntilde=209
+Ograve=210
+Oacute=211
+Ocirc=212
+Otilde=213
+Ouml=214
+times=215
+Oslash=216
+Ugrave=217
+Uacute=218
+Ucirc=219
+Uuml=220
+Yacute=221
+THORN=222
+szlig=223
+agrave=224
+aacute=225
+acirc=226
+atilde=227
+auml=228
+aring=229
+aelig=230
+ccedil=231
+egrave=232
+eacute=233
+ecirc=234
+euml=235
+igrave=236
+iacute=237
+icirc=238
+iuml=239
+eth=240
+ntilde=241
+ograve=242
+oacute=243
+ocirc=244
+otilde=245
+ouml=246
+divide=247
+oslash=248
+ugrave=249
+uacute=250
+ucirc=251
+uuml=252
+yacute=253
+thorn=254
+yuml=255
+#
+# Character entity references for symbols, mathematical symbols, and Greek letters
+#
+# Latin Extended -- Netscape can't handle
+# fnof 402
+#
+# Greek - Netscape can't handle these
+# Alpha 913
+# Beta 914
+# Gamma 915
+# Delta 916
+# Epsilon 917
+# Zeta 918
+# Eta 919
+# Theta 920
+# Iota 921
+# Kappa 922
+# Lambda 923
+# Mu 924
+# Nu 925
+# Xi 926
+# Omicron 927
+# Pi 928
+# Rho 929
+# Sigma 931
+# Tau 932
+# Upsilon 933
+# Phi 934
+# Chi 935
+# Psi 936
+# Omega 937
+# alpha 945
+# beta 946
+# gamma 947
+# delta 948
+# epsilon 949
+# zeta 950
+# eta 951
+# theta 952
+# iota 953
+# kappa 954
+# lambda 955
+# mu 956
+# nu 957
+# xi 958
+# omicron 959
+# pi 960
+# rho 961
+# sigmaf 962
+# sigma 963
+# tau 964
+# upsilon 965
+# phi 966
+# chi 967
+# psi 968
+# omega 969
+# thetasym 977
+# upsih 978
+# piv 982
+#
+# General Punctuation
+bull=8226
+hellip=8230
+prime=8242
+Prime=8243
+oline=8254
+frasl=8260
+#
+# Letterlike Symbols
+weierp=8472
+image=8465
+real=8476
+trade=8482
+alefsym=8501
+#
+# Arrows
+larr=8592
+uarr=8593
+rarr=8594
+darr=8595
+harr=8596
+crarr=8629
+lArr=8656
+uArr=8657
+rArr=8658
+dArr=8659
+hArr=8660
+#
+# Mathematical Operators
+forall=8704
+part=8706
+exist=8707
+empty=8709
+nabla=8711
+isin=8712
+notin=8713
+ni=8715
+prod=8719
+sum=8721
+minus=8722
+lowast=8727
+radic=8730
+prop=8733
+infin=8734
+ang=8736
+and=8743
+or=8744
+cap=8745
+cup=8746
+int=8747
+there4=8756
+sim=8764
+cong=8773
+asymp=8776
+ne=8800
+equiv=8801
+le=8804
+ge=8805
+sub=8834
+sup=8835
+nsub=8836
+sube=8838
+supe=8839
+oplus=8853
+otimes=8855
+perp=8869
+sdot=8901
+#
+# Miscellaneous Technical
+lceil=8968
+rceil=8969
+lfloor=8970
+rfloor=8971
+lang=9001
+rang=9002
+#
+# Geometric Shapes
+loz=9674
+#
+# Miscellaneous Symbols
+spades=9824
+clubs=9827
+hearts=9829
+diams=9830
+#
+# Character entity references for internationalization characters
+#
+# Latin Extended-A
+# Netscape can't handle!
+# OElig 338
+# oelig 339
+
+#-- NN 4.7 does not seem to support these, so they might ought to be commented.
+# Scaron 352
+# scaron 353
+# Yuml 376
+#
+# Spacing Modifier Letters -- Netscape can't handle
+# circ 710
+# tilde 732
+#
+# General Punctuation
+ensp=8194
+emsp=8195
+thinsp=8201
+zwnj=8204
+zwj=8205
+lrm=8206
+rlm=8207
+ndash=8211
+mdash=8212
+lsquo=8216
+rsquo=8217
+sbquo=8218
+ldquo=8220
+rdquo=8221
+bdquo=8222
+dagger=8224
+Dagger=8225
+permil=8240
+lsaquo=8249
+rsaquo=8250
+euro=8364
diff --git a/src/main/java/org/apache/xml/serializer/Method.java b/src/main/java/org/apache/xml/serializer/Method.java
new file mode 100644
index 0000000..0fb66f0
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Method.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Method.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+/**
+ * This class defines the constants which are the names of the four default
+ * output methods.
+ * <p>
+ * The default output methods defined are:
+ * <ul>
+ * <li>XML
+ * <li>TEXT
+ * <li>HTML
+ * </ul>
+ * These constants can be used as an argument to the
+ * OutputPropertiesFactory.getDefaultMethodProperties() method to get
+ * the properties to create a serializer.
+ * 
+ * This class is a public API.
+ * 
+ * @see OutputPropertiesFactory
+ * @see Serializer
+ * 
+ * @xsl.usage general
+ */
+public final class Method
+{
+    /**
+     * A private constructor to prevent the creation of such a class.
+     */
+    private Method() {
+        
+    }
+
+  /**
+   * The output method type for XML documents: <tt>xml</tt>.
+   */
+  public static final String XML = "xml";
+
+  /**
+   * The output method type for HTML documents: <tt>html</tt>.
+   */
+  public static final String HTML = "html";
+
+  /**
+   * The output method for XHTML documents: <tt>xhtml</tt>.
+   * <p>
+   * This method type is not currently supported.
+   */
+  public static final String XHTML = "xhtml";
+
+  /**
+   * The output method type for text documents: <tt>text</tt>.
+   */
+  public static final String TEXT = "text";
+  
+  /**
+   * The "internal" method, just used when no method is 
+   * specified in the style sheet, and a serializer of this type wraps either an
+   * XML or HTML type (depending on the first tag in the output being html or
+   * not)
+   */  
+  public static final String UNKNOWN = "";
+}
diff --git a/src/main/java/org/apache/xml/serializer/NamespaceMappings.java b/src/main/java/org/apache/xml/serializer/NamespaceMappings.java
new file mode 100644
index 0000000..3c67d80
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/NamespaceMappings.java
@@ -0,0 +1,500 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NamespaceMappings.java 469648 2006-10-31 20:52:27Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * This class keeps track of the currently defined namespaces. Conceptually the
+ * prefix/uri/depth triplets are pushed on a stack pushed on a stack. The depth
+ * indicates the nesting depth of the element for which the mapping was made.
+ * 
+ * <p>For example:
+ * <pre>
+ * <chapter xmlns:p1="def">
+ *   <paragraph xmlns:p2="ghi">
+ *      <sentance xmlns:p3="jkl">
+ *      </sentance>
+ *    </paragraph>
+ *    <paragraph xlmns:p4="mno">
+ *    </paragraph>
+ * </chapter>
+ * </pre>
+ * 
+ * When the <chapter> element is encounted the prefix "p1" associated with uri
+ * "def" is pushed on the stack with depth 1.
+ * When the first <paragraph> is encountered "p2" and "ghi" are pushed with
+ * depth 2.
+ * When the <sentance> is encountered "p3" and "jkl" are pushed with depth 3.
+ * When </sentance> occurs the popNamespaces(3) will pop "p3"/"jkl" off the
+ * stack.  Of course popNamespaces(2) would pop anything with depth 2 or
+ * greater.
+ * 
+ * So prefix/uri pairs are pushed and poped off the stack as elements are
+ * processed.  At any given moment of processing the currently visible prefixes
+ * are on the stack and a prefix can be found given a uri, or a uri can be found
+ * given a prefix.
+ *
+ * This class is intended for internal use only.  However, it is made public because
+ * other packages require it. 
+ * @xsl.usage internal
+ */
+public class NamespaceMappings
+{
+    /**
+     * This member is continually incremented when new prefixes need to be
+     * generated. ("ns0"  "ns1" ...)
+     */
+    private int count = 0;
+
+    /**
+     * Each entry (prefix) in this hashtable points to a Stack of URIs
+     * This table maps a prefix (String) to a Stack of NamespaceNodes.
+     * All Namespace nodes in that retrieved stack have the same prefix,
+     * though possibly different URI's or depths. Such a stack must have
+     * mappings at deeper depths push later on such a stack.  Mappings pushed
+     * earlier on the stack will have smaller values for MappingRecord.m_declarationDepth.
+     */
+    private Hashtable m_namespaces = new Hashtable();
+
+    /** 
+     * This stack is used as a convenience.
+     * It contains the pushed NamespaceNodes (shallowest
+     * to deepest) and is used to delete NamespaceNodes 
+     * when leaving the current element depth 
+     * to returning to the parent. The mappings of the deepest
+     * depth can be popped of the top and the same node
+     * can be removed from the appropriate prefix stack.
+     * 
+     * All prefixes pushed at the current depth can be 
+     * removed at the same time by using this stack to
+     * ensure prefix/uri map scopes are closed correctly.
+     */
+    private Stack m_nodeStack = new Stack();
+
+    private static final String EMPTYSTRING = "";
+    private static final String XML_PREFIX = "xml"; // was "xmlns"
+
+    /**
+     * Default constructor
+     * @see java.lang.Object#Object()
+     */
+    public NamespaceMappings()
+    {
+        initNamespaces();
+    }
+
+    /**
+     * This method initializes the namespace object with appropriate stacks
+     * and predefines a few prefix/uri pairs which always exist.
+     */
+    private void initNamespaces()
+    {
+        // The initial prefix mappings will never be deleted because they are at element depth -1 
+        // (a kludge)
+        
+        // Define the default namespace (initially maps to "" uri)
+        Stack stack;
+        MappingRecord nn;
+        nn = new MappingRecord(EMPTYSTRING, EMPTYSTRING, -1);
+        stack = createPrefixStack(EMPTYSTRING);
+        stack.push(nn);
+
+        // define "xml" namespace
+        nn = new MappingRecord(XML_PREFIX, "http://www.w3.org/XML/1998/namespace", -1);
+        stack = createPrefixStack(XML_PREFIX);
+        stack.push(nn);
+    }
+
+    /**
+     * Use a namespace prefix to lookup a namespace URI.
+     * 
+     * @param prefix String the prefix of the namespace
+     * @return the URI corresponding to the prefix, returns ""
+     * if there is no visible mapping.
+     */
+    public String lookupNamespace(String prefix)
+    {
+        String uri = null;
+        final Stack stack = getPrefixStack(prefix);
+        if (stack != null && !stack.isEmpty()) {
+            uri = ((MappingRecord) stack.peek()).m_uri;
+        }
+        if (uri == null)
+            uri = EMPTYSTRING;
+        return uri;
+    }
+  
+    
+    MappingRecord getMappingFromPrefix(String prefix) {
+        final Stack stack = (Stack) m_namespaces.get(prefix);
+        return stack != null && !stack.isEmpty() ? 
+            ((MappingRecord) stack.peek()) : null;
+    }
+
+    /**
+     * Given a namespace uri, and the namespaces mappings for the 
+     * current element, return the current prefix for that uri.
+     * 
+     * @param uri the namespace URI to be search for
+     * @return an existing prefix that maps to the given URI, null if no prefix
+     * maps to the given namespace URI.
+     */
+    public String lookupPrefix(String uri)
+    {
+        String foundPrefix = null;
+        Enumeration prefixes = m_namespaces.keys();
+        while (prefixes.hasMoreElements())
+        {
+            String prefix = (String) prefixes.nextElement();
+            String uri2 = lookupNamespace(prefix);
+            if (uri2 != null && uri2.equals(uri))
+            {
+                foundPrefix = prefix;
+                break;
+            }
+        }
+        return foundPrefix;
+    }
+    
+    MappingRecord getMappingFromURI(String uri)
+    {
+        MappingRecord foundMap = null;
+        Enumeration prefixes = m_namespaces.keys();
+        while (prefixes.hasMoreElements())
+        {
+            String prefix = (String) prefixes.nextElement();
+            MappingRecord map2 = getMappingFromPrefix(prefix);
+            if (map2 != null && (map2.m_uri).equals(uri))
+            {
+                foundMap = map2;
+                break;
+            }
+        }
+        return foundMap;
+    }
+
+    /**
+     * Undeclare the namespace that is currently pointed to by a given prefix
+     */
+    boolean popNamespace(String prefix)
+    {
+        // Prefixes "xml" and "xmlns" cannot be redefined
+        if (prefix.startsWith(XML_PREFIX))
+        {
+            return false;
+        }
+
+        Stack stack;
+        if ((stack = getPrefixStack(prefix)) != null)
+        {
+            stack.pop();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Declare a mapping of a prefix to namespace URI at the given element depth.
+     * @param prefix a String with the prefix for a qualified name
+     * @param uri a String with the uri to which the prefix is to map
+     * @param elemDepth the depth of current declaration
+     */
+    public boolean pushNamespace(String prefix, String uri, int elemDepth)
+    {
+        // Prefixes "xml" and "xmlns" cannot be redefined
+        if (prefix.startsWith(XML_PREFIX))
+        {
+            return false;
+        }
+
+        Stack stack;
+        // Get the stack that contains URIs for the specified prefix
+        if ((stack = (Stack) m_namespaces.get(prefix)) == null)
+        {
+            m_namespaces.put(prefix, stack = new Stack());
+        }
+
+        if (!stack.empty())
+        {
+            MappingRecord mr = (MappingRecord)stack.peek();
+            if (uri.equals(mr.m_uri) || elemDepth == mr.m_declarationDepth) {
+                // If the same prefix/uri mapping is already on the stack
+                // don't push this one.
+                // Or if we have a mapping at the same depth
+                // don't replace by pushing this one. 
+                return false;
+            }
+        }
+        MappingRecord map = new MappingRecord(prefix,uri,elemDepth);
+        stack.push(map);
+        m_nodeStack.push(map);
+        return true;
+    }
+
+    /**
+     * Pop, or undeclare all namespace definitions that are currently
+     * declared at the given element depth, or deepter.
+     * @param elemDepth the element depth for which mappings declared at this
+     * depth or deeper will no longer be valid
+     * @param saxHandler The ContentHandler to notify of any endPrefixMapping()
+     * calls.  This parameter can be null.
+     */
+    void popNamespaces(int elemDepth, ContentHandler saxHandler)
+    {
+        while (true)
+        {
+            if (m_nodeStack.isEmpty())
+                return;
+            MappingRecord map = (MappingRecord) (m_nodeStack.peek());
+            int depth = map.m_declarationDepth;
+            if (elemDepth < 1 || map.m_declarationDepth < elemDepth)
+                break;
+            /* the depth of the declared mapping is elemDepth or deeper
+             * so get rid of it
+             */
+
+            MappingRecord nm1 = (MappingRecord) m_nodeStack.pop();
+            // pop the node from the stack
+            String prefix = map.m_prefix;
+
+            Stack prefixStack = getPrefixStack(prefix);
+            MappingRecord nm2 = (MappingRecord) prefixStack.peek();
+            if (nm1 == nm2)
+            {
+                // It would be nice to always pop() but we
+                // need to check that the prefix stack still has
+                // the node we want to get rid of. This is because
+                // the optimization of essentially this situation:
+                // <a xmlns:x="abc"><b xmlns:x="" xmlns:x="abc" /></a>
+                // will remove both mappings in <b> because the
+                // new mapping is the same as the masked one and we get
+                // <a xmlns:x="abc"><b/></a>
+                // So we are only removing xmlns:x="" or
+                // xmlns:x="abc" from the depth of element <b>
+                // when going back to <a> if in fact they have
+                // not been optimized away.
+                // 
+                prefixStack.pop();
+                if (saxHandler != null)
+                {
+                    try
+                    {
+                        saxHandler.endPrefixMapping(prefix);
+                    }
+                    catch (SAXException e)
+                    {
+                        // not much we can do if they aren't willing to listen
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * Generate a new namespace prefix ( ns0, ns1 ...) not used before
+     * @return String a new namespace prefix ( ns0, ns1, ns2 ...)
+     */
+    public String generateNextPrefix()
+    {
+        return "ns" + (count++);
+    }
+
+ 
+    /**
+     * This method makes a clone of this object.
+     *
+     */
+    public Object clone() throws CloneNotSupportedException {
+        NamespaceMappings clone = new NamespaceMappings();
+        clone.m_nodeStack = (NamespaceMappings.Stack) m_nodeStack.clone();        
+        clone.count = this.count;
+        clone.m_namespaces = (Hashtable) m_namespaces.clone();
+        
+        clone.count = count;
+        return clone;
+        
+    }
+    
+    final void reset()
+    {
+        this.count = 0;
+        this.m_namespaces.clear();
+        this.m_nodeStack.clear();        
+        
+        initNamespaces();
+    }
+    
+    /**
+     * Just a little class that ties the 3 fields together
+     * into one object, and this simplifies the pushing
+     * and popping of namespaces to one push or one pop on
+     * one stack rather than on 3 separate stacks.
+     */
+    class MappingRecord {
+        final String m_prefix;  // the prefix
+        final String m_uri;     // the uri, possibly "" but never null
+        // the depth of the element where declartion was made
+        final int m_declarationDepth;
+        MappingRecord(String prefix, String uri, int depth) {
+            m_prefix = prefix;
+            m_uri = (uri==null)? EMPTYSTRING : uri;
+            m_declarationDepth = depth;
+        }
+    }    
+    
+    /**
+     * Rather than using java.util.Stack, this private class
+     * provides a minimal subset of methods and is faster
+     * because it is not thread-safe.
+     */
+    private class Stack {
+        private int top = -1;
+        private int max = 20;
+        Object[] m_stack = new Object[max];
+        
+        public Object clone() throws CloneNotSupportedException {
+            NamespaceMappings.Stack clone = new NamespaceMappings.Stack();  
+            clone.max = this.max;
+            clone.top = this.top;
+            clone.m_stack = new Object[clone.max];
+            for (int i=0; i <= top; i++) {
+            	// We are just copying references to immutable MappingRecord objects here
+            	// so it is OK if the clone has references to these.
+            	clone.m_stack[i] = this.m_stack[i];
+            }
+            return clone;            
+        }
+        
+        public Stack()
+        {
+        }
+        
+        public Object push(Object o) {
+            top++;
+            if (max <= top) {
+                int newMax = 2*max + 1;
+                Object[] newArray = new Object[newMax];
+                System.arraycopy(m_stack,0, newArray, 0, max);
+                max = newMax;
+                m_stack = newArray;
+            }
+            m_stack[top] = o;
+            return o;
+        }
+        
+        public Object pop() {
+            Object o;
+            if (0 <= top) {
+                o = m_stack[top];
+                // m_stack[top] = null;  do we really care?
+                top--;
+            }
+            else
+                o = null;
+            return o;
+        }
+        
+        public Object peek() {
+            Object o;
+            if (0 <= top) {
+                o = m_stack[top];
+            }
+            else
+                o = null;
+            return o;
+        }
+        
+        public Object peek(int idx) {
+            return m_stack[idx];
+        }
+        
+        public boolean isEmpty() {
+            return (top < 0);
+        }
+        public boolean empty() {
+            return (top < 0);
+        }
+        
+        public void clear() {
+            for (int i=0; i<= top; i++)
+                m_stack[i] = null;
+            top = -1;
+        }  
+        
+        public Object getElement(int index) {
+            return m_stack[index];      
+        }
+    }
+    /**
+     * A more type-safe way to get a stack of prefix mappings
+     * from the Hashtable m_namespaces
+     * (this is the only method that does the type cast).
+     */
+
+    private Stack getPrefixStack(String prefix) {
+        Stack fs = (Stack) m_namespaces.get(prefix);
+        return fs;
+    }
+    
+    /**
+     * A more type-safe way of saving stacks under the
+     * m_namespaces Hashtable.
+     */
+    private Stack createPrefixStack(String prefix)
+    {
+        Stack fs = new Stack();
+        m_namespaces.put(prefix, fs);
+        return fs;
+    }
+    
+    /**
+     * Given a namespace uri, get all prefixes bound to the Namespace URI in the current scope. 
+     * 
+     * @param uri the namespace URI to be search for
+     * @return An array of Strings which are
+     * all prefixes bound to the namespace URI in the current scope.
+     * An array of zero elements is returned if no prefixes map to the given
+     * namespace URI.
+     */
+    public String[] lookupAllPrefixes(String uri)
+    {
+        java.util.ArrayList foundPrefixes = new java.util.ArrayList();
+        Enumeration prefixes = m_namespaces.keys();
+        while (prefixes.hasMoreElements())
+        {
+            String prefix = (String) prefixes.nextElement();
+            String uri2 = lookupNamespace(prefix);
+            if (uri2 != null && uri2.equals(uri))
+            {
+                foundPrefixes.add(prefix);
+            }
+        }
+        String[] prefixArray = new String[foundPrefixes.size()];
+        foundPrefixes.toArray(prefixArray);
+        return prefixArray;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ObjectFactory.java b/src/main/java/org/apache/xml/serializer/ObjectFactory.java
new file mode 100755
index 0000000..560d984
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ObjectFactory.java
@@ -0,0 +1,660 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectFactory.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @xsl.usage internal
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services/";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                FileInputStream fis = null;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        fis = ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                    }
+	        } catch (Exception x) {
+	            fXalanProperties = null;
+	            fLastModified = -1;
+                    // assert(x instanceof FileNotFoundException
+	            //        || x instanceof SecurityException)
+	            // In both cases, ignore and continue w/ next location
+	        }
+                finally {
+                    // try to close the input stream if one was opened.
+                    if (fis != null) {
+                        try {
+                            fis.close();
+                        }
+                        // Ignore the exception.
+                        catch (IOException exc) {}
+                    }
+                }	            
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            FileInputStream fis = null;
+            try {
+                fis = ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+            finally {
+                // try to close the input stream if one was opened.
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    }
+                    // Ignore the exception.
+                    catch (IOException exc) {}
+                }
+            }               
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+        finally {
+            try {
+                // try to close the reader.
+                rd.close();
+            }
+            // Ignore the exception.
+            catch (IOException exc) {}
+        }          
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = 8859254254255146542L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xml/serializer/OutputPropertiesFactory.java b/src/main/java/org/apache/xml/serializer/OutputPropertiesFactory.java
new file mode 100644
index 0000000..cb41927
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/OutputPropertiesFactory.java
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OutputPropertiesFactory.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.xml.transform.OutputKeys;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.apache.xml.serializer.utils.WrappedRuntimeException;
+
+/**
+ * This class is a factory to generate a set of default properties
+ * of key/value pairs that are used to create a serializer through the
+ * factory {@link SerializerFactory SerilizerFactory}. 
+ * The properties generated by this factory
+ * may be modified to non-default values before the SerializerFactory is used to
+ * create a Serializer.
+ * <p>
+ * The given output types supported are "xml", "text", and "html". 
+ * These type strings can be obtained from the 
+ * {@link Method Method} class in this package.
+ * <p>
+ * Other constants defined in this class are the non-standard property keys
+ * that can be used to set non-standard property values on a java.util.Properties object
+ * that is used to create or configure a serializer. Here are the non-standard keys:
+ * <ul>
+ * <li> <b>S_KEY_INDENT_AMOUNT </b> -
+ * The non-standard property key to use to set the indentation amount.
+ * The "indent" key needs to have a value of "yes", and this
+ * properties value is a the number of whitespaces to indent by per
+ * indentation level.
+ * 
+ * <li> <b>S_KEY_CONTENT_HANDLER </b> -
+ * This non-standard property key is used to set the name of the fully qualified 
+ * Java class that implements the ContentHandler interface. 
+ * The output of the serializer will be SAX events sent to this an
+ * object of this class.
+ * 
+ * <li> <b>S_KEY_ENTITIES </b> -
+ * This non-standard property key is used to specify the name of the property file
+ * that specifies character to entity reference mappings. A line in such a
+ * file is has the name of the entity and the numeric (base 10) value
+ * of the corresponding character, like this one: <br> quot=34 <br>
+ * 
+ * <li> <b>S_USE_URL_ESCAPING </b> -
+ * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should
+ *  use %xx escaping.
+ * 
+ * <li> <b>S_OMIT_META_TAG </b> -
+ * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would
+ *  otherwise be supplied.
+ * </ul>
+ * 
+ * @see SerializerFactory
+ * @see Method
+ * @see Serializer
+ */
+public final class OutputPropertiesFactory
+{
+    /** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace 
+     *(http://xml.apache.org/xalan) predefined to signify Xalan's
+     * built-in XSLT Extensions. When used in stylesheets, this is often 
+     * bound to the "xalan:" prefix.
+     */
+    private static final String 
+      S_BUILTIN_EXTENSIONS_URL = "http://xml.apache.org/xalan"; 
+
+    /**
+     * The old built-in extension url. It is still supported for
+     * backward compatibility.
+     */
+    private static final String 
+      S_BUILTIN_OLD_EXTENSIONS_URL = "http://xml.apache.org/xslt"; 
+      
+    //************************************************************
+    //*  PUBLIC CONSTANTS
+    //************************************************************
+    /** 
+     * This is not a public API.
+     * This is the built-in extensions namespace, 
+     * reexpressed in {namespaceURI} syntax
+     * suitable for prepending to a localname to produce a "universal
+     * name".
+     */
+    public static final String S_BUILTIN_EXTENSIONS_UNIVERSAL =
+        "{" + S_BUILTIN_EXTENSIONS_URL + "}";
+
+    // Some special Xalan keys.
+
+    /** 
+     * The non-standard property key to use to set the
+     * number of whitepaces to indent by, per indentation level,
+     * if indent="yes".
+     */
+    public static final String S_KEY_INDENT_AMOUNT =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "indent-amount";
+        
+    /** 
+     * The non-standard property key to use to set the
+     * characters to write out as at the end of a line,
+     * rather than the default ones from the runtime.
+     */
+    public static final String S_KEY_LINE_SEPARATOR =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "line-separator";        
+
+    /** This non-standard property key is used to set the name of the fully qualified 
+     * Java class that implements the ContentHandler interface. 
+     * Fully qualified name of class with a default constructor that
+     *  implements the ContentHandler interface, where the result tree events
+     *  will be sent to.
+     */
+
+    public static final String S_KEY_CONTENT_HANDLER =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "content-handler";
+
+    /**
+     * This non-standard property key is used to specify the name of the property file
+     * that specifies character to entity reference mappings.
+     */
+    public static final String S_KEY_ENTITIES =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "entities";
+
+    /** 
+     * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should
+     *  use %xx escaping. */
+    public static final String S_USE_URL_ESCAPING =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "use-url-escaping";
+
+    /** 
+     * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would
+     *  otherwise be supplied.
+     */
+    public static final String S_OMIT_META_TAG =
+        S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag";
+
+    /**
+     * The old built-in extension namespace, this is not a public API.
+     */
+    public static final String S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL =
+        "{" + S_BUILTIN_OLD_EXTENSIONS_URL + "}";
+
+    /**
+     * This is not a public API, it is only public because it is used
+     * by outside of this package,
+     * it is the length of the old built-in extension namespace.
+     */
+    public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN =
+        S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL.length();
+
+    //************************************************************
+    //*  PRIVATE CONSTANTS
+    //************************************************************
+
+    private static final String S_XSLT_PREFIX = "xslt.output.";
+    private static final int S_XSLT_PREFIX_LEN = S_XSLT_PREFIX.length();
+    private static final String S_XALAN_PREFIX = "org.apache.xslt.";
+    private static final int S_XALAN_PREFIX_LEN = S_XALAN_PREFIX.length();
+
+    /** Synchronization object for lazy initialization of the above tables. */
+    private static Integer m_synch_object = new Integer(1);
+
+    /** the directory in which the various method property files are located */
+    private static final String PROP_DIR = SerializerBase.PKG_PATH+'/';
+    /** property file for default XML properties */
+    private static final String PROP_FILE_XML = "output_xml.properties";
+    /** property file for default TEXT properties */
+    private static final String PROP_FILE_TEXT = "output_text.properties";
+    /** property file for default HTML properties */
+    private static final String PROP_FILE_HTML = "output_html.properties";
+    /** property file for default UNKNOWN (Either XML or HTML, to be determined later) properties */
+    private static final String PROP_FILE_UNKNOWN = "output_unknown.properties";
+
+    //************************************************************
+    //*  PRIVATE STATIC FIELDS
+    //************************************************************
+
+    /** The default properties of all output files. */
+    private static Properties m_xml_properties = null;
+
+    /** The default properties when method="html". */
+    private static Properties m_html_properties = null;
+
+    /** The default properties when method="text". */
+    private static Properties m_text_properties = null;
+
+    /** The properties when method="" for the "unknown" wrapper */
+    private static Properties m_unknown_properties = null;
+
+    private static final Class
+        ACCESS_CONTROLLER_CLASS = findAccessControllerClass();
+
+    private static Class findAccessControllerClass() {
+        try
+        {
+            // This Class was introduced in JDK 1.2. With the re-architecture of
+            // security mechanism ( starting in JDK 1.2 ), we have option of
+            // giving privileges to certain part of code using doPrivileged block.
+            // In JDK1.1.X applications won't be having security manager and if
+            // there is security manager ( in applets ), code need to be signed
+            // and trusted for having access to resources.
+
+            return Class.forName("java.security.AccessController");
+        }
+        catch (Exception e)
+        {
+            //User may be using older JDK ( JDK <1.2 ). Allow him/her to use it.
+            // But don't try to use doPrivileged
+        }
+
+        return null;
+    }
+
+    /**
+     * Creates an empty OutputProperties with the property key/value defaults specified by
+     * a property file.  The method argument is used to construct a string of
+     * the form output_[method].properties (for instance, output_html.properties).
+     * The output_xml.properties file is always used as the base.
+     * 
+     * <p>Anything other than 'text', 'xml', and 'html', will
+     * use the output_xml.properties file.</p>
+     *
+     * @param   method non-null reference to method name.
+     *
+     * @return Properties object that holds the defaults for the given method.
+     */
+    static public final Properties getDefaultMethodProperties(String method)
+    {
+        String fileName = null;
+        Properties defaultProperties = null;
+        // According to this article : Double-check locking does not work
+        // http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-toolbox.html
+        try
+        {
+            synchronized (m_synch_object)
+            {
+                if (null == m_xml_properties) // double check
+                {
+                    fileName = PROP_FILE_XML;
+                    m_xml_properties = loadPropertiesFile(fileName, null);
+                }
+            }
+
+            if (method.equals(Method.XML))
+            {
+                defaultProperties = m_xml_properties;
+            }
+            else if (method.equals(Method.HTML))
+            {
+                if (null == m_html_properties) // double check
+                {
+                    fileName = PROP_FILE_HTML;
+                    m_html_properties =
+                        loadPropertiesFile(fileName, m_xml_properties);
+                }
+
+                defaultProperties = m_html_properties;
+            }
+            else if (method.equals(Method.TEXT))
+            {
+                if (null == m_text_properties) // double check
+                {
+                    fileName = PROP_FILE_TEXT;
+                    m_text_properties =
+                        loadPropertiesFile(fileName, m_xml_properties);
+                    if (null
+                        == m_text_properties.getProperty(OutputKeys.ENCODING))
+                    {
+                        String mimeEncoding = Encodings.getMimeEncoding(null);
+                        m_text_properties.put(
+                            OutputKeys.ENCODING,
+                            mimeEncoding);
+                    }
+                }
+
+                defaultProperties = m_text_properties;
+            }
+            else if (method.equals(Method.UNKNOWN))
+            {
+                if (null == m_unknown_properties) // double check
+                {
+                    fileName = PROP_FILE_UNKNOWN;
+                    m_unknown_properties =
+                        loadPropertiesFile(fileName, m_xml_properties);
+                }
+
+                defaultProperties = m_unknown_properties;
+            }
+            else
+            {
+                // TODO: Calculate res file from name.
+                defaultProperties = m_xml_properties;
+            }
+        }
+        catch (IOException ioe)
+        {
+            throw new WrappedRuntimeException(
+                Utils.messages.createMessage(
+                    MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                    new Object[] { fileName, method }),
+                ioe);
+        }
+        // wrap these cached defaultProperties in a new Property object just so
+        // that the caller of this method can't modify the default values
+        return new Properties(defaultProperties);
+    }
+
+    /**
+     * Load the properties file from a resource stream.  If a
+     * key name such as "org.apache.xslt.xxx", fix up the start of
+     * string to be a curly namespace.  If a key name starts with
+     * "xslt.output.xxx", clip off "xslt.output.".  If a key name *or* a
+     * key value is discovered, check for \u003a in the text, and
+     * fix it up to be ":", since earlier versions of the JDK do not
+     * handle the escape sequence (at least in key names).
+     *
+     * @param resourceName non-null reference to resource name.
+     * @param defaults Default properties, which may be null.
+     */
+    static private Properties loadPropertiesFile(
+        final String resourceName,
+        Properties defaults)
+        throws IOException
+    {
+
+        // This static method should eventually be moved to a thread-specific class
+        // so that we can cache the ContextClassLoader and bottleneck all properties file
+        // loading throughout Xalan.
+
+        Properties props = new Properties(defaults);
+
+        InputStream is = null;
+        BufferedInputStream bis = null;
+
+        try
+        {
+            if (ACCESS_CONTROLLER_CLASS != null)
+            {
+                is = (InputStream) AccessController
+                    .doPrivileged(new PrivilegedAction() {
+                        public Object run()
+                        {
+                            return OutputPropertiesFactory.class
+                                .getResourceAsStream(resourceName);
+                        }
+                    });
+            }
+            else
+            {
+                // User may be using older JDK ( JDK < 1.2 )
+                is = OutputPropertiesFactory.class
+                    .getResourceAsStream(resourceName);
+            }
+
+            bis = new BufferedInputStream(is);
+            props.load(bis);
+        }
+        catch (IOException ioe)
+        {
+            if (defaults == null)
+            {
+                throw ioe;
+            }
+            else
+            {
+                throw new WrappedRuntimeException(
+                    Utils.messages.createMessage(
+                        MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                        new Object[] { resourceName }),
+                    ioe);
+                //"Could not load '"+resourceName+"' (check CLASSPATH), now using just the defaults ", ioe);
+            }
+        }
+        catch (SecurityException se)
+        {
+            // Repeat IOException handling for sandbox/applet case -sc
+            if (defaults == null)
+            {
+                throw se;
+            }
+            else
+            {
+                throw new WrappedRuntimeException(
+                    Utils.messages.createMessage(
+                        MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                        new Object[] { resourceName }),
+                    se);
+                //"Could not load '"+resourceName+"' (check CLASSPATH, applet security), now using just the defaults ", se);
+            }
+        }
+        finally
+        {
+            if (bis != null)
+            {
+                bis.close();
+            }
+            if (is != null)
+            {
+                is.close();
+            }
+        }
+
+        // Note that we're working at the HashTable level here,
+        // and not at the Properties level!  This is important
+        // because we don't want to modify the default properties.
+        // NB: If fixupPropertyString ends up changing the property
+        // name or value, we need to remove the old key and re-add
+        // with the new key and value.  However, then our Enumeration
+        // could lose its place in the HashTable.  So, we first
+        // clone the HashTable and enumerate over that since the
+        // clone will not change.  When we migrate to Collections,
+        // this code should be revisited and cleaned up to use
+        // an Iterator which may (or may not) alleviate the need for
+        // the clone.  Many thanks to Padraig O'hIceadha
+        // <padraig@gradient.ie> for finding this problem.  Bugzilla 2000.
+
+        Enumeration keys = ((Properties) props.clone()).keys();
+        while (keys.hasMoreElements())
+        {
+            String key = (String) keys.nextElement();
+            // Now check if the given key was specified as a
+            // System property. If so, the system property
+            // overides the default value in the propery file.
+            String value = null;
+            try
+            {
+                value = System.getProperty(key);
+            }
+            catch (SecurityException se)
+            {
+                // No-op for sandbox/applet case, leave null -sc
+            }
+            if (value == null)
+                value = (String) props.get(key);
+
+            String newKey = fixupPropertyString(key, true);
+            String newValue = null;
+            try
+            {
+                newValue = System.getProperty(newKey);
+            }
+            catch (SecurityException se)
+            {
+                // No-op for sandbox/applet case, leave null -sc
+            }
+            if (newValue == null)
+                newValue = fixupPropertyString(value, false);
+            else
+                newValue = fixupPropertyString(newValue, false);
+
+            if (key != newKey || value != newValue)
+            {
+                props.remove(key);
+                props.put(newKey, newValue);
+            }
+
+        }
+
+        return props;
+    }
+
+    /**
+     * Fix up a string in an output properties file according to
+     * the rules of {@link #loadPropertiesFile}.
+     *
+     * @param s non-null reference to string that may need to be fixed up.
+     * @return A new string if fixup occured, otherwise the s argument.
+     */
+    static private String fixupPropertyString(String s, boolean doClipping)
+    {
+        int index;
+        if (doClipping && s.startsWith(S_XSLT_PREFIX))
+        {
+            s = s.substring(S_XSLT_PREFIX_LEN);
+        }
+        if (s.startsWith(S_XALAN_PREFIX))
+        {
+            s =
+                S_BUILTIN_EXTENSIONS_UNIVERSAL
+                    + s.substring(S_XALAN_PREFIX_LEN);
+        }
+        if ((index = s.indexOf("\\u003a")) > 0)
+        {
+            String temp = s.substring(index + 6);
+            s = s.substring(0, index) + ":" + temp;
+
+        }
+        return s;
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/OutputPropertyUtils.java b/src/main/java/org/apache/xml/serializer/OutputPropertyUtils.java
new file mode 100644
index 0000000..98b67ba
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/OutputPropertyUtils.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OutputPropertyUtils.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.util.Properties;
+
+/**
+ * This class contains some static methods that act as helpers when parsing a
+ * Java Property object.
+ * 
+ * This class is not a public API. 
+ * It is only public because it is used outside of this package.
+ * 
+ * @see java.util.Properties
+ * @xsl.usage internal
+ */
+public final class OutputPropertyUtils
+{
+    /**
+      * Searches for the boolean property with the specified key in the property list.
+      * If the key is not found in this property list, the default property list,
+      * and its defaults, recursively, are then checked. The method returns
+      * <code>false</code> if the property is not found, or if the value is other
+      * than "yes".
+      *
+      * @param   key   the property key.
+      * @param   props   the list of properties that will be searched.
+      * @return  the value in this property list as a boolean value, or false
+      * if null or not "yes".
+      */
+    public static boolean getBooleanProperty(String key, Properties props)
+    {
+
+        String s = props.getProperty(key);
+
+        if (null == s || !s.equals("yes"))
+            return false;
+        else
+            return true;
+    }
+
+    /**
+     * Searches for the int property with the specified key in the property list.
+     * If the key is not found in this property list, the default property list,
+     * and its defaults, recursively, are then checked. The method returns
+     * <code>false</code> if the property is not found, or if the value is other
+     * than "yes".
+     *
+     * @param   key   the property key.
+     * @param   props   the list of properties that will be searched.
+     * @return  the value in this property list as a int value, or 0
+     * if null or not a number.
+     */
+    public static int getIntProperty(String key, Properties props)
+    {
+
+        String s = props.getProperty(key);
+
+        if (null == s)
+            return 0;
+        else
+            return Integer.parseInt(s);
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/SecuritySupport.java b/src/main/java/org/apache/xml/serializer/SecuritySupport.java
new file mode 100644
index 0000000..2779261
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SecuritySupport.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xml/serializer/SecuritySupport12.java b/src/main/java/org/apache/xml/serializer/SecuritySupport12.java
new file mode 100644
index 0000000..a5e7fad
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SecuritySupport12.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport12.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xml/serializer/SerializationHandler.java b/src/main/java/org/apache/xml/serializer/SerializationHandler.java
new file mode 100644
index 0000000..57029e0
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializationHandler.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializationHandler.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+import javax.xml.transform.Transformer;
+
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DeclHandler;
+
+/**
+ * This interface is the one that a serializer implements. It is a group of
+ * other interfaces, such as ExtendedContentHandler, ExtendedLexicalHandler etc.
+ * In addition there are other methods, such as reset().
+ * 
+ * This class is public only because it is used in another package,
+ * it is not a public API.
+ * 
+ * @xsl.usage internal
+ */
+public interface SerializationHandler
+    extends
+        ExtendedContentHandler,
+        ExtendedLexicalHandler,
+        XSLOutputAttributes,
+        DeclHandler,
+        org.xml.sax.DTDHandler,
+        ErrorHandler,
+        DOMSerializer,
+        Serializer
+{
+    /**
+     * Set the SAX Content handler that the serializer sends its output to. This
+     * method only applies to a ToSAXHandler, not to a ToStream serializer.
+     * 
+     * @see Serializer#asContentHandler()
+     * @see ToSAXHandler
+     */
+    public void setContentHandler(ContentHandler ch);
+    
+    public void close();
+
+    /**
+     * Notify that the serializer should take this DOM node as input to be
+     * serialized.
+     * 
+     * @param node the DOM node to be serialized.
+     * @throws IOException
+     */
+    public void serialize(Node node) throws IOException;
+    /**
+     * Turns special character escaping on/off. 
+     * 
+     * Note that characters will
+     * never, even if this option is set to 'true', be escaped within
+     * CDATA sections in output XML documents.
+     * 
+     * @param escape true if escaping is to be set on.
+     */
+    public boolean setEscaping(boolean escape) throws SAXException;
+
+    /**
+     * Set the number of spaces to indent for each indentation level.
+     * @param spaces the number of spaces to indent for each indentation level.
+     */
+    public void setIndentAmount(int spaces);
+
+    /**
+     * Set the transformer associated with the serializer.
+     * @param transformer the transformer associated with the serializer.
+     */
+    public void setTransformer(Transformer transformer);
+    
+    /**
+     * Get the transformer associated with the serializer.
+     * @return Transformer the transformer associated with the serializer.
+     */
+    public Transformer getTransformer();
+
+    /** 
+     * Used only by TransformerSnapshotImpl to restore the serialization 
+     * to a previous state. 
+     * 
+     * @param mappings NamespaceMappings
+     */
+    public void setNamespaceMappings(NamespaceMappings mappings);
+
+    /**
+     * A SerializationHandler accepts SAX-like events, so
+     * it can accumulate attributes or namespace nodes after
+     * a startElement().
+     * <p>
+     * If the SerializationHandler has a Writer or OutputStream, 
+     * a call to this method will flush such accumulated 
+     * events as a closed start tag for an element.
+     * <p>
+     * If the SerializationHandler wraps a ContentHandler,
+     * a call to this method will flush such accumulated
+     * events as a SAX (not SAX-like) calls to
+     * startPrefixMapping() and startElement().
+     * <p>
+     * If one calls endDocument() then one need not call
+     * this method since a call to endDocument() will
+     * do what this method does. However, in some
+     * circumstances, such as with document fragments,
+     * endDocument() is not called and it may be
+     * necessary to call this method to flush
+     * any pending events.
+     * <p> 
+     * For performance reasons this method should not be called
+     * very often. 
+     */
+    public void flushPending() throws SAXException;
+    
+    /**
+     * Default behavior is to expand DTD entities,
+     * that is the initall default value is true.
+     * @param expand true if DTD entities are to be expanded,
+     * false if they are to be left as DTD entity references. 
+     */
+    public void setDTDEntityExpansion(boolean expand);
+    
+}
diff --git a/src/main/java/org/apache/xml/serializer/Serializer.java b/src/main/java/org/apache/xml/serializer/Serializer.java
new file mode 100644
index 0000000..849d39a
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Serializer.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Serializer.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Properties;
+
+import org.xml.sax.ContentHandler;
+
+/**
+ * The Serializer interface is implemented by a serializer to enable users to:
+ * <ul>
+ * <li>get and set streams or writers
+ * <li>configure the serializer with key/value properties
+ * <li>get an org.xml.sax.ContentHandler or a DOMSerializer to provide input to
+ * </ul>
+ *
+ * <p>
+ * Here is an example using the asContentHandler() method:
+ * <pre>
+ * java.util.Properties props = 
+ *   OutputPropertiesFactory.getDefaultMethodProperties(Method.TEXT);
+ * Serializer ser = SerializerFactory.getSerializer(props);
+ * java.io.PrintStream ostream = System.out; 
+ * ser.setOutputStream(ostream);
+ * 
+ * // Provide the SAX input events
+ * ContentHandler handler = ser.asContentHandler();
+ * handler.startDocument();
+ * char[] chars = { 'a', 'b', 'c' };
+ * handler.characters(chars, 0, chars.length);
+ * handler.endDocument();
+ * 
+ * ser.reset(); // get ready to use the serializer for another document
+ *              // of the same output method (TEXT).
+ * </pre>
+ * 
+ * <p>
+ * As an alternate to supplying a series of SAX events as input through the 
+ * ContentHandler interface, the input to serialize may be given as a DOM. 
+ * <p>
+ * For example:
+ * <pre>
+ * org.w3c.dom.Document     inputDoc;
+ * org.apache.xml.serializer.Serializer   ser;
+ * java.io.Writer owriter;
+ * 
+ * java.util.Properties props = 
+ *   OutputPropertiesFactory.getDefaultMethodProperties(Method.XML);
+ * Serializer ser = SerializerFactory.getSerializer(props);
+ * owriter = ...;  // create a writer to serialize the document to
+ * ser.setWriter( owriter );
+ * 
+ * inputDoc = ...; // create the DOM document to be serialized
+ * DOMSerializer dser = ser.asDOMSerializer(); // a DOM will be serialized
+ * dser.serialize(inputDoc); // serialize the DOM, sending output to owriter
+ * 
+ * ser.reset(); // get ready to use the serializer for another document
+ *              // of the same output method.
+ * </pre>
+ * 
+ * This interface is a public API.
+ * 
+ * @see Method
+ * @see OutputPropertiesFactory
+ * @see SerializerFactory
+ * @see DOMSerializer
+ * @see ContentHandler
+ * 
+ * @xsl.usage general
+ */
+public interface Serializer {
+
+    /**
+     * Specifies an output stream to which the document should be
+     * serialized. This method should not be called while the
+     * serializer is in the process of serializing a document.
+     * <p>
+     * The encoding specified in the output {@link Properties} is used, or
+     * if no encoding was specified, the default for the selected
+     * output method.
+     * <p>
+     * Only one of setWriter() or setOutputStream() should be called.
+     *
+     * @param output The output stream
+     */
+    public void setOutputStream(OutputStream output);
+
+    /**
+     * Get the output stream where the events will be serialized to.
+     *
+     * @return reference to the result stream, or null if only a writer was
+     * set.
+     */
+    public OutputStream getOutputStream();
+
+    /**
+     * Specifies a writer to which the document should be serialized.
+     * This method should not be called while the serializer is in
+     * the process of serializing a document.
+     * <p>
+     * The encoding specified for the output {@link Properties} must be
+     * identical to the output format used with the writer.
+     * 
+     * <p>
+     * Only one of setWriter() or setOutputStream() should be called.
+     *
+     * @param writer The output writer stream
+     */
+    public void setWriter(Writer writer);
+
+    /**
+     * Get the character stream where the events will be serialized to.
+     *
+     * @return Reference to the result Writer, or null.
+     */
+    public Writer getWriter();
+
+    /**
+     * Specifies an output format for this serializer. It the
+     * serializer has already been associated with an output format,
+     * it will switch to the new format. This method should not be
+     * called while the serializer is in the process of serializing
+     * a document.
+     * <p>
+     * The standard property keys supported are: "method", "version", "encoding",
+     * "omit-xml-declaration", "standalone", doctype-public",
+     * "doctype-system", "cdata-section-elements", "indent", "media-type". 
+     * These property keys and their values are described in the XSLT recommendation,
+     * see {@link <a href="http://www.w3.org/TR/1999/REC-xslt-19991116"> XSLT 1.0 recommendation</a>}
+     * <p>
+     * The non-standard property keys supported are defined in {@link OutputPropertiesFactory}.
+     *
+     * <p>
+     * This method can be called multiple times before a document is serialized. Each 
+     * time it is called more, or over-riding property values, can be specified. One 
+     * property value that can not be changed is that of the "method" property key.
+     * <p>
+     * The value of the "cdata-section-elements" property key is a whitespace
+     * separated list of elements. If the element is in a namespace then 
+     * value is passed in this format: {uri}localName 
+     * <p>
+     * If the "cdata-section-elements" key is specified on multiple calls
+     * to this method the set of elements specified in the value
+     * is not replaced from one call to the
+     * next, but it is cumulative across the calls.
+     *
+     * @param format The output format to use, as a set of key/value pairs.
+     */
+    public void setOutputFormat(Properties format);
+
+    /**
+     * Returns the output format properties for this serializer.
+     *
+     * @return The output format key/value pairs in use.
+     */
+    public Properties getOutputFormat();
+
+    /**
+     * Return a {@link ContentHandler} interface to provide SAX input to.
+     * Through the returned object the document to be serailized,
+     * as a series of SAX events, can be provided to the serialzier.
+     * If the serializer does not support the {@link ContentHandler}
+     * interface, it will return null.
+     * <p>
+     * In principle only one of asDOMSerializer() or asContentHander() 
+     * should be called.
+     *
+     * @return A {@link ContentHandler} interface into this serializer,
+     *  or null if the serializer is not SAX 2 capable
+     * @throws IOException An I/O exception occured
+     */
+    public ContentHandler asContentHandler() throws IOException;
+
+    /**
+     * Return a {@link DOMSerializer} interface into this serializer.
+     * Through the returned object the document to be serialized,
+     * a DOM, can be provided to the serializer.
+     * If the serializer does not support the {@link DOMSerializer}
+     * interface, it should return null.
+     * <p>
+     * In principle only one of asDOMSerializer() or asContentHander() 
+     * should be called.
+     *
+     * @return A {@link DOMSerializer} interface into this serializer,
+     *  or null if the serializer is not DOM capable
+     * @throws IOException An I/O exception occured
+     */
+    public DOMSerializer asDOMSerializer() throws IOException;
+
+    /**
+     * This method resets the serializer. 
+     * If this method returns true, the
+     * serializer may be used for subsequent serialization of new
+     * documents. It is possible to change the output format and
+     * output stream prior to serializing, or to reuse the existing
+     * output format and output stream or writer.
+     *
+     * @return True if serializer has been reset and can be reused
+     */
+    public boolean reset();
+
+    /**
+     * Return an Object into this serializer to be cast to a DOM3Serializer.
+     * Through the returned object the document to be serialized,
+     * a DOM (Level 3), can be provided to the serializer.
+     * If the serializer does not support casting to a {@link DOM3Serializer}
+     * interface, it should return null.
+     * <p>
+     * In principle only one of asDOM3Serializer() or asContentHander() 
+     * should be called.
+     *
+     * @return An Object to be cast to a DOM3Serializer interface into this serializer,
+     *  or null if the serializer is not DOM capable
+     * @throws IOException An I/O exception occured
+     */
+    public Object asDOM3Serializer() throws IOException;
+}
+
diff --git a/src/main/java/org/apache/xml/serializer/SerializerBase.java b/src/main/java/org/apache/xml/serializer/SerializerBase.java
new file mode 100644
index 0000000..8e7d38b
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializerBase.java
@@ -0,0 +1,1699 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerBase.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Set;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Transformer;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+/**
+ * This class acts as a base class for the XML "serializers"
+ * and the stream serializers.
+ * It contains a number of common fields and methods.
+ * 
+ * @xsl.usage internal
+ */
+public abstract class SerializerBase
+    implements SerializationHandler, SerializerConstants
+{
+    SerializerBase() {
+        return;
+    }
+    
+    /**
+     * The name of the package that this class is in.
+     * <p>
+     * Not a public API.
+     */
+    public static final String PKG_NAME;
+
+    /**
+     * The same as the name of the package that this class is in
+     * except that '.' are replaced with '/'.
+     * <p>
+     * Not a public API.
+     */
+    public static final String PKG_PATH;
+
+    static {
+        String fullyQualifiedName = SerializerBase.class.getName();
+        int lastDot = fullyQualifiedName.lastIndexOf('.');
+        if (lastDot < 0) {
+            PKG_NAME = "";
+        } else {
+            PKG_NAME = fullyQualifiedName.substring(0, lastDot);
+        }
+
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < PKG_NAME.length(); i++) {
+            char ch = PKG_NAME.charAt(i);
+            if (ch == '.')
+                sb.append('/');
+            else
+                sb.append(ch);
+        }
+        PKG_PATH = sb.toString();
+    }
+
+    
+
+    /**
+     * To fire off the end element trace event
+     * @param name Name of element
+     */
+    protected void fireEndElem(String name)
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENDELEMENT,name, (Attributes)null);
+        }     	        	    	
+    }
+
+    /**
+     * Report the characters trace event
+     * @param chars  content of characters
+     * @param start  starting index of characters to output
+     * @param length  number of characters to output
+     */
+    protected void fireCharEvent(char[] chars, int start, int length)
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_CHARACTERS, chars, start,length);
+        }     	        	    	
+    }
+
+    /**
+     * true if we still need to call startDocumentInternal() 
+	 */
+    protected boolean m_needToCallStartDocument = true; 
+
+    /** True if a trailing "]]>" still needs to be written to be
+     * written out. Used to merge adjacent CDATA sections
+     */
+    protected boolean m_cdataTagOpen = false;
+
+    /**
+     * All the attributes of the current element, collected from
+     * startPrefixMapping() calls, or addAddtribute() calls, or 
+     * from the SAX attributes in a startElement() call.
+     */
+    protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
+
+    /**
+     * Tells if we're in an EntityRef event.
+     */
+    protected boolean m_inEntityRef = false;
+
+    /** This flag is set while receiving events from the external DTD */
+    protected boolean m_inExternalDTD = false;
+
+    /**
+     * The System ID for the doc type.
+     */
+    protected String m_doctypeSystem;
+
+    /**
+     * The public ID for the doc type.
+     */
+    protected String m_doctypePublic;
+
+    /**
+     * Flag to tell that we need to add the doctype decl, which we can't do
+     * until the first element is encountered.
+     */
+    boolean m_needToOutputDocTypeDecl = true;
+
+    /**
+     * Tells if we should write the XML declaration.
+     */
+    protected boolean m_shouldNotWriteXMLHeader = false;
+
+    /**
+     * The standalone value for the doctype.
+     */
+    private String m_standalone;
+
+    /**
+     * True if standalone was specified.
+     */
+    protected boolean m_standaloneWasSpecified = false;
+
+    /**
+     * Flag to tell if indenting (pretty-printing) is on.
+     */
+    protected boolean m_doIndent = false;
+    /**
+     * Amount to indent.
+     */
+    protected int m_indentAmount = 0;
+
+    /**
+     * Tells the XML version, for writing out to the XML decl.
+     */
+    protected String m_version = null;
+
+    /**
+     * The mediatype.  Not used right now.
+     */
+    protected String m_mediatype;
+
+    /**
+     * The transformer that was around when this output handler was created (if
+     * any).
+     */
+    private Transformer m_transformer;
+
+    /**
+     * Namespace support, that keeps track of currently defined 
+     * prefix/uri mappings. As processed elements come and go, so do
+     * the associated mappings for that element.
+     */
+    protected NamespaceMappings m_prefixMap;
+    
+    /**
+     * Handle for firing generate events.  This interface may be implemented
+     * by the referenced transformer object.
+     */
+    protected SerializerTrace m_tracer;
+    
+    protected SourceLocator m_sourceLocator;
+    
+
+    /**
+     * The writer to send output to. This field is only used in the ToStream
+     * serializers, but exists here just so that the fireStartDoc() and
+     * other fire... methods can flush this writer when tracing.
+     */
+    protected java.io.Writer m_writer = null;
+    
+    /**
+     * A reference to "stack frame" corresponding to
+     * the current element. Such a frame is pushed at a startElement()
+     * and popped at an endElement(). This frame contains information about
+     * the element, such as its namespace URI. 
+     */
+    protected ElemContext m_elemContext = new ElemContext();
+    
+    /**
+     * A utility buffer for converting Strings passed to
+     * character() methods to character arrays.
+     * Reusing this buffer means not creating a new character array
+     * everytime and it runs faster.
+     */
+    protected char[] m_charsBuff = new char[60];
+    
+    /**
+     * A utility buffer for converting Strings passed to
+     * attribute methods to character arrays.
+     * Reusing this buffer means not creating a new character array
+     * everytime and it runs faster.
+     */
+    protected char[] m_attrBuff = new char[30];    
+
+    /**
+     * Receive notification of a comment.
+     * 
+     * @see ExtendedLexicalHandler#comment(String)
+     */
+    public void comment(String data) throws SAXException
+    {
+        m_docIsEmpty = false;
+        
+        final int length = data.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length * 2 + 1];
+        }
+        data.getChars(0, length, m_charsBuff, 0);
+        comment(m_charsBuff, 0, length);
+    }
+
+    /**
+     * If at runtime, when the qname of the attribute is
+     * known, another prefix is specified for the attribute, then we can
+     * patch or hack the name with this method. For
+     * a qname of the form "ns?:otherprefix:name", this function patches the
+     * qname by simply ignoring "otherprefix".
+     * TODO: This method is a HACK! We do not have access to the
+     * XML file, it sometimes generates a NS prefix of the form "ns?" for
+     * an attribute.
+     */
+    protected String patchName(String qname)
+    {
+
+        
+        final int lastColon = qname.lastIndexOf(':');
+
+        if (lastColon > 0) {
+            final int firstColon = qname.indexOf(':');
+            final String prefix = qname.substring(0, firstColon);
+            final String localName = qname.substring(lastColon + 1);
+
+        // If uri is "" then ignore prefix
+            final String uri = m_prefixMap.lookupNamespace(prefix);
+            if (uri != null && uri.length() == 0) {
+                return localName;
+            }
+            else if (firstColon != lastColon) {
+                return prefix + ':' + localName;
+            }
+        }
+        return qname;        
+    }
+
+    /**
+     * Returns the local name of a qualified name. If the name has no prefix,
+     * then it works as the identity (SAX2).
+     * @param qname the qualified name 
+     * @return the name, but excluding any prefix and colon.
+     */
+    protected static String getLocalName(String qname)
+    {
+        final int col = qname.lastIndexOf(':');
+        return (col > 0) ? qname.substring(col + 1) : qname;
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     *
+     * @param locator An object that can return the location of any SAX document
+     * event.
+     * 
+     * Receive an object for locating the origin of SAX document events.
+     *
+     * <p>SAX parsers are strongly encouraged (though not absolutely
+     * required) to supply a locator: if it does so, it must supply
+     * the locator to the application by invoking this method before
+     * invoking any of the other methods in the DocumentHandler
+     * interface.</p>
+     *
+     * <p>The locator allows the application to determine the end
+     * position of any document-related event, even if the parser is
+     * not reporting an error.  Typically, the application will
+     * use this information for reporting its own errors (such as
+     * character content that does not match an application's
+     * business rules).  The information returned by the locator
+     * is probably not sufficient for use with a search engine.</p>
+     *
+     * <p>Note that the locator will return correct information only
+     * during the invocation of the events in this interface.  The
+     * application should not attempt to use it at any other time.</p>
+     */
+    public void setDocumentLocator(Locator locator)
+    {
+        return;
+
+        // I don't do anything with this yet.
+    }
+
+    /**
+     * Adds the given attribute to the set of collected attributes , but only if
+     * there is a currently open element.
+     * 
+     * An element is currently open if a startElement() notification has
+     * occured but the start of the element has not yet been written to the
+     * output.  In the stream case this means that we have not yet been forced
+     * to close the elements opening tag by another notification, such as a
+     * character notification.
+     * 
+     * @param uri the URI of the attribute
+     * @param localName the local name of the attribute
+     * @param rawName    the qualified name of the attribute
+     * @param type the type of the attribute (probably CDATA)
+     * @param value the value of the attribute
+     * @param XSLAttribute true if this attribute is coming from an xsl:attriute element
+     * @see ExtendedContentHandler#addAttribute(String, String, String, String, String)
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+        throws SAXException
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            addAttributeAlways(uri, localName, rawName, type, value, XSLAttribute);
+        }
+
+    }
+    
+    /**
+     * Adds the given attribute to the set of attributes, even if there is
+     * no currently open element. This is useful if a SAX startPrefixMapping()
+     * should need to add an attribute before the element name is seen.
+     * 
+     * @param uri the URI of the attribute
+     * @param localName the local name of the attribute
+     * @param rawName   the qualified name of the attribute
+     * @param type the type of the attribute (probably CDATA)
+     * @param value the value of the attribute
+     * @param XSLAttribute true if this attribute is coming from an xsl:attribute element
+     * @return true if the attribute was added, 
+     * false if an existing value was replaced.
+     */
+    public boolean addAttributeAlways(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+    {
+        boolean was_added;
+//            final int index =
+//                (localName == null || uri == null) ?
+//                m_attributes.getIndex(rawName):m_attributes.getIndex(uri, localName);        
+            int index;
+//            if (localName == null || uri == null){
+//                index = m_attributes.getIndex(rawName);
+//            }
+//            else {
+//                index = m_attributes.getIndex(uri, localName);
+//            }
+            if (localName == null || uri == null || uri.length() == 0)
+                index = m_attributes.getIndex(rawName);
+            else {
+                index = m_attributes.getIndex(uri,localName);
+            }
+            if (index >= 0)
+            {
+                /* We've seen the attribute before.
+                 * We may have a null uri or localName, but all
+                 * we really want to re-set is the value anyway.
+                 */
+                m_attributes.setValue(index,value);
+                was_added = false;
+            }
+            else
+            {
+                // the attribute doesn't exist yet, create it
+                m_attributes.addAttribute(uri, localName, rawName, type, value);
+                was_added = true;
+            }
+            return was_added;
+        
+    }
+  
+
+    /**
+     *  Adds  the given attribute to the set of collected attributes, 
+     * but only if there is a currently open element.
+     *
+     * @param name the attribute's qualified name
+     * @param value the value of the attribute
+     */
+    public void addAttribute(String name, final String value)
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            final String patchedName = patchName(name);
+            final String localName = getLocalName(patchedName);
+            final String uri = getNamespaceURI(patchedName, false);
+
+            addAttributeAlways(uri,localName, patchedName, "CDATA", value, false);
+         }
+    }    
+
+    /**
+     * Adds the given xsl:attribute to the set of collected attributes, 
+     * but only if there is a currently open element.
+     *
+     * @param name the attribute's qualified name (prefix:localName)
+     * @param value the value of the attribute
+     * @param uri the URI that the prefix of the name points to
+     */
+    public void addXSLAttribute(String name, final String value, final String uri)
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            final String patchedName = patchName(name);
+            final String localName = getLocalName(patchedName);
+
+            addAttributeAlways(uri,localName, patchedName, "CDATA", value, true);
+         }
+    } 
+
+    /**
+     * Add the given attributes to the currently collected ones. These
+     * attributes are always added, regardless of whether on not an element
+     * is currently open.
+     * @param atts List of attributes to add to this list
+     */
+    public void addAttributes(Attributes atts) throws SAXException
+    {
+
+        int nAtts = atts.getLength();
+
+        for (int i = 0; i < nAtts; i++)
+        {
+            String uri = atts.getURI(i);
+
+            if (null == uri)
+                uri = "";
+
+            addAttributeAlways(
+                uri,
+                atts.getLocalName(i),
+                atts.getQName(i),
+                atts.getType(i),
+                atts.getValue(i),
+                false);
+
+        }
+    }
+
+    /**
+     * Return a {@link ContentHandler} interface into this serializer.
+     * If the serializer does not support the {@link ContentHandler}
+     * interface, it should return null.
+     *
+     * @return A {@link ContentHandler} interface into this serializer,
+     *  or null if the serializer is not SAX 2 capable
+     * @throws IOException An I/O exception occured
+     */
+    public ContentHandler asContentHandler() throws IOException
+    {
+        return this;
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     * @see #startEntity
+     */
+    public void endEntity(String name) throws org.xml.sax.SAXException
+    {
+        if (name.equals("[dtd]"))
+            m_inExternalDTD = false;
+        m_inEntityRef = false;
+
+        if (m_tracer != null)
+            this.fireEndEntity(name);        
+    }
+
+    /**
+     * Flush and close the underlying java.io.Writer. This method applies to
+     * ToStream serializers, not ToSAXHandler serializers.
+     * @see ToStream
+     */
+    public void close()
+    {
+        // do nothing (base behavior)
+    }
+
+    /**
+     * Initialize global variables
+     */
+    protected void initCDATA()
+    {
+        // CDATA stack
+        //        _cdataStack = new Stack();
+        //        _cdataStack.push(new Integer(-1)); // push dummy value
+    }
+
+    /**
+     * Returns the character encoding to be used in the output document.
+     * @return the character encoding to be used in the output document.
+     */
+    public String getEncoding()
+    {
+        return getOutputProperty(OutputKeys.ENCODING);
+    }
+
+   /**
+     * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
+     * @param m_encoding the character encoding
+     */
+    public void setEncoding(String encoding)
+    {
+        setOutputProperty(OutputKeys.ENCODING,encoding);
+    }
+
+    /**
+     * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
+     * @param b true if the XML declaration is to be omitted from the output
+     * document.
+     */
+    public void setOmitXMLDeclaration(boolean b)
+    {
+        String val = b ? "yes":"no";
+        setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,val);
+    }
+
+
+    /**
+     * @return true if the XML declaration is to be omitted from the output
+     * document.
+     */
+    public boolean getOmitXMLDeclaration()
+    {
+        return m_shouldNotWriteXMLHeader;
+    }
+
+    /**
+     * Returns the previously set value of the value to be used as the public
+     * identifier in the document type declaration (DTD).
+     * 
+     *@return the public identifier to be used in the DOCTYPE declaration in the
+     * output document.
+     */    
+    public String getDoctypePublic()
+    {
+        return m_doctypePublic;
+    }
+
+    /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
+      * @param doctypePublic the public identifier to be used in the DOCTYPE
+      * declaration in the output document.
+      */
+    public void setDoctypePublic(String doctypePublic)
+    {
+        setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
+    }
+
+
+    /**
+     * Returns the previously set value of the value to be used
+     * as the system identifier in the document type declaration (DTD).
+	 * @return the system identifier to be used in the DOCTYPE declaration in
+	 * the output document.
+     *
+     */    
+    public String getDoctypeSystem()
+    {
+        return m_doctypeSystem;
+    }
+
+    /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
+      * @param doctypeSystem the system identifier to be used in the DOCTYPE
+      * declaration in the output document.
+      */
+    public void setDoctypeSystem(String doctypeSystem)
+    {
+        setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
+    }
+
+    /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
+     * @param doctypeSystem the system identifier to be used in the DOCTYPE
+     * declaration in the output document.
+     * @param doctypePublic the public identifier to be used in the DOCTYPE
+     * declaration in the output document.
+     */
+    public void setDoctype(String doctypeSystem, String doctypePublic)
+    {
+        setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
+        setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
+    }
+
+    /**
+     * Sets the value coming from the xsl:output standalone stylesheet attribute.
+     * @param standalone a value of "yes" indicates that the
+     * <code>standalone</code> delaration is to be included in the output
+     * document. This method remembers if the value was explicitly set using
+     * this method, verses if the value is the default value.
+     */
+    public void setStandalone(String standalone)
+    {
+        setOutputProperty(OutputKeys.STANDALONE, standalone);
+    }
+    /**
+     * Sets the XSL standalone attribute, but does not remember if this is a
+     * default or explicite setting.
+     * @param standalone "yes" | "no"
+     */    
+    protected void setStandaloneInternal(String standalone)
+    {
+        if ("yes".equals(standalone))
+            m_standalone = "yes";
+        else
+            m_standalone = "no";
+        
+    }
+
+    /**
+     * Gets the XSL standalone attribute
+     * @return a value of "yes" if the <code>standalone</code> delaration is to
+     * be included in the output document.
+     *  @see XSLOutputAttributes#getStandalone()
+     */
+    public String getStandalone()
+    {
+        return m_standalone;
+    }
+
+    /**
+     * @return true if the output document should be indented to visually
+     * indicate its structure.
+     */
+    public boolean getIndent()
+    {
+        return m_doIndent;
+    }
+    /**
+     * Gets the mediatype the media-type or MIME type associated with the output
+     * document.
+     * @return the mediatype the media-type or MIME type associated with the
+     * output document.
+     */
+    public String getMediaType()
+    {
+        return m_mediatype;
+    }
+
+    /**
+     * Gets the version of the output format.
+     * @return the version of the output format.
+     */
+    public String getVersion()
+    {
+        return m_version;
+    }
+
+    /**
+     * Sets the value coming from the xsl:output version attribute.
+     * @param version the version of the output format.
+     * @see SerializationHandler#setVersion(String)
+     */
+    public void setVersion(String version)
+    {
+        setOutputProperty(OutputKeys.VERSION, version);
+    }
+
+    /**
+     * Sets the value coming from the xsl:output media-type stylesheet attribute.
+     * @param mediaType the non-null media-type or MIME type associated with the
+     * output document.
+     * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
+     * @see SerializationHandler#setMediaType(String)
+     */
+    public void setMediaType(String mediaType)
+    {
+        setOutputProperty(OutputKeys.MEDIA_TYPE,mediaType);
+    }
+
+    /**
+     * @return the number of spaces to indent for each indentation level.
+     */
+    public int getIndentAmount()
+    {
+        return m_indentAmount;
+    }
+
+    /**
+     * Sets the indentation amount.
+     * @param m_indentAmount The m_indentAmount to set
+     */
+    public void setIndentAmount(int m_indentAmount)
+    {
+        this.m_indentAmount = m_indentAmount;
+    }
+
+    /**
+     * Sets the value coming from the xsl:output indent stylesheet
+     * attribute.
+     * @param doIndent true if the output document should be indented to
+     * visually indicate its structure.
+     * @see XSLOutputAttributes#setIndent(boolean)
+     */
+    public void setIndent(boolean doIndent)
+    {
+        String val = doIndent ? "yes":"no";
+        setOutputProperty(OutputKeys.INDENT,val);
+    }
+
+    /**
+     * This method is used when a prefix/uri namespace mapping
+     * is indicated after the element was started with a 
+     * startElement() and before and endElement().
+     * startPrefixMapping(prefix,uri) would be used before the
+     * startElement() call.
+     * @param uri the URI of the namespace
+     * @param prefix the prefix associated with the given URI.
+     * 
+     * @see ExtendedContentHandler#namespaceAfterStartElement(String, String)
+     */
+    public void namespaceAfterStartElement(String uri, String prefix)
+        throws SAXException
+    {
+        // default behavior is to do nothing
+    }
+
+    /**
+     * Return a {@link DOMSerializer} interface into this serializer. If the
+     * serializer does not support the {@link DOMSerializer} interface, it should
+     * return null.
+     *
+     * @return A {@link DOMSerializer} interface into this serializer,  or null
+     * if the serializer is not DOM capable
+     * @throws IOException An I/O exception occured
+     * @see Serializer#asDOMSerializer()
+     */
+    public DOMSerializer asDOMSerializer() throws IOException
+    { 
+        return this;
+    }
+
+    /**
+     * Tell if two strings are equal, without worry if the first string is null.
+     *
+     * @param p String reference, which may be null.
+     * @param t String reference, which may be null.
+     *
+     * @return true if strings are equal.
+     */
+    private static final boolean subPartMatch(String p, String t)
+    {
+        return (p == t) || ((null != p) && (p.equals(t)));
+    }
+
+    /**
+     * Returns the local name of a qualified name. 
+     * If the name has no prefix,
+     * then it works as the identity (SAX2). 
+     * 
+     * @param qname a qualified name
+     * @return returns the prefix of the qualified name,
+     * or null if there is no prefix.
+     */
+    protected static final String getPrefixPart(String qname)
+    {
+        final int col = qname.indexOf(':');
+        return (col > 0) ? qname.substring(0, col) : null;
+        //return (col > 0) ? qname.substring(0,col) : "";
+    }
+
+    /**
+     * Some users of the serializer may need the current namespace mappings
+     * @return the current namespace mappings (prefix/uri)
+     * @see ExtendedContentHandler#getNamespaceMappings()
+     */
+    public NamespaceMappings getNamespaceMappings()
+    {
+        return m_prefixMap;
+    }
+
+    /**
+     * Returns the prefix currently pointing to the given URI (if any).
+     * @param namespaceURI the uri of the namespace in question
+     * @return a prefix pointing to the given URI (if any).
+     * @see ExtendedContentHandler#getPrefix(String)
+     */
+    public String getPrefix(String namespaceURI)
+    {
+        String prefix = m_prefixMap.lookupPrefix(namespaceURI);
+        return prefix;
+    }
+
+    /**
+     * Returns the URI of an element or attribute. Note that default namespaces
+     * do not apply directly to attributes.
+     * @param qname a qualified name
+     * @param isElement true if the qualified name is the name of 
+     * an element.
+     * @return returns the namespace URI associated with the qualified name.
+     */
+    public String getNamespaceURI(String qname, boolean isElement)
+    {
+        String uri = EMPTYSTRING;
+        int col = qname.lastIndexOf(':');
+        final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
+
+        if (!EMPTYSTRING.equals(prefix) || isElement)
+        {
+            if (m_prefixMap != null)
+            {
+                uri = m_prefixMap.lookupNamespace(prefix);
+                if (uri == null && !prefix.equals(XMLNS_PREFIX))
+                {
+                    throw new RuntimeException(
+                        Utils.messages.createMessage(
+                            MsgKey.ER_NAMESPACE_PREFIX,
+                            new Object[] { qname.substring(0, col) }  ));
+                }
+            }
+        }
+        return uri;
+    }
+
+    /**
+     * Returns the URI of prefix (if any)
+     * 
+	 * @param prefix the prefix whose URI is searched for
+     * @return the namespace URI currently associated with the
+     * prefix, null if the prefix is undefined.
+     */
+    public String getNamespaceURIFromPrefix(String prefix)
+    {
+        String uri = null;
+        if (m_prefixMap != null)
+            uri = m_prefixMap.lookupNamespace(prefix);
+        return uri;
+    }
+
+    /**
+     * Entity reference event.
+     *
+     * @param name Name of entity
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void entityReference(String name) throws org.xml.sax.SAXException
+    {
+
+        flushPending();
+
+        startEntity(name);
+        endEntity(name);
+
+        if (m_tracer != null)
+		    fireEntityReference(name);
+    }
+
+    /**
+     * Sets the transformer associated with this serializer
+     * @param t the transformer associated with this serializer.
+     * @see SerializationHandler#setTransformer(Transformer)
+     */
+    public void setTransformer(Transformer t)
+    {
+        m_transformer = t;
+        
+        // If this transformer object implements the SerializerTrace interface
+        // then assign m_tracer to the transformer object so it can be used
+        // to fire trace events.
+        if ((m_transformer instanceof SerializerTrace) &&
+            (((SerializerTrace) m_transformer).hasTraceListeners())) {
+           m_tracer = (SerializerTrace) m_transformer;
+        } else {
+           m_tracer = null;
+        }
+    }
+    /**
+     * Gets the transformer associated with this serializer
+     * @return returns the transformer associated with this serializer.
+     * @see SerializationHandler#getTransformer()
+     */
+    public Transformer getTransformer()
+    {
+        return m_transformer;
+    }
+    
+    /**
+     * This method gets the nodes value as a String and uses that String as if
+     * it were an input character notification.
+     * @param node the Node to serialize
+     * @throws org.xml.sax.SAXException
+     */
+    public void characters(org.w3c.dom.Node node)
+        throws org.xml.sax.SAXException
+    {
+        flushPending();
+        String data = node.getNodeValue();
+        if (data != null)
+        {
+            final int length = data.length();
+            if (length > m_charsBuff.length)
+            {
+                m_charsBuff = new char[length * 2 + 1];
+            }
+            data.getChars(0, length, m_charsBuff, 0);
+            characters(m_charsBuff, 0, length);
+        }
+    }
+    
+
+    /**
+     * @see org.xml.sax.ErrorHandler#error(SAXParseException)
+     */
+    public void error(SAXParseException exc) throws SAXException {
+    }
+
+    /**
+     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
+     */
+    public void fatalError(SAXParseException exc) throws SAXException {
+        
+      m_elemContext.m_startTagOpen = false;
+
+    }
+
+    /**
+     * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
+     */
+    public void warning(SAXParseException exc) throws SAXException 
+    {
+    }
+
+    /**
+     * To fire off start entity trace event
+     * @param name Name of entity
+     */
+    protected void fireStartEntity(String name)
+        throws org.xml.sax.SAXException
+    {        
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENTITYREF, name);
+        }     	        	    	
+    }
+
+    /**
+     * Report the characters event
+     * @param chars  content of characters
+     * @param start  starting index of characters to output
+     * @param length  number of characters to output
+     */
+//    protected void fireCharEvent(char[] chars, int start, int length)
+//        throws org.xml.sax.SAXException
+//    {
+//        if (m_tracer != null)
+//            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_CHARACTERS, chars, start,length);     	        	    	
+//    }
+//        
+
+    /**
+     * This method is only used internally when flushing the writer from the
+     * various fire...() trace events.  Due to the writer being wrapped with 
+     * SerializerTraceWriter it may cause the flush of these trace events:
+     * EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS 
+     * EVENTTYPE_OUTPUT_CHARACTERS
+     * which trace the output written to the output stream.
+     * 
+     */
+    private void flushMyWriter()
+    {
+        if (m_writer != null)
+        {
+            try
+            {
+                m_writer.flush();
+            }
+            catch(IOException ioe)
+            {
+            
+            }
+        }
+    }
+    /**
+     * Report the CDATA trace event
+     * @param chars  content of CDATA
+     * @param start  starting index of characters to output
+     * @param length  number of characters to output
+     */
+    protected void fireCDATAEvent(char[] chars, int start, int length)
+        throws org.xml.sax.SAXException
+    {
+		if (m_tracer != null)
+        {
+            flushMyWriter();
+			m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_CDATA, chars, start,length);
+        }     	        	    	
+    }
+
+    /**
+     * Report the comment trace event
+     * @param chars  content of comment
+     * @param start  starting index of comment to output
+     * @param length  number of characters to output
+     */
+    protected void fireCommentEvent(char[] chars, int start, int length)
+        throws org.xml.sax.SAXException
+    {
+		if (m_tracer != null)
+        {
+            flushMyWriter();
+			m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_COMMENT, new String(chars, start, length));
+        }     	        	    	
+    }
+
+
+    /**
+     * To fire off end entity trace event
+     * @param name Name of entity
+     */
+    public void fireEndEntity(String name)
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+            flushMyWriter();
+    	// we do not need to handle this.
+    }    
+
+    /**
+     * To fire off start document trace  event
+     */
+     protected void fireStartDoc()
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_STARTDOCUMENT);
+        }     	    
+    }    
+
+
+    /**
+     * To fire off end document trace event
+     */
+    protected void fireEndDoc()
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENDDOCUMENT);
+        }     	        	
+    }    
+    
+    /**
+     * Report the start element trace event. This trace method needs to be
+     * called just before the attributes are cleared.
+     * 
+     * @param elemName the qualified name of the element
+     * 
+     */
+    protected void fireStartElem(String elemName)
+        throws org.xml.sax.SAXException
+    {        
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_STARTELEMENT,
+                elemName, m_attributes);     	 
+        }       	
+    }    
+
+
+    /**
+     * To fire off the end element event
+     * @param name Name of element
+     */
+//    protected void fireEndElem(String name)
+//        throws org.xml.sax.SAXException
+//    {
+//        if (m_tracer != null)
+//            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENDELEMENT,name, (Attributes)null);     	        	    	
+//    }    
+
+
+    /**
+     * To fire off the PI trace event
+     * @param name Name of PI
+     */
+    protected void fireEscapingEvent(String name, String data)
+        throws org.xml.sax.SAXException
+    {
+
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_PI,name, data);
+        }     	        	    	
+    }    
+
+
+    /**
+     * To fire off the entity reference trace event
+     * @param name Name of entity reference
+     */
+    protected void fireEntityReference(String name)
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+        {
+            flushMyWriter();
+            m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENTITYREF,name, (Attributes)null);
+        }     	        	    	
+    }    
+
+    /**
+     * Receive notification of the beginning of a document.
+     * This method is never a self generated call, 
+     * but only called externally.
+     *
+     * <p>The SAX parser will invoke this method only once, before any
+     * other methods in this interface or in DTDHandler (except for
+     * setDocumentLocator).</p>
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void startDocument() throws org.xml.sax.SAXException
+    {
+
+        // if we do get called with startDocument(), handle it right away       
+        startDocumentInternal();
+        m_needToCallStartDocument = false;
+        return;
+    }   
+    
+    /**
+     * This method handles what needs to be done at a startDocument() call,
+     * whether from an external caller, or internally called in the 
+     * serializer.  For historical reasons the serializer is flexible to
+     * startDocument() not always being called.
+     * Even if no external call is
+     * made into startDocument() this method will always be called as a self
+     * generated internal startDocument, it handles what needs to be done at a
+     * startDocument() call.
+     * 
+     * This method exists just to make sure that startDocument() is only ever
+     * called from an external caller, which in principle is just a matter of
+     * style.
+     * 
+     * @throws SAXException
+     */
+    protected void startDocumentInternal() throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+            this.fireStartDoc();
+    } 
+    /**
+     * This method is used to set the source locator, which might be used to
+     * generated an error message.
+     * @param locator the source locator
+     *
+     * @see ExtendedContentHandler#setSourceLocator(javax.xml.transform.SourceLocator)
+     */
+    public void setSourceLocator(SourceLocator locator)
+    {
+        m_sourceLocator = locator;    
+    }
+
+    
+    /** 
+     * Used only by TransformerSnapshotImpl to restore the serialization 
+     * to a previous state. 
+     * 
+     * @param mappings NamespaceMappings
+     */
+    public void setNamespaceMappings(NamespaceMappings mappings) {
+        m_prefixMap = mappings;
+    }
+    
+    public boolean reset()
+    {
+    	resetSerializerBase();
+    	return true;
+    }
+    
+    /**
+     * Reset all of the fields owned by SerializerBase
+     *
+     */
+    private void resetSerializerBase()
+    {
+    	this.m_attributes.clear();
+        this.m_CdataElems = null;
+        this.m_cdataTagOpen = false;
+        this.m_docIsEmpty = true;
+    	this.m_doctypePublic = null;
+    	this.m_doctypeSystem = null;
+    	this.m_doIndent = false;
+        this.m_elemContext = new ElemContext();
+    	this.m_indentAmount = 0;
+    	this.m_inEntityRef = false;
+    	this.m_inExternalDTD = false;
+    	this.m_mediatype = null;
+    	this.m_needToCallStartDocument = true;
+    	this.m_needToOutputDocTypeDecl = false;
+        if (m_OutputProps != null)
+            this.m_OutputProps.clear();
+        if (m_OutputPropsDefault != null)
+            this.m_OutputPropsDefault.clear();
+        if (this.m_prefixMap != null)
+    	    this.m_prefixMap.reset();
+    	this.m_shouldNotWriteXMLHeader = false;
+    	this.m_sourceLocator = null;
+    	this.m_standalone = null;
+    	this.m_standaloneWasSpecified = false;
+        this.m_StringOfCDATASections = null;
+    	this.m_tracer = null;
+    	this.m_transformer = null;
+    	this.m_version = null;
+    	// don't set writer to null, so that it might be re-used
+    	//this.m_writer = null;
+    }
+    
+    /**
+     * Returns true if the serializer is used for temporary output rather than
+     * final output.
+     * 
+     * This concept is made clear in the XSLT 2.0 draft.
+     */
+    final boolean inTemporaryOutputState() 
+    {
+        /* This is a hack. We should really be letting the serializer know
+         * that it is in temporary output state with an explicit call, but
+         * from a pragmatic point of view (for now anyways) having no output
+         * encoding at all, not even the default UTF-8 indicates that the serializer
+         * is being used for temporary RTF.
+         */ 
+        return (getEncoding() == null);
+        
+    }
+    
+    /**
+     * This method adds an attribute the the current element,
+     * but should not be used for an xsl:attribute child.
+     * @see ExtendedContentHandler#addAttribute(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void addAttribute(String uri, String localName, String rawName, String type, String value) throws SAXException 
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            addAttributeAlways(uri, localName, rawName, type, value, false);
+        }
+    }
+    
+    /**
+     * @see org.xml.sax.DTDHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void notationDecl(String arg0, String arg1, String arg2)
+        throws SAXException {
+        // This method just provides a definition to satisfy the interface
+        // A particular sub-class of SerializerBase provides the implementation (if desired)        
+    }
+
+    /**
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void unparsedEntityDecl(
+        String arg0,
+        String arg1,
+        String arg2,
+        String arg3)
+        throws SAXException {
+        // This method just provides a definition to satisfy the interface
+        // A particular sub-class of SerializerBase provides the implementation (if desired)        
+    }
+
+    /**
+     * If set to false the serializer does not expand DTD entities,
+     * but leaves them as is, the default value is true.
+     */
+    public void setDTDEntityExpansion(boolean expand) {
+        // This method just provides a definition to satisfy the interface
+        // A particular sub-class of SerializerBase provides the implementation (if desired)        
+    }
+ 
+
+    /** 
+     * The CDATA section names stored in a whitespace separateed list with
+     * each element being a word of the form "{uri}localName" This list
+     * comes from the cdata-section-elements attribute.
+     * 
+     * This field replaces m_cdataSectionElements Vector.
+     */
+    protected String m_StringOfCDATASections = null; 
+    
+    boolean m_docIsEmpty = true;
+    void initCdataElems(String s)
+    {
+        if (s != null)
+        {            
+            int max = s.length();
+
+            // true if we are in the middle of a pair of curly braces that delimit a URI
+            boolean inCurly = false;
+
+            // true if we found a URI but haven't yet processed the local name 
+            boolean foundURI = false;
+
+            StringBuffer buf = new StringBuffer();
+            String uri = null;
+            String localName = null;
+
+            // parse through string, breaking on whitespaces.  I do this instead
+            // of a tokenizer so I can track whitespace inside of curly brackets,
+            // which theoretically shouldn't happen if they contain legal URLs.
+
+
+            for (int i = 0; i < max; i++)
+            {
+
+                char c = s.charAt(i);
+
+                if (Character.isWhitespace(c))
+                {
+                    if (!inCurly)
+                    {
+                        if (buf.length() > 0)
+                        {
+                            localName = buf.toString();
+                            if (!foundURI)
+                                uri = "";
+                            addCDATAElement(uri,localName);
+                            buf.setLength(0);
+                            foundURI = false;
+                        }
+                        continue;
+                    }
+                    else
+                        buf.append(c); // add whitespace to the URI
+                }
+                else if ('{' == c) // starting a URI
+                    inCurly = true;
+                else if ('}' == c)
+                {
+                    // we just ended a URI, add the URI to the vector
+                    foundURI = true;
+                    uri = buf.toString();
+                    buf.setLength(0);
+                    inCurly = false;
+                }
+                else
+                {
+                    // append non-whitespace, non-curly to current URI or localName being gathered.                    
+                    buf.append(c);
+                }
+
+            }
+
+            if (buf.length() > 0)
+            {
+                // We have one last localName to process.
+                localName = buf.toString();
+                if (!foundURI)
+                    uri = "";
+                addCDATAElement(uri,localName);
+            }
+        }
+    }
+    protected java.util.Hashtable m_CdataElems = null;
+    private void addCDATAElement(String uri, String localName) 
+    {
+        if (m_CdataElems == null) {
+            m_CdataElems = new java.util.Hashtable();
+        }
+        
+        java.util.Hashtable h = (java.util.Hashtable) m_CdataElems.get(localName);
+        if (h == null) {
+            h = new java.util.Hashtable();
+            m_CdataElems.put(localName,h);
+        }
+        h.put(uri,uri);
+        
+    }
+    
+    
+    /**
+     * Return true if nothing has been sent to this result tree yet.
+     * <p>
+     * This is not a public API.
+     * 
+     * @xsl.usage internal
+     */
+    public boolean documentIsEmpty() {
+        // If we haven't called startDocument() yet, then this document is empty
+        return m_docIsEmpty && (m_elemContext.m_currentElemDepth == 0);
+    }    
+    
+    /**
+     * Return true if the current element in m_elemContext
+     * is a CDATA section.
+     * CDATA sections are specified in the <xsl:output> attribute
+     * cdata-section-names or in the JAXP equivalent property.
+     * In any case the format of the value of such a property is:
+     * <pre>
+     * "{uri1}localName1 {uri2}localName2 . . . "
+     * </pre>
+     * 
+     * <p>
+     * This method is not a public API, but is only used internally by the serializer.
+     */
+    protected boolean isCdataSection()
+    {
+
+        boolean b = false;
+
+        if (null != m_StringOfCDATASections)
+        {
+            if (m_elemContext.m_elementLocalName == null) 
+            {
+                String localName =  getLocalName(m_elemContext.m_elementName); 
+                m_elemContext.m_elementLocalName = localName;                   
+            }
+            
+            if ( m_elemContext.m_elementURI == null) {
+                
+                m_elemContext.m_elementURI = getElementURI();
+            }
+            else if ( m_elemContext.m_elementURI.length() == 0) {
+                if ( m_elemContext.m_elementName == null) {
+                    m_elemContext.m_elementName = m_elemContext.m_elementLocalName;    
+                    // leave URI as "", meaning in no namespace
+                }
+                else if (m_elemContext.m_elementLocalName.length() < m_elemContext.m_elementName.length()){
+                    // We were told the URI was "", yet the name has a prefix since the name is longer than the localname.
+                    // So we will fix that incorrect information here.
+                    m_elemContext.m_elementURI = getElementURI();  
+                }
+            }
+
+            java.util.Hashtable h = (java.util.Hashtable) m_CdataElems.get(m_elemContext.m_elementLocalName);
+            if (h != null) 
+            {
+                Object obj = h.get(m_elemContext.m_elementURI);
+                if (obj != null)
+                    b = true; 
+            }
+
+        }
+        return b;
+    }
+    
+    /**
+     * Before this call m_elementContext.m_elementURI is null,
+     * which means it is not yet known. After this call it
+     * is non-null, but possibly "" meaning that it is in the
+     * default namespace.
+     * 
+     * @return The URI of the element, never null, but possibly "".
+     */
+    private String getElementURI() {
+        String uri = null;
+        // At this point in processing we have received all the
+        // namespace mappings
+        // As we still don't know the elements namespace,
+        // we now figure it out.
+
+        String prefix = getPrefixPart(m_elemContext.m_elementName);
+
+        if (prefix == null) {
+            // no prefix so lookup the URI of the default namespace
+            uri = m_prefixMap.lookupNamespace("");
+        } else {
+            uri = m_prefixMap.lookupNamespace(prefix);
+        }
+        if (uri == null) {
+            // We didn't find the namespace for the
+            // prefix ... ouch, that shouldn't happen.
+            // This is a hack, we really don't know
+            // the namespace
+            uri = EMPTYSTRING;
+        }
+
+        return uri;
+    }
+    
+
+    /**
+     * Get the value of an output property,
+     * the explicit value, if any, otherwise the
+     * default value, if any, otherwise null.
+     */
+    public String getOutputProperty(String name) {
+        String val = getOutputPropertyNonDefault(name);
+        // If no explicit value, try to get the default value
+        if (val == null)
+            val = getOutputPropertyDefault(name);
+        return val;
+        
+    }
+    /**
+     * Get the value of an output property, 
+     * not the default value. If there is a default
+     * value, but no non-default value this method
+     * will return null.
+     * <p>
+     * 
+     */
+    public String getOutputPropertyNonDefault(String name )
+    {
+        return getProp(name,false);
+    }
+
+    /**
+     * Return a {@link DOM3Serializer} interface into this serializer. If the
+     * serializer does not support the {@link DOM3Serializer} interface, it should
+     * return null.
+     *
+     * @return A {@link DOM3Serializer} interface into this serializer,  or null
+     * if the serializer is not DOM capable
+     * @throws IOException An I/O exception occured
+     * @see org.apache.xml.serializer.Serializer#asDOM3Serializer()
+     */
+    public Object asDOM3Serializer() throws IOException
+    {
+        return new org.apache.xml.serializer.dom3.DOM3SerializerImpl(this);
+    }
+    /**
+     * Get the default value of an xsl:output property,
+     * which would be null only if no default value exists
+     * for the property.
+     */
+    public String getOutputPropertyDefault(String name) {
+        return getProp(name, true);
+    } 
+    
+    /**
+     * Set the value for the output property, typically from
+     * an xsl:output element, but this does not change what
+     * the default value is.
+     */
+    public void   setOutputProperty(String name, String val) {
+        setProp(name,val,false);
+        
+    }
+    
+    /**
+     * Set the default value for an output property, but this does
+     * not impact any explicitly set value.
+     */
+    public void   setOutputPropertyDefault(String name, String val) {
+        setProp(name,val,true);
+        
+    }
+    
+    /**
+     * A mapping of keys to explicitly set values, for example if 
+     * and <xsl:output/> has an "encoding" attribute, this
+     * map will have what that attribute maps to.
+     */
+    private HashMap m_OutputProps;
+    /**
+     * A mapping of keys to default values, for example if
+     * the default value of the encoding is "UTF-8" then this
+     * map will have that "encoding" maps to "UTF-8".
+     */
+    private HashMap m_OutputPropsDefault;
+    
+    Set getOutputPropDefaultKeys() {
+        return m_OutputPropsDefault.keySet();
+    }
+    Set getOutputPropKeys() {
+        return m_OutputProps.keySet();
+    }
+    
+    private String getProp(String name, boolean defaultVal) {
+        if (m_OutputProps == null) {
+            m_OutputProps = new HashMap();
+            m_OutputPropsDefault = new HashMap();
+        }
+        
+        String val;
+        if (defaultVal)
+            val = (String) m_OutputPropsDefault.get(name);
+        else
+            val = (String) m_OutputProps.get(name);
+        
+        return val;
+        
+    }
+    /**
+     * 
+     * @param name The name of the property, e.g. "{http://myprop}indent-tabs" or "indent".
+     * @param val The value of the property, e.g. "4"
+     * @param defaultVal true if this is a default value being set for the property as 
+     * opposed to a user define on, set say explicitly in the stylesheet or via JAXP
+     */
+    void setProp(String name, String val, boolean defaultVal) {
+        if (m_OutputProps == null) {
+            m_OutputProps = new HashMap();
+            m_OutputPropsDefault = new HashMap();
+        }
+        
+        if (defaultVal)
+            m_OutputPropsDefault.put(name,val);
+        else {
+            if (OutputKeys.CDATA_SECTION_ELEMENTS.equals(name) && val != null) {
+                initCdataElems(val);
+                String oldVal = (String) m_OutputProps.get(name);
+                String newVal;
+                if (oldVal == null)
+                    newVal = oldVal + ' ' + val;
+                else
+                    newVal = val;
+                m_OutputProps.put(name,newVal);
+            }
+            else {
+                m_OutputProps.put(name,val);
+            }
+        }
+        
+
+    }
+
+    /**
+     * Get the first char of the local name
+     * @param name Either a local name, or a local name
+     * preceeded by a uri enclosed in curly braces.
+     */
+    static char getFirstCharLocName(String name) {
+        final char first;
+        int i = name.indexOf('}');
+        if (i < 0)
+            first = name.charAt(0);
+        else
+            first = name.charAt(i+1);
+        return first;
+    }
+}
+    
+
diff --git a/src/main/java/org/apache/xml/serializer/SerializerConstants.java b/src/main/java/org/apache/xml/serializer/SerializerConstants.java
new file mode 100644
index 0000000..87f5052
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializerConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerConstants.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+/**
+ * Constants used in serialization, such as the string "xmlns"
+ * @xsl.usage internal
+ */
+interface SerializerConstants
+{
+
+    /** To insert ]]> in a CDATA section by ending the last CDATA section with
+     * ]] and starting the next CDATA section with >
+     */
+    static final String CDATA_CONTINUE = "]]]]><![CDATA[>";
+    /**
+     * The constant "]]>"
+     */
+    static final String CDATA_DELIMITER_CLOSE = "]]>";
+    static final String CDATA_DELIMITER_OPEN = "<![CDATA[";
+
+    static final String EMPTYSTRING = "";
+
+    static final String ENTITY_AMP = "&amp;";
+    static final String ENTITY_CRLF = "&#xA;";
+    static final String ENTITY_GT = "&gt;";
+    static final String ENTITY_LT = "&lt;";
+    static final String ENTITY_QUOT = "&quot;";
+
+    static final String XML_PREFIX = "xml";
+    static final String XMLNS_PREFIX = "xmlns";
+    static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+   
+    public static final String DEFAULT_SAX_SERIALIZER=SerializerBase.PKG_NAME+".ToXMLSAXHandler";
+    
+    /**
+     * Define the XML version.
+     */
+    static final String XMLVERSION11 = "1.1";
+    static final String XMLVERSION10 = "1.0";
+}
diff --git a/src/main/java/org/apache/xml/serializer/SerializerFactory.java b/src/main/java/org/apache/xml/serializer/SerializerFactory.java
new file mode 100644
index 0000000..f4e5986
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializerFactory.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerFactory.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.xml.transform.OutputKeys;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.xml.sax.ContentHandler;
+
+/**
+ * This class is a public API, it is a factory for creating serializers.
+   * 
+   * The properties object passed to the getSerializer() method should be created by
+   * the OutputPropertiesFactory. Although the properties object
+   * used to create a serializer does not need to be obtained 
+   * from OutputPropertiesFactory,
+   * using this factory ensures that the default key/value properties
+   * are set for the given output "method".
+   * 
+   * <p>
+   * The standard property keys supported are: "method", "version", "encoding",
+   * "omit-xml-declaration", "standalone", doctype-public",
+   * "doctype-system", "cdata-section-elements", "indent", "media-type". 
+   * These property keys and their values are described in the XSLT recommendation,
+   * see {@link <a href="http://www.w3.org/TR/1999/REC-xslt-19991116"> XSLT 1.0 recommendation</a>}
+   * 
+   * <p>
+   * The value of the "cdata-section-elements" property key is a whitespace
+   * separated list of elements. If the element is in a namespace then 
+   * value is passed in this format: {uri}localName 
+   *
+   * <p>
+   * The non-standard property keys supported are defined in {@link OutputPropertiesFactory}.
+   *
+   * @see OutputPropertiesFactory
+   * @see Method
+   * @see Serializer
+   */
+public final class SerializerFactory
+{
+  /**
+   * This constructor is private just to prevent the creation of such an object.
+   */
+
+  private SerializerFactory() {
+ 
+  }
+  /**
+   * Associates output methods to default output formats.
+   */
+  private static Hashtable m_formats = new Hashtable();
+
+  /**
+   * Returns a serializer for the specified output method. The output method
+   * is specified by the value of the property associated with the "method" key.
+   * If no implementation exists that supports the specified output method
+   * an exception of some type will be thrown.
+   * For a list of the output "method" key values see {@link Method}.
+   *
+   * @param format The output format, minimally the "method" property must be set.
+   * @return A suitable serializer.
+   * @throws IllegalArgumentException if method is
+   * null or an appropriate serializer can't be found
+   * @throws Exception if the class for the serializer is found but does not
+   * implement ContentHandler.
+   * @throws WrappedRuntimeException if an exception is thrown while trying to find serializer
+   */
+  public static Serializer getSerializer(Properties format)
+  {
+      Serializer ser;
+
+      try
+      {
+        String method = format.getProperty(OutputKeys.METHOD);
+
+        if (method == null) {
+            String msg = Utils.messages.createMessage(
+                MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                new Object[] { OutputKeys.METHOD});
+            throw new IllegalArgumentException(msg);
+        }
+
+        String className =
+            format.getProperty(OutputPropertiesFactory.S_KEY_CONTENT_HANDLER);
+
+
+        if (null == className)
+        {
+            // Missing Content Handler property, load default using OutputPropertiesFactory
+            Properties methodDefaults =
+                OutputPropertiesFactory.getDefaultMethodProperties(method);
+            className = 
+            methodDefaults.getProperty(OutputPropertiesFactory.S_KEY_CONTENT_HANDLER);
+            if (null == className) {
+                String msg = Utils.messages.createMessage(
+                    MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                    new Object[] { OutputPropertiesFactory.S_KEY_CONTENT_HANDLER});
+                throw new IllegalArgumentException(msg);
+            }
+
+        }
+
+
+
+        ClassLoader loader = ObjectFactory.findClassLoader();
+
+        Class cls = ObjectFactory.findProviderClass(className, loader, true);
+
+        // _serializers.put(method, cls);
+
+        Object obj = cls.newInstance();
+
+        if (obj instanceof SerializationHandler)
+        {
+              // this is one of the supplied serializers
+            ser = (Serializer) cls.newInstance();
+            ser.setOutputFormat(format);
+        }
+        else
+        {
+              /*
+               *  This  must be a user defined Serializer.
+               *  It had better implement ContentHandler.
+               */
+               if (obj instanceof ContentHandler)
+               {
+
+                  /*
+                   * The user defined serializer defines ContentHandler,
+                   * but we need to wrap it with ToXMLSAXHandler which
+                   * will collect SAX-like events and emit true
+                   * SAX ContentHandler events to the users handler.
+                   */
+                  className = SerializerConstants.DEFAULT_SAX_SERIALIZER;
+                  cls = ObjectFactory.findProviderClass(className, loader, true);
+                  SerializationHandler sh =
+                      (SerializationHandler) cls.newInstance();
+                  sh.setContentHandler( (ContentHandler) obj);
+                  sh.setOutputFormat(format);
+
+                  ser = sh;
+               }
+               else
+               {
+                  // user defined serializer does not implement
+                  // ContentHandler, ... very bad
+                   throw new Exception(
+                       Utils.messages.createMessage(
+                           MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                               new Object[] { className}));
+               }
+
+        }
+      }
+      catch (Exception e)
+      {
+        throw new org.apache.xml.serializer.utils.WrappedRuntimeException(e);
+      }
+
+      // If we make it to here ser is not null.
+      return ser;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/SerializerTrace.java b/src/main/java/org/apache/xml/serializer/SerializerTrace.java
new file mode 100644
index 0000000..df612f5
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializerTrace.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerTrace.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import org.xml.sax.Attributes;
+
+/**
+ * This interface defines a set of integer constants that identify trace event
+ * types.
+ * 
+ * @xsl.usage internal
+ */
+
+public interface SerializerTrace {
+    
+  /**
+   * Event type generated when a document begins.
+   *
+   */
+  public static final int EVENTTYPE_STARTDOCUMENT = 1;
+
+  /**
+   * Event type generated when a document ends.
+   */
+  public static final int EVENTTYPE_ENDDOCUMENT = 2;
+
+  /**
+   * Event type generated when an element begins (after the attributes have been processed but before the children have been added).
+   */
+  public static final int EVENTTYPE_STARTELEMENT = 3;
+
+  /**
+   * Event type generated when an element ends, after it's children have been added.
+   */
+  public static final int EVENTTYPE_ENDELEMENT = 4;
+
+  /**
+   * Event type generated for character data (CDATA and Ignorable Whitespace have their own events).
+   */
+  public static final int EVENTTYPE_CHARACTERS = 5;
+
+  /**
+   * Event type generated for ignorable whitespace (I'm not sure how much this is actually called.
+   */
+  public static final int EVENTTYPE_IGNORABLEWHITESPACE = 6;
+
+  /**
+   * Event type generated for processing instructions.
+   */
+  public static final int EVENTTYPE_PI = 7;
+
+  /**
+   * Event type generated after a comment has been added.
+   */
+  public static final int EVENTTYPE_COMMENT = 8;
+
+  /**
+   * Event type generate after an entity ref is created.
+   */
+  public static final int EVENTTYPE_ENTITYREF = 9;
+
+  /**
+   * Event type generated after CDATA is generated.
+   */
+  public static final int EVENTTYPE_CDATA = 10;
+  
+  /**
+   * Event type generated when characters might be written to an output stream,
+   *  but  these characters never are. They will ultimately be written out via
+   * EVENTTYPE_OUTPUT_CHARACTERS. This type is used as attributes are collected.
+   * Whenever the attributes change this event type is fired. At the very end
+   * however, when the attributes do not change anymore and are going to be
+   * ouput to the document the real characters will be written out using the
+   * EVENTTYPE_OUTPUT_CHARACTERS.
+   */
+  public static final int EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS = 11;
+  
+  /**
+   * Event type generated when characters are written to an output stream.
+   */
+  public static final int EVENTTYPE_OUTPUT_CHARACTERS = 12;
+    
+
+  /**
+   * Tell if trace listeners are present.
+   *
+   * @return True if there are trace listeners
+   */
+  public boolean hasTraceListeners();
+  
+  /**
+   * Fire startDocument, endDocument events.
+   *
+   * @param eventType One of the EVENTTYPE_XXX constants.
+   */
+  public void fireGenerateEvent(int eventType);
+  
+  /**
+   * Fire startElement, endElement events.
+   *
+   * @param eventType One of the EVENTTYPE_XXX constants.
+   * @param name The name of the element.
+   * @param atts The SAX attribute list.
+   */
+  public void fireGenerateEvent(int eventType, String name, Attributes atts);
+  
+  /**
+   * Fire characters, cdata events.
+   *
+   * @param eventType One of the EVENTTYPE_XXX constants.
+   * @param ch The char array from the SAX event.
+   * @param start The start offset to be used in the char array.
+   * @param length The end offset to be used in the chara array.
+   */
+  public void fireGenerateEvent(int eventType, char ch[], int start, int length);
+  
+  /**
+   * Fire processingInstruction events.
+   *
+   * @param eventType One of the EVENTTYPE_XXX constants.
+   * @param name The name of the processing instruction.
+   * @param data The processing instruction data.
+   */
+  public void fireGenerateEvent(int eventType, String name, String data);
+  
+
+  /**
+   * Fire comment and entity ref events.
+   *
+   * @param eventType One of the EVENTTYPE_XXX constants.
+   * @param data The comment or entity ref data.
+   */
+  public void fireGenerateEvent(int eventType, String data);
+  
+}
diff --git a/src/main/java/org/apache/xml/serializer/SerializerTraceWriter.java b/src/main/java/org/apache/xml/serializer/SerializerTraceWriter.java
new file mode 100644
index 0000000..5255dba
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/SerializerTraceWriter.java
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerTraceWriter.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * This class wraps the real writer, it only purpose is to send
+ * CHARACTERTOSTREAM events to the trace listener. 
+ * Each method immediately sends the call to the wrapped writer unchanged, but
+ * in addition it collects characters to be issued to a trace listener.
+ * 
+ * In this way the trace
+ * listener knows what characters have been written to the output Writer.
+ * 
+ * There may still be differences in what the trace events say is going to the
+ * output writer and what is really going there. These differences will be due
+ * to the fact that this class is UTF-8 encoding before emiting the trace event
+ * and the underlying writer may not be UTF-8 encoding. There may also be
+ * encoding differences.  So the main pupose of this class is to provide a
+ * resonable facsimile of the true output.
+ * 
+ * @xsl.usage internal
+ */
+final class SerializerTraceWriter extends Writer implements WriterChain
+{
+
+    /** The real writer to immediately write to.
+     * This reference may be null, in which case nothing is written out, but
+     * only the trace events are fired for output.
+     */
+    private final java.io.Writer m_writer;
+
+    /** The tracer to send events to */
+    private final SerializerTrace m_tracer;
+
+    /** The size of the internal buffer, just to keep too many
+     * events from being sent to the tracer
+     */
+    private int buf_length;
+
+    /**
+     * Internal buffer to collect the characters to go to the trace listener.
+     * 
+     */
+    private byte buf[];
+
+    /**
+     * How many bytes have been collected and still need to go to trace
+     * listener.
+     */
+    private int count;
+
+    /**
+     * Creates or replaces the internal buffer, and makes sure it has a few
+     * extra bytes slight overflow of the last UTF8 encoded character.
+     * @param size
+     */
+    private void setBufferSize(int size)
+    {
+        buf = new byte[size + 3];
+        buf_length = size;
+        count = 0;
+    }
+
+    /**
+     * Constructor.
+     * If the writer passed in is null, then this SerializerTraceWriter will
+     * only signal trace events of what would have been written to that writer.
+     * If the writer passed in is not null then the trace events will mirror
+     * what is going to that writer. In this way tools, such as a debugger, can
+     * gather information on what is being written out.
+     * 
+     * @param out the Writer to write to (possibly null)
+     * @param tracer the tracer to inform that characters are being written
+     */
+    public SerializerTraceWriter(Writer out, SerializerTrace tracer)
+    {
+        m_writer = out;
+        m_tracer = tracer;
+        setBufferSize(1024);
+    }
+
+    /**
+     * Flush out the collected characters by sending them to the trace
+     * listener.  These characters are never written to the real writer
+     * (m_writer) because that has already happened with every method
+     * call. This method simple informs the listener of what has already
+     * happened.
+     * @throws IOException
+     */
+    private void flushBuffer() throws IOException
+    {
+
+        // Just for tracing purposes
+        if (count > 0)
+        {
+            char[] chars = new char[count];
+            for(int i=0; i<count; i++)
+                chars[i] = (char) buf[i];
+
+            if (m_tracer != null)
+                m_tracer.fireGenerateEvent(
+                    SerializerTrace.EVENTTYPE_OUTPUT_CHARACTERS,
+                    chars,
+                    0,
+                    chars.length);
+
+            count = 0;
+        }
+    }
+
+    /**
+     * Flush the internal buffer and flush the Writer
+     * @see java.io.Writer#flush()
+     */
+    public void flush() throws java.io.IOException
+    {
+        // send to the real writer
+        if (m_writer != null)
+            m_writer.flush();
+
+        // from here on just for tracing purposes
+        flushBuffer();
+    }
+
+    /**
+     * Flush the internal buffer and close the Writer
+     * @see java.io.Writer#close()
+     */
+    public void close() throws java.io.IOException
+    {
+        // send to the real writer
+        if (m_writer != null)   
+            m_writer.close();
+
+        // from here on just for tracing purposes
+        flushBuffer();
+    }
+
+
+    /**
+     * Write a single character.  The character to be written is contained in
+     * the 16 low-order bits of the given integer value; the 16 high-order bits
+     * are ignored.
+     *
+     * <p> Subclasses that intend to support efficient single-character output
+     * should override this method.
+     *
+     * @param c  int specifying a character to be written.
+     * @exception  IOException  If an I/O error occurs
+     */
+    public void write(final int c) throws IOException
+    {
+        // send to the real writer
+        if (m_writer != null)
+            m_writer.write(c);
+
+        // ---------- from here on just collect for tracing purposes
+
+        /* If we are close to the end of the buffer then flush it.
+         * Remember the buffer can hold a few more characters than buf_length
+         */
+        if (count >= buf_length)
+            flushBuffer();
+
+        if (c < 0x80)
+        {
+            buf[count++] = (byte) (c);
+        }
+        else if (c < 0x800)
+        {
+            buf[count++] = (byte) (0xc0 + (c >> 6));
+            buf[count++] = (byte) (0x80 + (c & 0x3f));
+        }
+        else
+        {
+            buf[count++] = (byte) (0xe0 + (c >> 12));
+            buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+            buf[count++] = (byte) (0x80 + (c & 0x3f));
+        }
+    }
+
+    /**
+     * Write a portion of an array of characters.
+     *
+     * @param  chars  Array of characters
+     * @param  start   Offset from which to start writing characters
+     * @param  length   Number of characters to write
+     *
+     * @exception  IOException  If an I/O error occurs
+     *
+     * @throws java.io.IOException
+     */
+    public void write(final char chars[], final int start, final int length)
+        throws java.io.IOException
+    {
+        // send to the real writer
+        if (m_writer != null)
+            m_writer.write(chars, start, length);
+
+        // from here on just collect for tracing purposes
+        int lengthx3 = (length << 1) + length;
+
+        if (lengthx3 >= buf_length)
+        {
+
+            /* If the request length exceeds the size of the output buffer,
+              * flush the output buffer and make the buffer bigger to handle.
+              */
+
+            flushBuffer();
+            setBufferSize(2 * lengthx3);
+
+        }
+
+        if (lengthx3 > buf_length - count)
+        {
+            flushBuffer();
+        }
+
+        final int n = length + start;
+        for (int i = start; i < n; i++)
+        {
+            final char c = chars[i];
+
+            if (c < 0x80)
+                buf[count++] = (byte) (c);
+            else if (c < 0x800)
+            {
+                buf[count++] = (byte) (0xc0 + (c >> 6));
+                buf[count++] = (byte) (0x80 + (c & 0x3f));
+            }
+            else
+            {
+                buf[count++] = (byte) (0xe0 + (c >> 12));
+                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+                buf[count++] = (byte) (0x80 + (c & 0x3f));
+            }
+        }
+
+    }
+
+    /**
+     * Write a string.
+     *
+     * @param  s  String to be written
+     *
+     * @exception  IOException  If an I/O error occurs
+     */
+    public void write(final String s) throws IOException
+    {
+        // send to the real writer
+        if (m_writer != null)
+            m_writer.write(s);
+
+        // from here on just collect for tracing purposes
+        final int length = s.length();
+
+        // We multiply the length by three since this is the maximum length
+        // of the characters that we can put into the buffer.  It is possible
+        // for each Unicode character to expand to three bytes.
+
+        int lengthx3 = (length << 1) + length;
+
+        if (lengthx3 >= buf_length)
+        {
+
+            /* If the request length exceeds the size of the output buffer,
+              * flush the output buffer and make the buffer bigger to handle.
+              */
+
+            flushBuffer();
+            setBufferSize(2 * lengthx3);
+        }
+
+        if (lengthx3 > buf_length - count)
+        {
+            flushBuffer();
+        }
+
+        for (int i = 0; i < length; i++)
+        {
+            final char c = s.charAt(i);
+
+            if (c < 0x80)
+                buf[count++] = (byte) (c);
+            else if (c < 0x800)
+            {
+                buf[count++] = (byte) (0xc0 + (c >> 6));
+                buf[count++] = (byte) (0x80 + (c & 0x3f));
+            }
+            else
+            {
+                buf[count++] = (byte) (0xe0 + (c >> 12));
+                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+                buf[count++] = (byte) (0x80 + (c & 0x3f));
+            }
+        }
+    }
+
+    /**
+     * Get the writer that this one directly wraps.
+     */
+    public Writer getWriter()
+    {
+        return m_writer;
+    }
+
+    /**
+     * Get the OutputStream that is the at the end of the
+     * chain of writers.
+     */
+    public OutputStream getOutputStream()
+    {
+        OutputStream retval = null;
+        if (m_writer instanceof WriterChain)
+            retval = ((WriterChain) m_writer).getOutputStream();
+        return retval;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToHTMLStream.java b/src/main/java/org/apache/xml/serializer/ToHTMLStream.java
new file mode 100644
index 0000000..4f2927a
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToHTMLStream.java
@@ -0,0 +1,2350 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToHTMLStream.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.xml.transform.Result;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This serializer takes a series of SAX or
+ * SAX-like events and writes its output
+ * to the given stream.
+ * 
+ * This class is not a public API, it is public
+ * because it is used from another package.
+ * 
+ * @xsl.usage internal
+ */
+public class ToHTMLStream extends ToStream 
+{
+
+    /** This flag is set while receiving events from the DTD */
+    protected boolean m_inDTD = false;
+
+    /** True if the current element is a block element.  (seems like 
+     *  this needs to be a stack. -sb). */
+    private boolean m_inBlockElem = false;
+
+    /**
+     * Map that tells which XML characters should have special treatment, and it
+     *  provides character to entity name lookup.
+     */
+    private final CharInfo m_htmlcharInfo =
+//        new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE);
+        CharInfo.getCharInfo(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML);
+
+    /** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */
+    static final Trie m_elementFlags = new Trie();
+
+    static {
+        initTagReference(m_elementFlags);
+    }
+    static void initTagReference(Trie m_elementFlags) {
+
+        // HTML 4.0 loose DTD
+        m_elementFlags.put("BASEFONT", new ElemDesc(0 | ElemDesc.EMPTY));
+        m_elementFlags.put(
+            "FRAME",
+            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put("FRAMESET", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("NOFRAMES", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "ISINDEX",
+            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "APPLET",
+            new ElemDesc(0 | ElemDesc.WHITESPACESENSITIVE));
+        m_elementFlags.put("CENTER", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("DIR", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("MENU", new ElemDesc(0 | ElemDesc.BLOCK));
+
+        // HTML 4.0 strict DTD
+        m_elementFlags.put("TT", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("I", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("B", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("BIG", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("SMALL", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("EM", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("STRONG", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("DFN", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("CODE", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("SAMP", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("KBD", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("VAR", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("CITE", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("ABBR", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put("ACRONYM", new ElemDesc(0 | ElemDesc.PHRASE));
+        m_elementFlags.put(
+            "SUP",
+            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
+        m_elementFlags.put(
+            "SUB",
+            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
+        m_elementFlags.put(
+            "SPAN",
+            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
+        m_elementFlags.put(
+            "BDO",
+            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
+        m_elementFlags.put(
+            "BR",
+            new ElemDesc(
+                0
+                    | ElemDesc.SPECIAL
+                    | ElemDesc.ASPECIAL
+                    | ElemDesc.EMPTY
+                    | ElemDesc.BLOCK));
+        m_elementFlags.put("BODY", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "ADDRESS",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put(
+            "DIV",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put("A", new ElemDesc(0 | ElemDesc.SPECIAL));
+        m_elementFlags.put(
+            "MAP",
+            new ElemDesc(
+                0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "AREA",
+            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "LINK",
+            new ElemDesc(
+                0 | ElemDesc.HEADMISC | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "IMG",
+            new ElemDesc(
+                0
+                    | ElemDesc.SPECIAL
+                    | ElemDesc.ASPECIAL
+                    | ElemDesc.EMPTY
+                    | ElemDesc.WHITESPACESENSITIVE));
+        m_elementFlags.put(
+            "OBJECT",
+            new ElemDesc(
+                0
+                    | ElemDesc.SPECIAL
+                    | ElemDesc.ASPECIAL
+                    | ElemDesc.HEADMISC
+                    | ElemDesc.WHITESPACESENSITIVE));
+        m_elementFlags.put("PARAM", new ElemDesc(0 | ElemDesc.EMPTY));
+        m_elementFlags.put(
+            "HR",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET
+                    | ElemDesc.EMPTY));
+        m_elementFlags.put(
+            "P",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put(
+            "H1",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "H2",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "H3",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "H4",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "H5",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "H6",
+            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "PRE",
+            new ElemDesc(0 | ElemDesc.PREFORMATTED | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "Q",
+            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
+        m_elementFlags.put(
+            "BLOCKQUOTE",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put("INS", new ElemDesc(0));
+        m_elementFlags.put("DEL", new ElemDesc(0));
+        m_elementFlags.put(
+            "DL",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put("DT", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("DD", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "OL",
+            new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "UL",
+            new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
+        m_elementFlags.put("LI", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("FORM", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("LABEL", new ElemDesc(0 | ElemDesc.FORMCTRL));
+        m_elementFlags.put(
+            "INPUT",
+            new ElemDesc(
+                0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL | ElemDesc.EMPTY));
+        m_elementFlags.put(
+            "SELECT",
+            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
+        m_elementFlags.put("OPTGROUP", new ElemDesc(0));
+        m_elementFlags.put("OPTION", new ElemDesc(0));
+        m_elementFlags.put(
+            "TEXTAREA",
+            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
+        m_elementFlags.put(
+            "FIELDSET",
+            new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM));
+        m_elementFlags.put("LEGEND", new ElemDesc(0));
+        m_elementFlags.put(
+            "BUTTON",
+            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
+        m_elementFlags.put(
+            "TABLE",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put("CAPTION", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("THEAD", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("TFOOT", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("TBODY", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("COLGROUP", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "COL",
+            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put("TR", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("TH", new ElemDesc(0));
+        m_elementFlags.put("TD", new ElemDesc(0));
+        m_elementFlags.put(
+            "HEAD",
+            new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HEADELEM));
+        m_elementFlags.put("TITLE", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "BASE",
+            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "META",
+            new ElemDesc(
+                0 | ElemDesc.HEADMISC | ElemDesc.EMPTY | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "STYLE",
+            new ElemDesc(
+                0 | ElemDesc.HEADMISC | ElemDesc.RAW | ElemDesc.BLOCK));
+        m_elementFlags.put(
+            "SCRIPT",
+            new ElemDesc(
+                0
+                    | ElemDesc.SPECIAL
+                    | ElemDesc.ASPECIAL
+                    | ElemDesc.HEADMISC
+                    | ElemDesc.RAW));
+        m_elementFlags.put(
+            "NOSCRIPT",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        m_elementFlags.put("HTML", new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HTMLELEM));
+
+        // From "John Ky" <hand@syd.speednet.com.au
+        // Transitional Document Type Definition ()
+        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/sgml/loosedtd.html#basefont
+        m_elementFlags.put("FONT", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+
+        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-STRIKE
+        m_elementFlags.put("S", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+        m_elementFlags.put("STRIKE", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+
+        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-U
+        m_elementFlags.put("U", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+
+        // From "John Ky" <hand@syd.speednet.com.au
+        m_elementFlags.put("NOBR", new ElemDesc(0 | ElemDesc.FONTSTYLE));
+
+        // HTML 4.0, section 16.5
+        m_elementFlags.put(
+            "IFRAME",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+                    
+        // Netscape 4 extension
+        m_elementFlags.put(
+            "LAYER",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+        // Netscape 4 extension                    
+        m_elementFlags.put(
+            "ILAYER",
+            new ElemDesc(
+                0
+                    | ElemDesc.BLOCK
+                    | ElemDesc.BLOCKFORM
+                    | ElemDesc.BLOCKFORMFIELDSET));
+
+        // NOW FOR ATTRIBUTE INFORMATION . . .
+        ElemDesc elemDesc;
+
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("a");
+        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
+        elemDesc.setAttr("NAME", ElemDesc.ATTRURL);
+        
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("area");
+
+        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
+        elemDesc.setAttr("NOHREF", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("base");
+
+        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("button");
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("blockquote");
+
+        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("del");
+        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("dir");
+        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
+           
+        // ----------------------------------------------
+        
+        elemDesc = (ElemDesc) m_elementFlags.get("div");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL); // Netscape 4 extension
+        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY); // Internet-Explorer extension
+   
+        // ----------------------------------------------        
+        elemDesc = (ElemDesc) m_elementFlags.get("dl");
+        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
+           
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("form");
+        elemDesc.setAttr("ACTION", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        // Attribution to: "Voytenko, Dimitry" <DVoytenko@SECTORBASE.COM>
+        elemDesc = (ElemDesc) m_elementFlags.get("frame");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("NORESIZE",ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("head");
+        elemDesc.setAttr("PROFILE", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------        
+        elemDesc = (ElemDesc) m_elementFlags.get("hr");
+        elemDesc.setAttr("NOSHADE", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        // HTML 4.0, section 16.5
+        elemDesc = (ElemDesc) m_elementFlags.get("iframe");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        // Netscape 4 extension
+        elemDesc = (ElemDesc) m_elementFlags.get("ilayer");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("img");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
+        elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("input");
+
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
+        elemDesc.setAttr("CHECKED", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("ins");
+        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        // Netscape 4 extension
+        elemDesc = (ElemDesc) m_elementFlags.get("layer");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("link");
+        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
+       
+        // ----------------------------------------------       
+        elemDesc = (ElemDesc) m_elementFlags.get("menu");
+        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("object");
+
+        elemDesc.setAttr("CLASSID", ElemDesc.ATTRURL);
+        elemDesc.setAttr("CODEBASE", ElemDesc.ATTRURL);
+        elemDesc.setAttr("DATA", ElemDesc.ATTRURL);
+        elemDesc.setAttr("ARCHIVE", ElemDesc.ATTRURL);
+        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
+        elemDesc.setAttr("DECLARE", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------        
+        elemDesc = (ElemDesc) m_elementFlags.get("ol");
+        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("optgroup");
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("option");
+        elemDesc.setAttr("SELECTED", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("q");
+        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("script");
+        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
+        elemDesc.setAttr("FOR", ElemDesc.ATTRURL);
+        elemDesc.setAttr("DEFER", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("select");
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("MULTIPLE", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("table");
+        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY); // Internet-Explorer extension
+        
+        // ----------------------------------------------        
+        elemDesc = (ElemDesc) m_elementFlags.get("td");
+        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
+
+        // ----------------------------------------------
+        elemDesc = (ElemDesc) m_elementFlags.get("textarea");
+        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
+        elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);
+       
+        // ----------------------------------------------                
+        elemDesc = (ElemDesc) m_elementFlags.get("th");
+        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------
+        // The nowrap attribute of a tr element is both
+        // a Netscape and Internet-Explorer extension                
+        elemDesc = (ElemDesc) m_elementFlags.get("tr");
+        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
+        
+        // ----------------------------------------------        
+        elemDesc = (ElemDesc) m_elementFlags.get("ul");
+        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
+    }
+
+    /**
+     * Dummy element for elements not found.
+     */
+    static private final ElemDesc m_dummy = new ElemDesc(0 | ElemDesc.BLOCK);
+
+    /** True if URLs should be specially escaped with the %xx form. */
+    private boolean m_specialEscapeURLs = true;
+
+    /** True if the META tag should be omitted. */
+    private boolean m_omitMetaTag = false;
+
+    /**
+     * Tells if the formatter should use special URL escaping.
+     *
+     * @param bool True if URLs should be specially escaped with the %xx form.
+     */
+    public void setSpecialEscapeURLs(boolean bool)
+    {
+        m_specialEscapeURLs = bool;
+    }
+
+    /**
+     * Tells if the formatter should omit the META tag.
+     *
+     * @param bool True if the META tag should be omitted.
+     */
+    public void setOmitMetaTag(boolean bool)
+    {
+        m_omitMetaTag = bool;
+    }
+
+    /**
+     * Specifies an output format for this serializer. It the
+     * serializer has already been associated with an output format,
+     * it will switch to the new format. This method should not be
+     * called while the serializer is in the process of serializing
+     * a document.
+     * 
+     * This method can be called multiple times before starting
+     * the serialization of a particular result-tree. In principle
+     * all serialization parameters can be changed, with the exception
+     * of method="html" (it must be method="html" otherwise we
+     * shouldn't even have a ToHTMLStream object here!) 
+     *
+     * @param format The output format or serialzation parameters
+     * to use.
+     */
+    public void setOutputFormat(Properties format)
+    {
+        /*
+         * If "format" does not contain the property
+         * S_USE_URL_ESCAPING, then don't set this value at all,
+         * just leave as-is rather than explicitly setting it.
+         */
+        String value; 
+        value = format.getProperty(OutputPropertiesFactory.S_USE_URL_ESCAPING);
+        if (value != null) {
+            m_specialEscapeURLs =
+                OutputPropertyUtils.getBooleanProperty(
+                    OutputPropertiesFactory.S_USE_URL_ESCAPING,
+                    format);
+        }
+
+        /*
+         * If "format" does not contain the property
+         * S_OMIT_META_TAG, then don't set this value at all,
+         * just leave as-is rather than explicitly setting it.
+         */
+        value = format.getProperty(OutputPropertiesFactory.S_OMIT_META_TAG);
+        if (value != null) {
+           m_omitMetaTag =
+                OutputPropertyUtils.getBooleanProperty(
+                    OutputPropertiesFactory.S_OMIT_META_TAG,
+                    format);
+        }
+
+        super.setOutputFormat(format);
+    }
+
+    /**
+     * Tells if the formatter should use special URL escaping.
+     *
+     * @return True if URLs should be specially escaped with the %xx form.
+     */
+    private final boolean getSpecialEscapeURLs()
+    {
+        return m_specialEscapeURLs;
+    }
+
+    /**
+     * Tells if the formatter should omit the META tag.
+     *
+     * @return True if the META tag should be omitted.
+     */
+    private final boolean getOmitMetaTag()
+    {
+        return m_omitMetaTag;
+    }
+
+    /**
+     * Get a description of the given element.
+     *
+     * @param name non-null name of element, case insensitive.
+     *
+     * @return non-null reference to ElemDesc, which may be m_dummy if no 
+     *         element description matches the given name.
+     */
+    public static final ElemDesc getElemDesc(String name)
+    {
+        /* this method used to return m_dummy  when name was null
+         * but now it doesn't check and and requires non-null name.
+         */
+        Object obj = m_elementFlags.get(name);
+        if (null != obj)
+            return (ElemDesc)obj;
+        return m_dummy;
+    }
+    
+    
+    /**
+     * A Trie that is just a copy of the "static" one.
+     * We need this one to be able to use the faster, but not thread-safe
+     * method Trie.get2(name)
+     */
+    private Trie m_htmlInfo = new Trie(m_elementFlags);
+    /**
+     * Calls to this method could be replaced with calls to
+     * getElemDesc(name), but this one should be faster.
+     */
+    private ElemDesc getElemDesc2(String name)
+    {
+        Object obj = m_htmlInfo.get2(name);
+        if (null != obj)
+            return (ElemDesc)obj;
+        return m_dummy;
+    }
+
+    /**
+     * Default constructor.
+     */
+    public ToHTMLStream()
+    {
+
+        super();
+        // we are just constructing this thing, no output properties
+        // have been used, so we will set the right default for
+        // indenting anyways
+        m_doIndent = true; 
+        m_charInfo = m_htmlcharInfo;
+        // initialize namespaces
+        m_prefixMap = new NamespaceMappings();
+
+    }
+
+    /** The name of the current element. */
+//    private String m_currentElementName = null;
+
+    /**
+     * Receive notification of the beginning of a document.
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void startDocumentInternal() throws org.xml.sax.SAXException
+    {
+        super.startDocumentInternal();
+
+        m_needToCallStartDocument = false; 
+        m_needToOutputDocTypeDecl = true;
+        m_startNewLine = false;
+        setOmitXMLDeclaration(true);
+    }
+
+    /**
+     * This method should only get called once.
+     * If a DOCTYPE declaration needs to get written out, it will
+     * be written out. If it doesn't need to be written out, then
+     * the call to this method has no effect.
+     */
+    private void outputDocTypeDecl(String name) throws SAXException {
+        if (true == m_needToOutputDocTypeDecl)
+        {
+            String doctypeSystem = getDoctypeSystem();
+            String doctypePublic = getDoctypePublic();
+            if ((null != doctypeSystem) || (null != doctypePublic))
+            {
+                final java.io.Writer writer = m_writer;
+                try
+                {
+                writer.write("<!DOCTYPE ");
+                writer.write(name);
+
+                if (null != doctypePublic)
+                {
+                    writer.write(" PUBLIC \"");
+                    writer.write(doctypePublic);
+                    writer.write('"');
+                }
+
+                if (null != doctypeSystem)
+                {
+                    if (null == doctypePublic)
+                        writer.write(" SYSTEM \"");
+                    else
+                        writer.write(" \"");
+
+                    writer.write(doctypeSystem);
+                    writer.write('"');
+                }
+
+                writer.write('>');
+                outputLineSep();
+                }
+                catch(IOException e)
+                {
+                    throw new SAXException(e);
+                }
+            }
+        }
+
+        m_needToOutputDocTypeDecl = false;
+    }
+
+    /**
+     * Receive notification of the end of a document. 
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public final void endDocument() throws org.xml.sax.SAXException
+    {
+        
+        flushPending();
+        if (m_doIndent && !m_isprevtext)
+        {
+            try
+            {
+            outputLineSep();
+            }
+            catch(IOException e)
+            {
+                throw new SAXException(e);
+            }
+        }
+
+        flushWriter();
+        if (m_tracer != null)
+            super.fireEndDoc();
+    }
+
+    /**
+     *  Receive notification of the beginning of an element.
+     *
+     *
+     *  @param namespaceURI
+     *  @param localName
+     *  @param name The element type name.
+     *  @param atts The attributes attached to the element, if any.
+     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *             wrapping another exception.
+     *  @see #endElement
+     *  @see org.xml.sax.AttributeList
+     */
+    public void startElement(
+        String namespaceURI,
+        String localName,
+        String name,
+        Attributes atts)
+        throws org.xml.sax.SAXException
+    {
+
+        ElemContext elemContext = m_elemContext;
+
+        // clean up any pending things first
+        if (elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            elemContext.m_startTagOpen = false;
+        }
+        else if (m_cdataTagOpen)
+        {
+            closeCDATA();
+            m_cdataTagOpen = false;
+        }
+        else if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+            m_needToCallStartDocument = false;
+        }
+        
+        if (m_needToOutputDocTypeDecl) {            
+            String n = name;
+            if (n == null || n.length() == 0) {
+                // If the lexical QName is not given
+                // use the localName in the DOCTYPE
+                n = localName;
+            }
+            outputDocTypeDecl(n);
+        }
+
+
+        // if this element has a namespace then treat it like XML
+        if (null != namespaceURI && namespaceURI.length() > 0)
+        {
+            super.startElement(namespaceURI, localName, name, atts);
+
+            return;
+        }
+        
+        try
+        {
+            // getElemDesc2(name) is faster than getElemDesc(name)
+            ElemDesc elemDesc = getElemDesc2(name);
+            int elemFlags = elemDesc.getFlags();
+
+            // deal with indentation issues first
+            if (m_doIndent)
+            {
+
+                boolean isBlockElement = (elemFlags & ElemDesc.BLOCK) != 0;
+                if (m_ispreserve)
+                    m_ispreserve = false;
+                else if (
+                    (null != elemContext.m_elementName)
+                    && (!m_inBlockElem
+                        || isBlockElement) /* && !isWhiteSpaceSensitive */
+                    )
+                {
+                    m_startNewLine = true;
+
+                    indent();
+
+                }
+                m_inBlockElem = !isBlockElement;
+            }
+
+            // save any attributes for later processing
+            if (atts != null)
+                addAttributes(atts);            
+
+            m_isprevtext = false;
+            final java.io.Writer writer = m_writer;
+            writer.write('<');
+            writer.write(name);
+
+
+
+            if (m_tracer != null)
+                firePseudoAttributes();
+            
+            if ((elemFlags & ElemDesc.EMPTY) != 0)  
+            {
+                // an optimization for elements which are expected
+                // to be empty.
+                m_elemContext = elemContext.push();
+                /* XSLTC sometimes calls namespaceAfterStartElement()
+                 * so we need to remember the name
+                 */
+                m_elemContext.m_elementName = name;
+                m_elemContext.m_elementDesc = elemDesc;
+                return;                
+            } 
+            else
+            {
+                elemContext = elemContext.push(namespaceURI,localName,name);
+                m_elemContext = elemContext;
+                elemContext.m_elementDesc = elemDesc;
+                elemContext.m_isRaw = (elemFlags & ElemDesc.RAW) != 0;
+            }
+            
+
+            if ((elemFlags & ElemDesc.HEADELEM) != 0)
+            {
+                // This is the <HEAD> element, do some special processing
+                closeStartTag();
+                elemContext.m_startTagOpen = false;
+                if (!m_omitMetaTag)
+                {
+                    if (m_doIndent)
+                        indent();
+                    writer.write(
+                        "<META http-equiv=\"Content-Type\" content=\"text/html; charset=");
+                    String encoding = getEncoding();
+                    String encode = Encodings.getMimeEncoding(encoding);
+                    writer.write(encode);
+                    writer.write("\">");
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     *  Receive notification of the end of an element.
+     *
+     *
+     *  @param namespaceURI
+     *  @param localName
+     *  @param name The element type name
+     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *             wrapping another exception.
+     */
+    public final void endElement(
+        final String namespaceURI,
+        final String localName,
+        final String name)
+        throws org.xml.sax.SAXException
+    {
+        // deal with any pending issues
+        if (m_cdataTagOpen)
+            closeCDATA();
+
+        // if the element has a namespace, treat it like XML, not HTML
+        if (null != namespaceURI && namespaceURI.length() > 0)
+        {
+            super.endElement(namespaceURI, localName, name);
+
+            return;
+        }
+
+        try
+        {
+
+            ElemContext elemContext = m_elemContext;
+            final ElemDesc elemDesc = elemContext.m_elementDesc;
+            final int elemFlags = elemDesc.getFlags();
+            final boolean elemEmpty = (elemFlags & ElemDesc.EMPTY) != 0;
+
+            // deal with any indentation issues
+            if (m_doIndent)
+            {
+                final boolean isBlockElement = (elemFlags&ElemDesc.BLOCK) != 0;
+                boolean shouldIndent = false;
+
+                if (m_ispreserve)
+                {
+                    m_ispreserve = false;
+                }
+                else if (m_doIndent && (!m_inBlockElem || isBlockElement))
+                {
+                    m_startNewLine = true;
+                    shouldIndent = true;
+                }
+                if (!elemContext.m_startTagOpen && shouldIndent)
+                    indent(elemContext.m_currentElemDepth - 1);
+                m_inBlockElem = !isBlockElement;
+            }
+
+            final java.io.Writer writer = m_writer;
+            if (!elemContext.m_startTagOpen)
+            {
+                writer.write("</");
+                writer.write(name);
+                writer.write('>');
+            }
+            else
+            {
+                // the start-tag open when this method was called,
+                // so we need to process it now.
+                
+                if (m_tracer != null)
+                    super.fireStartElem(name);
+
+                // the starting tag was still open when we received this endElement() call
+                // so we need to process any gathered attributes NOW, before they go away.
+                int nAttrs = m_attributes.getLength();
+                if (nAttrs > 0)
+                {
+                    processAttributes(m_writer, nAttrs);
+                    // clear attributes object for re-use with next element
+                    m_attributes.clear();
+                }
+                if (!elemEmpty)
+                {
+                    // As per Dave/Paul recommendation 12/06/2000
+                    // if (shouldIndent)
+                    // writer.write('>');
+                    //  indent(m_currentIndent);
+
+                    writer.write("></");
+                    writer.write(name);
+                    writer.write('>');
+                }
+                else
+                {
+                    writer.write('>');
+                }
+            }
+            
+            // clean up because the element has ended
+            if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)
+                m_ispreserve = true;
+            m_isprevtext = false;
+
+            // fire off the end element event
+            if (m_tracer != null)
+                super.fireEndElem(name);            
+                           
+            // OPTIMIZE-EMPTY                
+            if (elemEmpty)
+            {
+                // a quick exit if the HTML element had no children.
+                // This block of code can be removed if the corresponding block of code
+                // in startElement() also labeled with "OPTIMIZE-EMPTY" is also removed
+                m_elemContext = elemContext.m_prev;
+                return;
+            }
+
+            // some more clean because the element has ended. 
+            if (!elemContext.m_startTagOpen)
+            {
+                if (m_doIndent && !m_preserves.isEmpty())
+                    m_preserves.pop();
+            }
+            m_elemContext = elemContext.m_prev;
+//            m_isRawStack.pop();
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     * Process an attribute.
+     * @param   writer The writer to write the processed output to.
+     * @param   name   The name of the attribute.
+     * @param   value   The value of the attribute.
+     * @param   elemDesc The description of the HTML element 
+     *           that has this attribute.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void processAttribute(
+        java.io.Writer writer,
+        String name,
+        String value,
+        ElemDesc elemDesc)
+        throws IOException
+    {
+        writer.write(' ');
+
+        if (   ((value.length() == 0) || value.equalsIgnoreCase(name))
+            && elemDesc != null 
+            && elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY))
+        {
+            writer.write(name);
+        }
+        else
+        {
+            // %REVIEW% %OPT%
+            // Two calls to single-char write may NOT
+            // be more efficient than one to string-write...
+            writer.write(name);
+            writer.write("=\"");
+            if (   elemDesc != null
+                && elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL))
+                writeAttrURI(writer, value, m_specialEscapeURLs);
+            else
+                writeAttrString(writer, value, this.getEncoding());
+            writer.write('"');
+
+        }
+    }
+
+    /**
+     * Tell if a character is an ASCII digit.
+     */
+    private boolean isASCIIDigit(char c)
+    {
+        return (c >= '0' && c <= '9');
+    }
+
+    /**
+     * Make an integer into an HH hex value.
+     * Does no checking on the size of the input, since this 
+     * is only meant to be used locally by writeAttrURI.
+     * 
+     * @param i must be a value less than 255.
+     * 
+     * @return should be a two character string.
+     */
+    private static String makeHHString(int i)
+    {
+        String s = Integer.toHexString(i).toUpperCase();
+        if (s.length() == 1)
+        {
+            s = "0" + s;
+        }
+        return s;
+    }
+
+    /**
+    * Dmitri Ilyin: Makes sure if the String is HH encoded sign.
+    * @param str must be 2 characters long
+    *
+    * @return true or false
+    */
+    private boolean isHHSign(String str)
+    {
+        boolean sign = true;
+        try
+        {
+            char r = (char) Integer.parseInt(str, 16);
+        }
+        catch (NumberFormatException e)
+        {
+            sign = false;
+        }
+        return sign;
+    }
+
+    /**
+     * Write the specified <var>string</var> after substituting non ASCII characters,
+     * with <CODE>%HH</CODE>, where HH is the hex of the byte value.
+     *
+     * @param   string      String to convert to XML format.
+     * @param doURLEscaping True if we should try to encode as 
+     *                      per http://www.ietf.org/rfc/rfc2396.txt.
+     *
+     * @throws org.xml.sax.SAXException if a bad surrogate pair is detected.
+     */
+    public void writeAttrURI(
+        final java.io.Writer writer, String string, boolean doURLEscaping)
+        throws IOException
+    {
+        // http://www.ietf.org/rfc/rfc2396.txt says:
+        // A URI is always in an "escaped" form, since escaping or unescaping a
+        // completed URI might change its semantics.  Normally, the only time
+        // escape encodings can safely be made is when the URI is being created
+        // from its component parts; each component may have its own set of
+        // characters that are reserved, so only the mechanism responsible for
+        // generating or interpreting that component can determine whether or
+        // not escaping a character will change its semantics. Likewise, a URI
+        // must be separated into its components before the escaped characters
+        // within those components can be safely decoded.
+        //
+        // ...So we do our best to do limited escaping of the URL, without 
+        // causing damage.  If the URL is already properly escaped, in theory, this 
+        // function should not change the string value.
+
+        final int end = string.length();
+        if (end > m_attrBuff.length)
+        {
+           m_attrBuff = new char[end*2 + 1];               
+        }
+        string.getChars(0,end, m_attrBuff, 0); 
+        final char[] chars = m_attrBuff;
+
+        int cleanStart = 0;
+        int cleanLength = 0;
+        
+        
+        char ch = 0;
+        for (int i = 0; i < end; i++)
+        {
+            ch = chars[i];
+
+            if ((ch < 32) || (ch > 126))
+            {
+                if (cleanLength > 0)
+                {
+                    writer.write(chars, cleanStart, cleanLength);
+                    cleanLength = 0;
+                }
+                if (doURLEscaping)
+                {
+                    // Encode UTF16 to UTF8.
+                    // Reference is Unicode, A Primer, by Tony Graham.
+                    // Page 92.
+
+                    // Note that Kay doesn't escape 0x20...
+                    //  if(ch == 0x20) // Not sure about this... -sb
+                    //  {
+                    //    writer.write(ch);
+                    //  }
+                    //  else 
+                    if (ch <= 0x7F)
+                    {
+                        writer.write('%');
+                        writer.write(makeHHString(ch));
+                    }
+                    else if (ch <= 0x7FF)
+                    {
+                        // Clear low 6 bits before rotate, put high 4 bits in low byte, 
+                        // and set two high bits.
+                        int high = (ch >> 6) | 0xC0;
+                        int low = (ch & 0x3F) | 0x80;
+                        // First 6 bits, + high bit
+                        writer.write('%');
+                        writer.write(makeHHString(high));
+                        writer.write('%');
+                        writer.write(makeHHString(low));
+                    }
+                    else if (Encodings.isHighUTF16Surrogate(ch)) // high surrogate
+                    {
+                        // I'm sure this can be done in 3 instructions, but I choose 
+                        // to try and do it exactly like it is done in the book, at least 
+                        // until we are sure this is totally clean.  I don't think performance 
+                        // is a big issue with this particular function, though I could be 
+                        // wrong.  Also, the stuff below clearly does more masking than 
+                        // it needs to do.
+
+                        // Clear high 6 bits.
+                        int highSurrogate = ((int) ch) & 0x03FF;
+
+                        // Middle 4 bits (wwww) + 1
+                        // "Note that the value of wwww from the high surrogate bit pattern
+                        // is incremented to make the uuuuu bit pattern in the scalar value 
+                        // so the surrogate pair don't address the BMP."
+                        int wwww = ((highSurrogate & 0x03C0) >> 6);
+                        int uuuuu = wwww + 1;
+
+                        // next 4 bits
+                        int zzzz = (highSurrogate & 0x003C) >> 2;
+
+                        // low 2 bits
+                        int yyyyyy = ((highSurrogate & 0x0003) << 4) & 0x30;
+
+                        // Get low surrogate character.
+                        ch = chars[++i];
+
+                        // Clear high 6 bits.
+                        int lowSurrogate = ((int) ch) & 0x03FF;
+
+                        // put the middle 4 bits into the bottom of yyyyyy (byte 3)
+                        yyyyyy = yyyyyy | ((lowSurrogate & 0x03C0) >> 6);
+
+                        // bottom 6 bits.
+                        int xxxxxx = (lowSurrogate & 0x003F);
+
+                        int byte1 = 0xF0 | (uuuuu >> 2); // top 3 bits of uuuuu
+                        int byte2 =
+                            0x80 | (((uuuuu & 0x03) << 4) & 0x30) | zzzz;
+                        int byte3 = 0x80 | yyyyyy;
+                        int byte4 = 0x80 | xxxxxx;
+
+                        writer.write('%');
+                        writer.write(makeHHString(byte1));
+                        writer.write('%');
+                        writer.write(makeHHString(byte2));
+                        writer.write('%');
+                        writer.write(makeHHString(byte3));
+                        writer.write('%');
+                        writer.write(makeHHString(byte4));
+                    }
+                    else
+                    {
+                        int high = (ch >> 12) | 0xE0; // top 4 bits
+                        int middle = ((ch & 0x0FC0) >> 6) | 0x80;
+                        // middle 6 bits
+                        int low = (ch & 0x3F) | 0x80;
+                        // First 6 bits, + high bit
+                        writer.write('%');
+                        writer.write(makeHHString(high));
+                        writer.write('%');
+                        writer.write(makeHHString(middle));
+                        writer.write('%');
+                        writer.write(makeHHString(low));
+                    }
+
+                }
+                else if (escapingNotNeeded(ch))
+                {
+                    writer.write(ch);
+                }
+                else
+                {
+                    writer.write("&#");
+                    writer.write(Integer.toString(ch));
+                    writer.write(';');
+                }
+                // In this character range we have first written out any previously accumulated 
+                // "clean" characters, then processed the current more complicated character,
+                // which may have incremented "i".
+                // We now we reset the next possible clean character.
+                cleanStart = i + 1;
+            }
+            // Since http://www.ietf.org/rfc/rfc2396.txt refers to the URI grammar as
+            // not allowing quotes in the URI proper syntax, nor in the fragment 
+            // identifier, we believe that it's OK to double escape quotes.
+            else if (ch == '"')
+            {
+                // If the character is a '%' number number, try to avoid double-escaping.
+                // There is a question if this is legal behavior.
+
+                // Dmitri Ilyin: to check if '%' number number is invalid. It must be checked if %xx is a sign, that would be encoded
+                // The encoded signes are in Hex form. So %xx my be in form %3C that is "<" sign. I will try to change here a little.
+
+                //        if( ((i+2) < len) && isASCIIDigit(stringArray[i+1]) && isASCIIDigit(stringArray[i+2]) )
+
+                // We are no longer escaping '%'
+
+                if (cleanLength > 0)
+                {
+                    writer.write(chars, cleanStart, cleanLength);
+                    cleanLength = 0;
+                }   
+                
+                
+                // Mike Kay encodes this as &#34;, so he may know something I don't?
+                if (doURLEscaping)
+                    writer.write("%22");
+                else
+                    writer.write("&quot;"); // we have to escape this, I guess.
+
+                // We have written out any clean characters, then the escaped '%' and now we
+                // We now we reset the next possible clean character.
+                cleanStart = i + 1;    
+            }
+            else if (ch == '&')
+            {
+                // HTML 4.01 reads, "Authors should use "&amp;" (ASCII decimal 38) 
+                // instead of "&" to avoid confusion with the beginning of a character 
+                // reference (entity reference open delimiter). 
+                if (cleanLength > 0)
+                {
+                    writer.write(chars, cleanStart, cleanLength);
+                    cleanLength = 0;
+                } 
+                writer.write("&amp;");
+                cleanStart = i + 1; 
+            }
+            else
+            {
+                // no processing for this character, just count how
+                // many characters in a row that we have that need no processing
+                cleanLength++;
+            }
+        }
+        
+        // are there any clean characters at the end of the array
+        // that we haven't processed yet?
+        if (cleanLength > 1)
+        {
+            // if the whole string can be written out as-is do so
+            // otherwise write out the clean chars at the end of the
+            // array
+            if (cleanStart == 0)
+                writer.write(string);
+            else
+                writer.write(chars, cleanStart, cleanLength);
+        }
+        else if (cleanLength == 1)
+        {
+            // a little optimization for 1 clean character
+            // (we could have let the previous if(...) handle them all)
+            writer.write(ch);
+        }
+    }
+
+    /**
+     * Writes the specified <var>string</var> after substituting <VAR>specials</VAR>,
+     * and UTF-16 surrogates for character references <CODE>&amp;#xnn</CODE>.
+     *
+     * @param   string      String to convert to XML format.
+     * @param   encoding    CURRENTLY NOT IMPLEMENTED.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void writeAttrString(
+        final java.io.Writer writer, String string, String encoding)
+        throws IOException
+    {
+        final int end = string.length();
+        if (end > m_attrBuff.length)
+        {
+            m_attrBuff = new char[end * 2 + 1];
+        }
+        string.getChars(0, end, m_attrBuff, 0);
+        final char[] chars = m_attrBuff;
+
+        
+
+        int cleanStart = 0;
+        int cleanLength = 0;
+
+        char ch = 0;
+        for (int i = 0; i < end; i++)
+        {
+            ch = chars[i];
+
+            // System.out.println("SPECIALSSIZE: "+SPECIALSSIZE);
+            // System.out.println("ch: "+(int)ch);
+            // System.out.println("m_maxCharacter: "+(int)m_maxCharacter);
+            // System.out.println("m_attrCharsMap[ch]: "+(int)m_attrCharsMap[ch]);
+            if (escapingNotNeeded(ch) && (!m_charInfo.shouldMapAttrChar(ch)))
+            {
+                cleanLength++;
+            }
+            else if ('<' == ch || '>' == ch)
+            {
+                cleanLength++; // no escaping in this case, as specified in 15.2
+            }
+            else if (
+                ('&' == ch) && ((i + 1) < end) && ('{' == chars[i + 1]))
+            {
+                cleanLength++; // no escaping in this case, as specified in 15.2
+            }
+            else
+            {
+                if (cleanLength > 0)
+                {
+                    writer.write(chars,cleanStart,cleanLength);
+                    cleanLength = 0;
+                }
+                int pos = accumDefaultEntity(writer, ch, i, chars, end, false, true);
+
+                if (i != pos)
+                {
+                    i = pos - 1;
+                }
+                else
+                {
+                    if (Encodings.isHighUTF16Surrogate(ch))
+                    {
+ 
+                            writeUTF16Surrogate(ch, chars, i, end);
+                            i++; // two input characters processed
+                                 // this increments by one and the for()
+                                 // loop itself increments by another one.
+                    }
+
+                    // The next is kind of a hack to keep from escaping in the case 
+                    // of Shift_JIS and the like.
+
+                    /*
+                    else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF)
+                    && (ch != 160))
+                    {
+                    writer.write(ch);  // no escaping in this case
+                    }
+                    else
+                    */
+                    String outputStringForChar = m_charInfo.getOutputStringForChar(ch);
+                    if (null != outputStringForChar)
+                    {
+                        writer.write(outputStringForChar);
+                    }
+                    else if (escapingNotNeeded(ch))
+                    {
+                        writer.write(ch); // no escaping in this case
+                    }
+                    else
+                    {
+                        writer.write("&#");
+                        writer.write(Integer.toString(ch));
+                        writer.write(';');
+                    }
+                }
+                cleanStart = i + 1;
+            }
+        } // end of for()
+        
+        // are there any clean characters at the end of the array
+        // that we haven't processed yet?
+        if (cleanLength > 1)
+        {
+            // if the whole string can be written out as-is do so
+            // otherwise write out the clean chars at the end of the
+            // array
+            if (cleanStart == 0)
+                writer.write(string);
+            else
+                writer.write(chars, cleanStart, cleanLength);
+        }
+        else if (cleanLength == 1)
+        {
+            // a little optimization for 1 clean character
+            // (we could have let the previous if(...) handle them all)
+            writer.write(ch);
+        }
+    }
+
+
+
+    /**
+     * Receive notification of character data.
+     *
+     * <p>The Parser will call this method to report each chunk of
+     * character data.  SAX parsers may return all contiguous character
+     * data in a single chunk, or they may split it into several
+     * chunks; however, all of the characters in any single event
+     * must come from the same external entity, so that the Locator
+     * provides useful information.</p>
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Note that some parsers will report whitespace using the
+     * ignorableWhitespace() method rather than this one (validating
+     * parsers must do so).</p>
+     *
+     * @param chars The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #ignorableWhitespace
+     * @see org.xml.sax.Locator
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public final void characters(char chars[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+
+        if (m_elemContext.m_isRaw)
+        { 
+            try
+            {
+                // Clean up some pending issues.
+                if (m_elemContext.m_startTagOpen)
+                {
+                    closeStartTag();
+                    m_elemContext.m_startTagOpen = false;
+                }
+                
+                m_ispreserve = true;
+                
+                writeNormalizedChars(chars, start, length, false, m_lineSepUse);
+                
+                // time to generate characters event
+                if (m_tracer != null)
+                    super.fireCharEvent(chars, start, length);
+                
+                return;
+            }
+            catch (IOException ioe)
+            {
+                throw new org.xml.sax.SAXException(
+                    Utils.messages.createMessage(MsgKey.ER_OIERROR,null),ioe);
+            }
+        }
+        else
+        {
+            super.characters(chars, start, length);
+        }
+    }
+
+    /**
+     *  Receive notification of cdata.
+     *
+     *  <p>The Parser will call this method to report each chunk of
+     *  character data.  SAX parsers may return all contiguous character
+     *  data in a single chunk, or they may split it into several
+     *  chunks; however, all of the characters in any single event
+     *  must come from the same external entity, so that the Locator
+     *  provides useful information.</p>
+     *
+     *  <p>The application must not attempt to read from the array
+     *  outside of the specified range.</p>
+     *
+     *  <p>Note that some parsers will report whitespace using the
+     *  ignorableWhitespace() method rather than this one (validating
+     *  parsers must do so).</p>
+     *
+     *  @param ch The characters from the XML document.
+     *  @param start The start position in the array.
+     *  @param length The number of characters to read from the array.
+     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *             wrapping another exception.
+     *  @see #ignorableWhitespace
+     *  @see org.xml.sax.Locator
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public final void cdata(char ch[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+
+        if ((null != m_elemContext.m_elementName)
+            && (m_elemContext.m_elementName.equalsIgnoreCase("SCRIPT")
+                || m_elemContext.m_elementName.equalsIgnoreCase("STYLE")))
+        {
+            try
+            {
+                if (m_elemContext.m_startTagOpen)
+                {
+                    closeStartTag();
+                    m_elemContext.m_startTagOpen = false;
+                }
+
+                m_ispreserve = true;
+
+                if (shouldIndent())
+                    indent();
+
+                // writer.write(ch, start, length);
+                writeNormalizedChars(ch, start, length, true, m_lineSepUse);
+            }
+            catch (IOException ioe)
+            {
+                throw new org.xml.sax.SAXException(
+                    Utils.messages.createMessage(
+                        MsgKey.ER_OIERROR,
+                        null),
+                    ioe);
+                //"IO error", ioe);
+            }
+        }
+        else
+        {
+            super.cdata(ch, start, length);
+        }
+    }
+
+    /**
+     *  Receive notification of a processing instruction.
+     *
+     *  @param target The processing instruction target.
+     *  @param data The processing instruction data, or null if
+     *         none was supplied.
+     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *             wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void processingInstruction(String target, String data)
+        throws org.xml.sax.SAXException
+    {
+
+        // Process any pending starDocument and startElement first.
+        flushPending(); 
+        
+        // Use a fairly nasty hack to tell if the next node is supposed to be 
+        // unescaped text.
+        if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
+        {
+            startNonEscaping();
+        }
+        else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING))
+        {
+            endNonEscaping();
+        }
+        else
+        {
+            try
+            {
+                // clean up any pending things first
+                if (m_elemContext.m_startTagOpen)
+                {
+                    closeStartTag();
+                    m_elemContext.m_startTagOpen = false;
+                }
+                else if (m_cdataTagOpen)
+                {
+                    closeCDATA();
+                }
+                else if (m_needToCallStartDocument)
+                {
+                    startDocumentInternal();
+                }
+            
+
+            /*
+             * Perhaps processing instructions can be written out in HTML before
+             * the DOCTYPE, in which case this could be emitted with the
+             * startElement call, that knows the name of the document element
+             * doing it right.
+             */
+            if (true == m_needToOutputDocTypeDecl)
+                outputDocTypeDecl("html"); // best guess for the upcoming element
+
+ 
+            if (shouldIndent())
+                indent();
+
+            final java.io.Writer writer = m_writer;
+            //writer.write("<?" + target);
+            writer.write("<?");
+            writer.write(target);
+
+            if (data.length() > 0 && !Character.isSpaceChar(data.charAt(0)))
+                writer.write(' '); 
+
+            //writer.write(data + ">"); // different from XML
+            writer.write(data); // different from XML
+            writer.write('>'); // different from XML
+
+            // Always output a newline char if not inside of an 
+            // element. The whitespace is not significant in that
+            // case.
+            if (m_elemContext.m_currentElemDepth <= 0)
+                outputLineSep();
+
+            m_startNewLine = true;
+            }
+            catch(IOException e)
+            {
+                throw new SAXException(e);
+            }
+        }
+               
+        // now generate the PI event
+        if (m_tracer != null)
+            super.fireEscapingEvent(target, data);
+     }
+
+    /**
+     * Receive notivication of a entityReference.
+     *
+     * @param name non-null reference to entity name string.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public final void entityReference(String name)
+        throws org.xml.sax.SAXException
+    {
+        try
+        {
+
+        final java.io.Writer writer = m_writer;
+        writer.write('&');
+        writer.write(name);
+        writer.write(';');
+        
+        } catch(IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+    /**
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public final void endElement(String elemName) throws SAXException
+    {
+        endElement(null, null, elemName);
+    }
+
+    /**
+     * Process the attributes, which means to write out the currently
+     * collected attributes to the writer. The attributes are not
+     * cleared by this method
+     * 
+     * @param writer the writer to write processed attributes to.
+     * @param nAttrs the number of attributes in m_attributes 
+     * to be processed
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void processAttributes(java.io.Writer writer, int nAttrs)
+        throws IOException,SAXException
+    {
+            /* 
+             * process the collected attributes
+             */
+            for (int i = 0; i < nAttrs; i++)
+            {
+                processAttribute(
+                    writer,
+                    m_attributes.getQName(i),
+                    m_attributes.getValue(i),
+                    m_elemContext.m_elementDesc);
+            }
+    }
+
+    /**
+     * For the enclosing elements starting tag write out out any attributes
+     * followed by ">". At this point we also mark if this element is
+     * a cdata-section-element.
+     *
+     *@throws org.xml.sax.SAXException
+     */
+    protected void closeStartTag() throws SAXException
+    {
+            try
+            {
+
+            // finish processing attributes, time to fire off the start element event
+            if (m_tracer != null)
+                super.fireStartElem(m_elemContext.m_elementName);  
+            
+            int nAttrs = m_attributes.getLength();   
+            if (nAttrs>0)
+            {
+                processAttributes(m_writer, nAttrs);
+                // clear attributes object for re-use with next element
+                m_attributes.clear();
+            }
+
+            m_writer.write('>');
+
+            /* At this point we have the prefix mappings now, so
+             * lets determine if the current element is specified in the cdata-
+             * section-elements list.
+             */
+            if (m_CdataElems != null) // if there are any cdata sections
+                m_elemContext.m_isCdataSection = isCdataSection();
+            if (m_doIndent)
+            {
+                m_isprevtext = false;
+                m_preserves.push(m_ispreserve);
+            }
+            
+            }
+            catch(IOException e)
+            {
+                throw new SAXException(e);
+            }
+    }
+    
+
+   
+        /**
+         * This method is used when a prefix/uri namespace mapping
+         * is indicated after the element was started with a
+         * startElement() and before and endElement().
+         * startPrefixMapping(prefix,uri) would be used before the
+         * startElement() call.
+         * @param uri the URI of the namespace
+         * @param prefix the prefix associated with the given URI.
+         *
+         * @see ExtendedContentHandler#namespaceAfterStartElement(String, String)
+         */
+        public void namespaceAfterStartElement(String prefix, String uri)
+            throws SAXException
+        {
+            // hack for XSLTC with finding URI for default namespace
+            if (m_elemContext.m_elementURI == null)
+            {
+                String prefix1 = getPrefixPart(m_elemContext.m_elementName);
+                if (prefix1 == null && EMPTYSTRING.equals(prefix))
+                {
+                    // the elements URI is not known yet, and it
+                    // doesn't have a prefix, and we are currently
+                    // setting the uri for prefix "", so we have
+                    // the uri for the element... lets remember it
+                    m_elemContext.m_elementURI = uri;
+                }
+            }            
+            startPrefixMapping(prefix,uri,false);
+        }
+
+    public void startDTD(String name, String publicId, String systemId)
+        throws SAXException
+    {
+        m_inDTD = true;
+        super.startDTD(name, publicId, systemId);
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     * @see #startDTD
+     */
+    public void endDTD() throws org.xml.sax.SAXException
+    {
+        m_inDTD = false;
+        /* for ToHTMLStream the DOCTYPE is entirely output in the
+         * startDocumentInternal() method, so don't do anything here
+         */
+    }
+    /**
+     * This method does nothing.
+     */
+    public void attributeDecl(
+        String eName,
+        String aName,
+        String type,
+        String valueDefault,
+        String value)
+        throws SAXException
+    {
+        // The internal DTD subset is not serialized by the ToHTMLStream serializer
+    }
+
+    /**
+     * This method does nothing.
+     */
+    public void elementDecl(String name, String model) throws SAXException
+    {
+        // The internal DTD subset is not serialized by the ToHTMLStream serializer
+    }
+    /**
+     * This method does nothing.
+     */
+    public void internalEntityDecl(String name, String value)
+        throws SAXException
+    {
+        // The internal DTD subset is not serialized by the ToHTMLStream serializer
+    }
+    /**
+     * This method does nothing.
+     */
+    public void externalEntityDecl(
+        String name,
+        String publicId,
+        String systemId)
+        throws SAXException
+    {
+        // The internal DTD subset is not serialized by the ToHTMLStream serializer
+    }
+
+    /**
+     * This method is used to add an attribute to the currently open element. 
+     * The caller has guaranted that this attribute is unique, which means that it
+     * not been seen before and will not be seen again.
+     * 
+     * @param name the qualified name of the attribute
+     * @param value the value of the attribute which can contain only
+     * ASCII printable characters characters in the range 32 to 127 inclusive.
+     * @param flags the bit values of this integer give optimization information.
+     */
+    public void addUniqueAttribute(String name, String value, int flags)
+        throws SAXException
+    {
+        try
+        {
+            final java.io.Writer writer = m_writer;
+            if ((flags & NO_BAD_CHARS) > 0 && m_htmlcharInfo.onlyQuotAmpLtGt)
+            {
+                // "flags" has indicated that the characters
+                // '>'  '<'   '&'  and '"' are not in the value and
+                // m_htmlcharInfo has recorded that there are no other
+                // entities in the range 0 to 127 so we write out the
+                // value directly
+                writer.write(' ');
+                writer.write(name);
+                writer.write("=\"");
+                writer.write(value);
+                writer.write('"');
+            }
+            else if (
+                (flags & HTML_ATTREMPTY) > 0
+                    && (value.length() == 0 || value.equalsIgnoreCase(name)))
+            {
+                writer.write(' ');
+                writer.write(name);
+            }
+            else
+            {
+                writer.write(' ');
+                writer.write(name);
+                writer.write("=\"");
+                if ((flags & HTML_ATTRURL) > 0)
+                {
+                    writeAttrURI(writer, value, m_specialEscapeURLs);
+                }
+                else
+                {
+                    writeAttrString(writer, value, this.getEncoding());
+                }
+                writer.write('"');
+            }
+        } catch (IOException e) {
+            throw new SAXException(e);
+        }
+    }
+
+    public void comment(char ch[], int start, int length)
+            throws SAXException
+    {
+        // The internal DTD subset is not serialized by the ToHTMLStream serializer
+        if (m_inDTD)
+            return;
+        
+        // Clean up some pending issues, just in case
+        // this call is coming right after a startElement()
+        // or we are in the middle of writing out CDATA
+        // or if a startDocument() call was not received
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+        else if (m_cdataTagOpen)
+        {
+            closeCDATA();
+        }
+        else if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+        }
+
+        /*
+         * Perhaps comments can be written out in HTML before the DOCTYPE.
+         * In this case we might delete this call to writeOutDOCTYPE, and
+         * it would be handled within the startElement() call.
+         */
+        if (m_needToOutputDocTypeDecl)
+            outputDocTypeDecl("html"); // best guess for the upcoming element
+
+        super.comment(ch, start, length);
+    }
+    
+    public boolean reset()
+    {
+        boolean ret = super.reset();
+        if (!ret)
+            return false;
+        resetToHTMLStream();
+        return true;        
+    }
+    
+    private void resetToHTMLStream()
+    {
+        // m_htmlcharInfo remains unchanged
+        // m_htmlInfo = null;  // Don't reset
+        m_inBlockElem = false;
+        m_inDTD = false;
+        m_omitMetaTag = false;
+        m_specialEscapeURLs = true;     
+    }
+    
+    static class Trie
+    {
+        /**
+         * A digital search trie for 7-bit ASCII text
+         * The API is a subset of java.util.Hashtable
+         * The key must be a 7-bit ASCII string
+         * The value may be any Java Object
+         * One can get an object stored in a trie from its key, 
+         * but the search is either case sensitive or case 
+         * insensitive to the characters in the key, and this
+         * choice of sensitivity or insensitivity is made when
+         * the Trie is created, before any objects are put in it.
+         * 
+         * This class is a copy of the one in org.apache.xml.utils. 
+         * It exists to cut the serializers dependancy on that package.
+         *  
+         * @xsl.usage internal
+         */
+
+        /** Size of the m_nextChar array.  */
+        public static final int ALPHA_SIZE = 128;
+
+        /** The root node of the tree.    */
+        final Node m_Root;
+
+        /** helper buffer to convert Strings to char arrays */
+        private char[] m_charBuffer = new char[0];
+
+        /** true if the search for an object is lower case only with the key */
+        private final boolean m_lowerCaseOnly;
+
+        /**
+         * Construct the trie that has a case insensitive search.
+         */
+        public Trie()
+        {
+            m_Root = new Node();
+            m_lowerCaseOnly = false;
+        }
+
+        /**
+         * Construct the trie given the desired case sensitivity with the key.
+         * @param lowerCaseOnly true if the search keys are to be loser case only,
+         * not case insensitive.
+         */
+        public Trie(boolean lowerCaseOnly)
+        {
+            m_Root = new Node();
+            m_lowerCaseOnly = lowerCaseOnly;
+        }
+
+        /**
+         * Put an object into the trie for lookup.
+         *
+         * @param key must be a 7-bit ASCII string
+         * @param value any java object.
+         *
+         * @return The old object that matched key, or null.
+         */
+        public Object put(String key, Object value)
+        {
+
+            final int len = key.length();
+            if (len > m_charBuffer.length)
+            {
+                // make the biggest buffer ever needed in get(String)
+                m_charBuffer = new char[len];
+            }
+
+            Node node = m_Root;
+
+            for (int i = 0; i < len; i++)
+            {
+                Node nextNode =
+                    node.m_nextChar[Character.toLowerCase(key.charAt(i))];
+
+                if (nextNode != null)
+                {
+                    node = nextNode;
+                }
+                else
+                {
+                    for (; i < len; i++)
+                    {
+                        Node newNode = new Node();
+                        if (m_lowerCaseOnly)
+                        {
+                            // put this value into the tree only with a lower case key 
+                            node.m_nextChar[Character.toLowerCase(
+                                key.charAt(i))] =
+                                newNode;
+                        }
+                        else
+                        {
+                            // put this value into the tree with a case insensitive key
+                            node.m_nextChar[Character.toUpperCase(
+                                key.charAt(i))] =
+                                newNode;
+                            node.m_nextChar[Character.toLowerCase(
+                                key.charAt(i))] =
+                                newNode;
+                        }
+                        node = newNode;
+                    }
+                    break;
+                }
+            }
+
+            Object ret = node.m_Value;
+
+            node.m_Value = value;
+
+            return ret;
+        }
+
+        /**
+         * Get an object that matches the key.
+         *
+         * @param key must be a 7-bit ASCII string
+         *
+         * @return The object that matches the key, or null.
+         */
+        public Object get(final String key)
+        {
+
+            final int len = key.length();
+
+            /* If the name is too long, we won't find it, this also keeps us
+             * from overflowing m_charBuffer
+             */
+            if (m_charBuffer.length < len)
+                return null;
+
+            Node node = m_Root;
+            switch (len) // optimize the look up based on the number of chars
+            {
+                // case 0 looks silly, but the generated bytecode runs
+                // faster for lookup of elements of length 2 with this in
+                // and a fair bit faster.  Don't know why.
+                case 0 :
+                    {
+                        return null;
+                    }
+
+                case 1 :
+                    {
+                        final char ch = key.charAt(0);
+                        if (ch < ALPHA_SIZE)
+                        {
+                            node = node.m_nextChar[ch];
+                            if (node != null)
+                                return node.m_Value;
+                        }
+                        return null;
+                    }
+                    //                comment out case 2 because the default is faster            
+                    //                case 2 :
+                    //                    {
+                    //                        final char ch0 = key.charAt(0);
+                    //                        final char ch1 = key.charAt(1);
+                    //                        if (ch0 < ALPHA_SIZE && ch1 < ALPHA_SIZE)
+                    //                        {
+                    //                            node = node.m_nextChar[ch0];
+                    //                            if (node != null)
+                    //                            {
+                    //                        
+                    //                                if (ch1 < ALPHA_SIZE) 
+                    //                                {
+                    //                                    node = node.m_nextChar[ch1];
+                    //                                    if (node != null)
+                    //                                        return node.m_Value;
+                    //                                }
+                    //                            }
+                    //                        }
+                    //                        return null;
+                    //                   }
+                default :
+                    {
+                        for (int i = 0; i < len; i++)
+                        {
+                            // A thread-safe way to loop over the characters
+                            final char ch = key.charAt(i);
+                            if (ALPHA_SIZE <= ch)
+                            {
+                                // the key is not 7-bit ASCII so we won't find it here
+                                return null;
+                            }
+
+                            node = node.m_nextChar[ch];
+                            if (node == null)
+                                return null;
+                        }
+
+                        return node.m_Value;
+                    }
+            }
+        }
+
+        /**
+         * The node representation for the trie.
+         * @xsl.usage internal
+         */
+        private class Node
+        {
+
+            /**
+             * Constructor, creates a Node[ALPHA_SIZE].
+             */
+            Node()
+            {
+                m_nextChar = new Node[ALPHA_SIZE];
+                m_Value = null;
+            }
+
+            /** The next nodes.   */
+            final Node m_nextChar[];
+
+            /** The value.   */
+            Object m_Value;
+        }
+        /**
+         * Construct the trie from another Trie.
+         * Both the existing Trie and this new one share the same table for
+         * lookup, and it is assumed that the table is fully populated and
+         * not changing anymore.
+         * 
+         * @param existingTrie the Trie that this one is a copy of.
+         */
+        public Trie(Trie existingTrie)
+        {
+            // copy some fields from the existing Trie into this one.
+            m_Root = existingTrie.m_Root;
+            m_lowerCaseOnly = existingTrie.m_lowerCaseOnly;
+
+            // get a buffer just big enough to hold the longest key in the table.
+            int max = existingTrie.getLongestKeyLength();
+            m_charBuffer = new char[max];
+        }
+
+        /**
+         * Get an object that matches the key.
+         * This method is faster than get(), but is not thread-safe.
+         *
+         * @param key must be a 7-bit ASCII string
+         *
+         * @return The object that matches the key, or null.
+         */
+        public Object get2(final String key)
+        {
+
+            final int len = key.length();
+
+            /* If the name is too long, we won't find it, this also keeps us
+             * from overflowing m_charBuffer
+             */
+            if (m_charBuffer.length < len)
+                return null;
+
+            Node node = m_Root;
+            switch (len) // optimize the look up based on the number of chars
+            {
+                // case 0 looks silly, but the generated bytecode runs
+                // faster for lookup of elements of length 2 with this in
+                // and a fair bit faster.  Don't know why.
+                case 0 :
+                    {
+                        return null;
+                    }
+
+                case 1 :
+                    {
+                        final char ch = key.charAt(0);
+                        if (ch < ALPHA_SIZE)
+                        {
+                            node = node.m_nextChar[ch];
+                            if (node != null)
+                                return node.m_Value;
+                        }
+                        return null;
+                    }
+                default :
+                    {
+                        /* Copy string into array. This is not thread-safe because
+                         * it modifies the contents of m_charBuffer. If multiple
+                         * threads were to use this Trie they all would be
+                         * using this same array (not good). So this 
+                         * method is not thread-safe, but it is faster because
+                         * converting to a char[] and looping over elements of
+                         * the array is faster than a String's charAt(i).
+                         */
+                        key.getChars(0, len, m_charBuffer, 0);
+
+                        for (int i = 0; i < len; i++)
+                        {
+                            final char ch = m_charBuffer[i];
+                            if (ALPHA_SIZE <= ch)
+                            {
+                                // the key is not 7-bit ASCII so we won't find it here
+                                return null;
+                            }
+
+                            node = node.m_nextChar[ch];
+                            if (node == null)
+                                return null;
+                        }
+
+                        return node.m_Value;
+                    }
+            }
+        }
+
+        /**
+         * Get the length of the longest key used in the table. 
+         */
+        public int getLongestKeyLength()
+        {
+            return m_charBuffer.length;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToSAXHandler.java b/src/main/java/org/apache/xml/serializer/ToSAXHandler.java
new file mode 100644
index 0000000..97adcba
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToSAXHandler.java
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToSAXHandler.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.util.Vector;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class is used to provide a base behavior to be inherited
+ * by other To...SAXHandler serializers.
+ * 
+ * This class is not a public API.
+ * 
+ * @xsl.usage internal
+ */
+public abstract class ToSAXHandler extends SerializerBase 
+{
+    public ToSAXHandler()
+    {
+    }
+
+    public ToSAXHandler(
+        ContentHandler hdlr,
+        LexicalHandler lex,
+        String encoding)
+    {
+        setContentHandler(hdlr);
+        setLexHandler(lex);
+        setEncoding(encoding);
+    }
+    public ToSAXHandler(ContentHandler handler, String encoding)
+    {
+        setContentHandler(handler);
+        setEncoding(encoding);
+    }
+
+    /**
+     * Underlying SAX handler. Taken from XSLTC
+     */
+    protected ContentHandler m_saxHandler;
+
+    /**
+     * Underlying LexicalHandler. Taken from XSLTC
+     */
+    protected LexicalHandler m_lexHandler;
+
+    /**
+     * A startPrefixMapping() call on a ToSAXHandler will pass that call
+     * on to the wrapped ContentHandler, but should we also mirror these calls
+     * with matching attributes, if so this field is true.
+     * For example if this field is true then a call such as
+     * startPrefixMapping("prefix1","uri1") will also cause the additional
+     * internally generated attribute xmlns:prefix1="uri1" to be effectively added
+     * to the attributes passed to the wrapped ContentHandler.
+     */ 
+    private boolean m_shouldGenerateNSAttribute = true;
+    
+    /** If this is true, then the content handler wrapped by this
+     * serializer implements the TransformState interface which
+     * will give the content handler access to the state of
+     * the transform. */
+    protected TransformStateSetter m_state = null;
+
+    /**
+     * Pass callback to the SAX Handler
+     */
+    protected void startDocumentInternal() throws SAXException
+    {
+        if (m_needToCallStartDocument)  
+        {
+            super.startDocumentInternal();
+
+            m_saxHandler.startDocument();
+            m_needToCallStartDocument = false;
+        }
+    }
+    /**
+     * Do nothing.
+     * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String)
+     */
+    public void startDTD(String arg0, String arg1, String arg2)
+        throws SAXException
+    {
+        // do nothing for now
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param characters The string of characters to process.
+     *
+     * @throws org.xml.sax.SAXException
+     *
+     * @see ExtendedContentHandler#characters(String)
+     */
+    public void characters(String characters) throws SAXException
+    {
+        final int len = characters.length();
+        if (len > m_charsBuff.length)
+        {
+           m_charsBuff = new char[len*2 + 1];             
+        }
+        characters.getChars(0,len, m_charsBuff, 0);   
+        characters(m_charsBuff, 0, len);
+    }
+
+    /**
+     * Receive notification of a comment.
+     *
+     * @see ExtendedLexicalHandler#comment(String)
+     */
+    public void comment(String comment) throws SAXException
+    {
+        flushPending();
+
+        // Ignore if a lexical handler has not been set
+        if (m_lexHandler != null)
+        {
+            final int len = comment.length();
+            if (len > m_charsBuff.length)
+            {
+               m_charsBuff = new char[len*2 + 1];              
+            }
+            comment.getChars(0,len, m_charsBuff, 0);            
+            m_lexHandler.comment(m_charsBuff, 0, len);
+            // time to fire off comment event
+            if (m_tracer != null)
+                super.fireCommentEvent(m_charsBuff, 0, len);
+        }
+
+    }
+
+    /**
+     * Do nothing as this is an abstract class. All subclasses will need to
+     * define their behavior if it is different.
+     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
+     */
+    public void processingInstruction(String target, String data)
+        throws SAXException
+    {
+        // Redefined in SAXXMLOutput
+    }
+
+    protected void closeStartTag() throws SAXException
+    {
+    }
+
+    protected void closeCDATA() throws SAXException
+    {
+        // Redefined in SAXXMLOutput
+    }
+    
+    /**
+     * Receive notification of the beginning of an element, although this is a
+     * SAX method additional namespace or attribute information can occur before
+     * or after this call, that is associated with this element.
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#startElement
+     * @see org.xml.sax.ContentHandler#endElement
+     * @see org.xml.sax.AttributeList
+     *
+     * @throws org.xml.sax.SAXException
+     *
+     * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes)
+     */
+    public void startElement(
+        String arg0,
+        String arg1,
+        String arg2,
+        Attributes arg3)
+        throws SAXException
+    {
+        if (m_state != null) {
+            m_state.resetState(getTransformer());
+        }
+
+        // fire off the start element event
+        if (m_tracer != null)
+            super.fireStartElem(arg2);
+    }
+
+    /**
+     * Sets the LexicalHandler.
+     * @param _lexHandler The LexicalHandler to set
+     */
+    public void setLexHandler(LexicalHandler _lexHandler)
+    {
+        this.m_lexHandler = _lexHandler;
+    }
+
+    /**
+     * Sets the SAX ContentHandler.
+     * @param _saxHandler The ContentHandler to set
+     */
+    public void setContentHandler(ContentHandler _saxHandler)
+    {
+        this.m_saxHandler = _saxHandler;
+        if (m_lexHandler == null && _saxHandler instanceof LexicalHandler)
+        {
+            // we are not overwriting an existing LexicalHandler, and _saxHandler
+            // is also implements LexicalHandler, so lets use it
+            m_lexHandler = (LexicalHandler) _saxHandler;
+        }
+    }
+
+    /**
+     * Does nothing. The setting of CDATA section elements has an impact on
+     * stream serializers.
+     * @see SerializationHandler#setCdataSectionElements(java.util.Vector)
+     */
+    public void setCdataSectionElements(Vector URI_and_localNames)
+    {
+        // do nothing
+    }
+    
+    /** Set whether or not namespace declarations (e.g. 
+     * xmlns:foo) should appear as attributes of 
+     * elements
+     * @param doOutputNSAttr whether or not namespace declarations
+     * should appear as attributes
+     */
+    public void setShouldOutputNSAttr(boolean doOutputNSAttr)
+    {
+        m_shouldGenerateNSAttribute = doOutputNSAttr;
+    }
+ 
+    /** 
+     * Returns true if namespace declarations from calls such as
+     * startPrefixMapping("prefix1","uri1") should
+     * also be mirrored with self generated additional attributes of elements 
+     * that declare the namespace, for example the attribute xmlns:prefix1="uri1"
+     */
+    boolean getShouldOutputNSAttr()
+    {
+        return m_shouldGenerateNSAttribute;
+    }
+
+    /**
+     * This method flushes any pending events, which can be startDocument()
+     * closing the opening tag of an element, or closing an open CDATA section.
+     */
+    public void flushPending() throws SAXException
+    {
+    
+            if (m_needToCallStartDocument)
+            {
+                startDocumentInternal();
+                m_needToCallStartDocument = false;
+            }
+
+            if (m_elemContext.m_startTagOpen)
+            {
+                closeStartTag();
+                m_elemContext.m_startTagOpen = false;
+            }
+            
+            if (m_cdataTagOpen)
+            {
+                closeCDATA();
+                m_cdataTagOpen = false;
+            }
+
+    }
+
+    /**
+     * Pass in a reference to a TransformState object, which
+     * can be used during SAX ContentHandler events to obtain
+     * information about he state of the transformation. This
+     * method will be called  before each startDocument event.
+     *
+     * @param ts A reference to a TransformState object
+     */
+    public void setTransformState(TransformStateSetter ts) {
+        this.m_state = ts;
+    }
+    
+    /**
+     * Receives notification that an element starts, but attributes are not
+     * fully known yet.
+     *
+     * @param uri the URI of the namespace of the element (optional)
+     * @param localName the element name, but without prefix (optional)
+     * @param qName the element name, with prefix, if any (required)
+     *
+     * @see ExtendedContentHandler#startElement(String, String, String)
+     */
+    public void startElement(String uri, String localName, String qName)
+        throws SAXException {
+            
+        if (m_state != null) {
+            m_state.resetState(getTransformer());
+        }
+
+        // fire off the start element event
+        if (m_tracer != null)
+            super.fireStartElem(qName);         
+    }
+
+    /**
+     * An element starts, but attributes are not fully known yet.
+     *
+     * @param qName the element name, with prefix (if any).
+
+     * @see ExtendedContentHandler#startElement(String)
+     */
+    public void startElement(String qName) throws SAXException {
+        if (m_state != null) {
+            m_state.resetState(getTransformer());
+        }        
+        // fire off the start element event
+        if (m_tracer != null)
+            super.fireStartElem(qName);              
+    }
+    
+    /**
+     * This method gets the node's value as a String and uses that String as if
+     * it were an input character notification.
+     * @param node the Node to serialize
+     * @throws org.xml.sax.SAXException
+     */    
+    public void characters(org.w3c.dom.Node node)
+        throws org.xml.sax.SAXException
+    {
+        // remember the current node
+        if (m_state != null)
+        {
+            m_state.setCurrentNode(node);
+        }
+        
+        // Get the node's value as a String and use that String as if
+        // it were an input character notification.
+        String data = node.getNodeValue();
+        if (data != null) {
+            this.characters(data);
+        }
+    }    
+
+    /**
+     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
+     */
+    public void fatalError(SAXParseException exc) throws SAXException {
+        super.fatalError(exc);
+        
+        m_needToCallStartDocument = false;
+        
+        if (m_saxHandler instanceof ErrorHandler) {
+            ((ErrorHandler)m_saxHandler).fatalError(exc);            
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ErrorHandler#error(SAXParseException)
+     */
+    public void error(SAXParseException exc) throws SAXException {
+        super.error(exc);
+        
+        if (m_saxHandler instanceof ErrorHandler)
+            ((ErrorHandler)m_saxHandler).error(exc);        
+        
+    }
+
+    /**
+     * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
+     */
+    public void warning(SAXParseException exc) throws SAXException {
+        super.warning(exc);
+        
+        if (m_saxHandler instanceof ErrorHandler)
+            ((ErrorHandler)m_saxHandler).warning(exc);        
+    }
+    
+       
+    /**
+     * Try's to reset the super class and reset this class for 
+     * re-use, so that you don't need to create a new serializer 
+     * (mostly for performance reasons).
+     * 
+     * @return true if the class was successfuly reset.
+     * @see Serializer#reset()
+     */
+    public boolean reset()
+    {
+        boolean wasReset = false;
+        if (super.reset())
+        {
+            resetToSAXHandler();
+            wasReset = true;
+        }
+        return wasReset;
+    }
+    
+    /**
+     * Reset all of the fields owned by ToSAXHandler class
+     *
+     */
+    private void resetToSAXHandler()
+    {
+        this.m_lexHandler = null;
+        this.m_saxHandler = null;
+        this.m_state = null;
+        this.m_shouldGenerateNSAttribute = false;
+    }  
+
+    /**
+     * Add a unique attribute
+     */
+    public void addUniqueAttribute(String qName, String value, int flags)
+        throws SAXException
+    {
+        addAttribute(qName, value); 
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToStream.java b/src/main/java/org/apache/xml/serializer/ToStream.java
new file mode 100644
index 0000000..c56f747
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToStream.java
@@ -0,0 +1,3601 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToStream.java 475894 2006-11-16 19:43:59Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.EmptyStackException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.apache.xml.serializer.utils.WrappedRuntimeException;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * This abstract class is a base class for other stream 
+ * serializers (xml, html, text ...) that write output to a stream.
+ * 
+ * @xsl.usage internal
+ */
+abstract public class ToStream extends SerializerBase
+{
+
+    private static final String COMMENT_BEGIN = "<!--";
+    private static final String COMMENT_END = "-->";
+
+    /** Stack to keep track of disabling output escaping. */
+    protected BoolStack m_disableOutputEscapingStates = new BoolStack();
+
+
+    /**
+     * The encoding information associated with this serializer.
+     * Although initially there is no encoding,
+     * there is a dummy EncodingInfo object that will say
+     * that every character is in the encoding. This is useful
+     * for a serializer that is in temporary output state and has
+     * no associated encoding. A serializer in final output state
+     * will have an encoding, and will worry about whether 
+     * single chars or surrogate pairs of high/low chars form
+     * characters in the output encoding. 
+     */
+    EncodingInfo m_encodingInfo = new EncodingInfo(null,null, '\u0000');
+    
+    /**
+     * Stack to keep track of whether or not we need to
+     * preserve whitespace.
+     * 
+     * Used to push/pop values used for the field m_ispreserve, but
+     * m_ispreserve is only relevant if m_doIndent is true.
+     * If m_doIndent is false this field has no impact.
+     * 
+     */
+    protected BoolStack m_preserves = new BoolStack();
+
+    /**
+     * State flag to tell if preservation of whitespace
+     * is important. 
+     * 
+     * Used only in shouldIndent() but only if m_doIndent is true.
+     * If m_doIndent is false this flag has no impact.
+     * 
+     */
+    protected boolean m_ispreserve = false;
+
+    /**
+     * State flag that tells if the previous node processed
+     * was text, so we can tell if we should preserve whitespace.
+     * 
+     * Used in endDocument() and shouldIndent() but
+     * only if m_doIndent is true. 
+     * If m_doIndent is false this flag has no impact.
+     */
+    protected boolean m_isprevtext = false;
+        
+    private static final char[] s_systemLineSep;
+    static {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        s_systemLineSep = ss.getSystemProperty("line.separator").toCharArray();
+    }
+    
+    /**
+     * The system line separator for writing out line breaks.
+     * The default value is from the system property,
+     * but this value can be set through the xsl:output
+     * extension attribute xalan:line-separator.
+     */
+    protected char[] m_lineSep = s_systemLineSep;
+        
+        
+    /**
+     * True if the the system line separator is to be used.
+     */    
+    protected boolean m_lineSepUse = true;    
+
+    /**
+     * The length of the line seperator, since the write is done
+     * one character at a time.
+     */
+    protected int m_lineSepLen = m_lineSep.length;
+
+    /**
+     * Map that tells which characters should have special treatment, and it
+     *  provides character to entity name lookup.
+     */
+    protected CharInfo m_charInfo;
+
+    /** True if we control the buffer, and we should flush the output on endDocument. */
+    boolean m_shouldFlush = true;
+
+    /**
+     * Add space before '/>' for XHTML.
+     */
+    protected boolean m_spaceBeforeClose = false;
+
+    /**
+     * Flag to signal that a newline should be added.
+     * 
+     * Used only in indent() which is called only if m_doIndent is true.
+     * If m_doIndent is false this flag has no impact.
+     */
+    boolean m_startNewLine;
+
+    /**
+     * Tells if we're in an internal document type subset.
+     */
+    protected boolean m_inDoctype = false;
+
+    /**
+       * Flag to quickly tell if the encoding is UTF8.
+       */
+    boolean m_isUTF8 = false;
+
+
+    /**
+     * remembers if we are in between the startCDATA() and endCDATA() callbacks
+     */
+    protected boolean m_cdataStartCalled = false;
+    
+    /**
+     * If this flag is true DTD entity references are not left as-is,
+     * which is exiting older behavior.
+     */
+    private boolean m_expandDTDEntities = true;
+  
+
+    /**
+     * Default constructor
+     */
+    public ToStream()
+    {
+    }
+
+    /**
+     * This helper method to writes out "]]>" when closing a CDATA section.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void closeCDATA() throws org.xml.sax.SAXException
+    {
+        try
+        {
+            m_writer.write(CDATA_DELIMITER_CLOSE);
+            // write out a CDATA section closing "]]>"
+            m_cdataTagOpen = false; // Remember that we have done so.
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     * Serializes the DOM node. Throws an exception only if an I/O
+     * exception occured while serializing.
+     *
+     * @param node Node to serialize.
+     * @throws IOException An I/O exception occured while serializing
+     */
+    public void serialize(Node node) throws IOException
+    {
+
+        try
+        {
+            TreeWalker walker =
+                new TreeWalker(this);
+
+            walker.traverse(node);
+        }
+        catch (org.xml.sax.SAXException se)
+        {
+            throw new WrappedRuntimeException(se);
+        }
+    }
+
+    /**
+     * Taken from XSLTC 
+     */
+    protected boolean m_escaping = true;
+
+    /**
+     * Flush the formatter's result stream.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected final void flushWriter() throws org.xml.sax.SAXException
+    {
+        final java.io.Writer writer = m_writer;
+        if (null != writer)
+        {
+            try
+            {
+                if (writer instanceof WriterToUTF8Buffered)
+                {
+                    if (m_shouldFlush)
+                         ((WriterToUTF8Buffered) writer).flush();
+                    else
+                         ((WriterToUTF8Buffered) writer).flushBuffer();
+                }
+                if (writer instanceof WriterToASCI)
+                {
+                    if (m_shouldFlush)
+                        writer.flush();
+                }
+                else
+                {
+                    // Flush always. 
+                    // Not a great thing if the writer was created 
+                    // by this class, but don't have a choice.
+                    writer.flush();
+                }
+            }
+            catch (IOException ioe)
+            {
+                throw new org.xml.sax.SAXException(ioe);
+            }
+        }
+    }
+
+    OutputStream m_outputStream;
+    /**
+     * Get the output stream where the events will be serialized to.
+     *
+     * @return reference to the result stream, or null of only a writer was
+     * set.
+     */
+    public OutputStream getOutputStream()
+    {
+        return m_outputStream;
+    }
+
+    // Implement DeclHandler
+
+    /**
+     *   Report an element type declaration.
+     *  
+     *   <p>The content model will consist of the string "EMPTY", the
+     *   string "ANY", or a parenthesised group, optionally followed
+     *   by an occurrence indicator.  The model will be normalized so
+     *   that all whitespace is removed,and will include the enclosing
+     *   parentheses.</p>
+     *  
+     *   @param name The element type name.
+     *   @param model The content model as a normalized string.
+     *   @exception SAXException The application may raise an exception.
+     */
+    public void elementDecl(String name, String model) throws SAXException
+    {
+        // Do not inline external DTD
+        if (m_inExternalDTD)
+            return;
+        try
+        {
+            final java.io.Writer writer = m_writer;
+            DTDprolog();
+
+            writer.write("<!ELEMENT ");
+            writer.write(name);
+            writer.write(' ');
+            writer.write(model);
+            writer.write('>');
+            writer.write(m_lineSep, 0, m_lineSepLen);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+    }
+
+    /**
+     * Report an internal entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param value The replacement text of the entity.
+     * @exception SAXException The application may raise an exception.
+     * @see #externalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void internalEntityDecl(String name, String value)
+        throws SAXException
+    {
+        // Do not inline external DTD
+        if (m_inExternalDTD)
+            return;
+        try
+        {
+            DTDprolog();
+            outputEntityDecl(name, value);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+    }
+
+    /**
+     * Output the doc type declaration.
+     *
+     * @param name non-null reference to document type name.
+     * NEEDSDOC @param value
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    void outputEntityDecl(String name, String value) throws IOException
+    {
+        final java.io.Writer writer = m_writer;
+        writer.write("<!ENTITY ");
+        writer.write(name);
+        writer.write(" \"");
+        writer.write(value);
+        writer.write("\">");
+        writer.write(m_lineSep, 0, m_lineSepLen);
+    }
+
+    /**
+     * Output a system-dependent line break.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected final void outputLineSep() throws IOException
+    {
+
+        m_writer.write(m_lineSep, 0, m_lineSepLen);
+    }
+
+    void setProp(String name, String val, boolean defaultVal) {
+        if (val != null) {
+
+
+            char first = getFirstCharLocName(name);
+            switch (first) {
+            case 'c':
+                if (OutputKeys.CDATA_SECTION_ELEMENTS.equals(name)) {
+                    String cdataSectionNames = val;
+                    addCdataSectionElements(cdataSectionNames);
+                }
+                break;
+            case 'd':
+                if (OutputKeys.DOCTYPE_SYSTEM.equals(name)) {
+                    this.m_doctypeSystem = val;
+                } else if (OutputKeys.DOCTYPE_PUBLIC.equals(name)) {
+                    this.m_doctypePublic = val;
+                    if (val.startsWith("-//W3C//DTD XHTML"))
+                        m_spaceBeforeClose = true;
+                }
+                break;
+            case 'e':
+                String newEncoding = val;
+                if (OutputKeys.ENCODING.equals(name)) {
+                    String possible_encoding = Encodings.getMimeEncoding(val);
+                    if (possible_encoding != null) {
+                        // if the encoding is being set, try to get the
+                        // preferred
+                        // mime-name and set it too.
+                        super.setProp("mime-name", possible_encoding,
+                                defaultVal);
+                    }
+                    final String oldExplicitEncoding = getOutputPropertyNonDefault(OutputKeys.ENCODING);
+                    final String oldDefaultEncoding  = getOutputPropertyDefault(OutputKeys.ENCODING);
+                    if ( (defaultVal && ( oldDefaultEncoding == null || !oldDefaultEncoding.equalsIgnoreCase(newEncoding)))
+                            || ( !defaultVal && (oldExplicitEncoding == null || !oldExplicitEncoding.equalsIgnoreCase(newEncoding) ))) {
+                       // We are trying to change the default or the non-default setting of the encoding to a different value
+                       // from what it was
+                       
+                       EncodingInfo encodingInfo = Encodings.getEncodingInfo(newEncoding);
+                       if (newEncoding != null && encodingInfo.name == null) {
+                        // We tried to get an EncodingInfo for Object for the given
+                        // encoding, but it came back with an internall null name
+                        // so the encoding is not supported by the JDK, issue a message.
+                        final String msg = Utils.messages.createMessage(
+                                MsgKey.ER_ENCODING_NOT_SUPPORTED,new Object[]{ newEncoding });
+                        
+                        final String msg2 = 
+                            "Warning: encoding \"" + newEncoding + "\" not supported, using "
+                                   + Encodings.DEFAULT_MIME_ENCODING;
+                        try {
+                                // Prepare to issue the warning message
+                                final Transformer tran = super.getTransformer();
+                                if (tran != null) {
+                                    final ErrorListener errHandler = tran
+                                            .getErrorListener();
+                                    // Issue the warning message
+                                    if (null != errHandler
+                                            && m_sourceLocator != null) {
+                                        errHandler
+                                                .warning(new TransformerException(
+                                                        msg, m_sourceLocator));
+                                        errHandler
+                                                .warning(new TransformerException(
+                                                        msg2, m_sourceLocator));
+                                    } else {
+                                        System.out.println(msg);
+                                        System.out.println(msg2);
+                                    }
+                                } else {
+                                    System.out.println(msg);
+                                    System.out.println(msg2);
+                                }
+                            } catch (Exception e) {
+                            }
+
+                            // We said we are using UTF-8, so use it
+                            newEncoding = Encodings.DEFAULT_MIME_ENCODING;
+                            val = Encodings.DEFAULT_MIME_ENCODING; // to store the modified value into the properties a little later
+                            encodingInfo = Encodings.getEncodingInfo(newEncoding);
+
+                        } 
+                       // The encoding was good, or was forced to UTF-8 above
+                       
+                       
+                       // If there is already a non-default set encoding and we 
+                       // are trying to set the default encoding, skip the this block
+                       // as the non-default value is already the one to use.
+                       if (defaultVal == false || oldExplicitEncoding == null) {
+                           m_encodingInfo = encodingInfo;
+                           if (newEncoding != null)
+                               m_isUTF8 = newEncoding.equals(Encodings.DEFAULT_MIME_ENCODING);
+                           
+                           // if there was a previously set OutputStream
+                           OutputStream os = getOutputStream();
+                           if (os != null) {
+                               Writer w = getWriter();
+                               
+                               // If the writer was previously set, but
+                               // set by the user, or if the new encoding is the same
+                               // as the old encoding, skip this block
+                               String oldEncoding = getOutputProperty(OutputKeys.ENCODING);
+                               if ((w == null || !m_writer_set_by_user) 
+                                       && !newEncoding.equalsIgnoreCase(oldEncoding)) {
+                                   // Make the change of encoding in our internal
+                                   // table, then call setOutputStreamInternal
+                                   // which will stomp on the old Writer (if any)
+                                   // with a new Writer with the new encoding.
+                                   super.setProp(name, val, defaultVal);
+                                   setOutputStreamInternal(os,false);
+                               }
+                           }
+                       }
+                    }
+                }
+                break;
+            case 'i':
+                if (OutputPropertiesFactory.S_KEY_INDENT_AMOUNT.equals(name)) {
+                    setIndentAmount(Integer.parseInt(val));
+                } else if (OutputKeys.INDENT.equals(name)) {
+                    boolean b = "yes".equals(val) ? true : false;
+                    m_doIndent = b;
+                }
+
+                break;
+            case 'l':
+                if (OutputPropertiesFactory.S_KEY_LINE_SEPARATOR.equals(name)) {
+                    m_lineSep = val.toCharArray();
+                    m_lineSepLen = m_lineSep.length;
+                }
+
+                break;
+            case 'm':
+                if (OutputKeys.MEDIA_TYPE.equals(name)) {
+                    m_mediatype = val;
+                }
+                break;
+            case 'o':
+                if (OutputKeys.OMIT_XML_DECLARATION.equals(name)) {
+                    boolean b = "yes".equals(val) ? true : false;
+                    this.m_shouldNotWriteXMLHeader = b;
+                }
+                break;
+            case 's':
+                // if standalone was explicitly specified
+                if (OutputKeys.STANDALONE.equals(name)) {
+                    if (defaultVal) {
+                        setStandaloneInternal(val);
+                    } else {
+                        m_standaloneWasSpecified = true;
+                        setStandaloneInternal(val);
+                    }
+                }
+
+                break;
+            case 'v':
+                if (OutputKeys.VERSION.equals(name)) {
+                    m_version = val;
+                }
+                break;
+            default:
+                break;
+
+            } 
+            super.setProp(name, val, defaultVal);
+        }
+    }
+    /**
+     * Specifies an output format for this serializer. It the
+     * serializer has already been associated with an output format,
+     * it will switch to the new format. This method should not be
+     * called while the serializer is in the process of serializing
+     * a document.
+     *
+     * @param format The output format to use
+     */
+    public void setOutputFormat(Properties format)
+    {
+
+        boolean shouldFlush = m_shouldFlush;
+        
+        if (format != null)
+        {
+            // Set the default values first,
+            // and the non-default values after that, 
+            // just in case there is some unexpected
+            // residual values left over from over-ridden default values
+            Enumeration propNames;
+            propNames = format.propertyNames();
+            while (propNames.hasMoreElements())
+            {
+                String key = (String) propNames.nextElement();
+                // Get the value, possibly a default value
+                String value = format.getProperty(key);
+                // Get the non-default value (if any).
+                String explicitValue = (String) format.get(key);
+                if (explicitValue == null && value != null) {
+                    // This is a default value
+                    this.setOutputPropertyDefault(key,value);
+                }
+                if (explicitValue != null) {
+                    // This is an explicit non-default value
+                    this.setOutputProperty(key,explicitValue);
+                }
+            } 
+        }   
+
+        // Access this only from the Hashtable level... we don't want to 
+        // get default properties.
+        String entitiesFileName =
+            (String) format.get(OutputPropertiesFactory.S_KEY_ENTITIES);
+
+        if (null != entitiesFileName)
+        {
+
+            String method = 
+                (String) format.get(OutputKeys.METHOD);
+            
+            m_charInfo = CharInfo.getCharInfo(entitiesFileName, method);
+        }
+
+
+         
+
+        m_shouldFlush = shouldFlush;
+    }
+
+    /**
+     * Returns the output format for this serializer.
+     *
+     * @return The output format in use
+     */
+    public Properties getOutputFormat() {
+        Properties def = new Properties();
+        {
+            Set s = getOutputPropDefaultKeys();
+            Iterator i = s.iterator();
+            while (i.hasNext()) {
+                String key = (String) i.next();
+                String val = getOutputPropertyDefault(key);
+                def.put(key, val);
+            }
+        }
+        
+        Properties props = new Properties(def);
+        {
+            Set s = getOutputPropKeys();
+            Iterator i = s.iterator();
+            while (i.hasNext()) {
+                String key = (String) i.next();
+                String val = getOutputPropertyNonDefault(key);
+                if (val != null)
+                    props.put(key, val);
+            }
+        }
+        return props;
+    }
+
+    /**
+     * Specifies a writer to which the document should be serialized.
+     * This method should not be called while the serializer is in
+     * the process of serializing a document.
+     *
+     * @param writer The output writer stream
+     */
+    public void setWriter(Writer writer)
+    {        
+        setWriterInternal(writer, true);
+    }
+    
+    private boolean m_writer_set_by_user;
+    private void setWriterInternal(Writer writer, boolean setByUser) {
+
+        m_writer_set_by_user = setByUser;
+        m_writer = writer;
+        // if we are tracing events we need to trace what
+        // characters are written to the output writer.
+        if (m_tracer != null) {
+            boolean noTracerYet = true;
+            Writer w2 = m_writer;
+            while (w2 instanceof WriterChain) {
+                if (w2 instanceof SerializerTraceWriter) {
+                    noTracerYet = false;
+                    break;
+                }
+                w2 = ((WriterChain)w2).getWriter();
+            }
+            if (noTracerYet)
+                m_writer = new SerializerTraceWriter(m_writer, m_tracer);
+        }
+    }
+    
+    /**
+     * Set if the operating systems end-of-line line separator should
+     * be used when serializing.  If set false NL character 
+     * (decimal 10) is left alone, otherwise the new-line will be replaced on
+     * output with the systems line separator. For example on UNIX this is
+     * NL, while on Windows it is two characters, CR NL, where CR is the
+     * carriage-return (decimal 13).
+     *  
+     * @param use_sytem_line_break True if an input NL is replaced with the 
+     * operating systems end-of-line separator.
+     * @return The previously set value of the serializer.
+     */
+    public boolean setLineSepUse(boolean use_sytem_line_break)
+    {
+        boolean oldValue = m_lineSepUse;
+        m_lineSepUse = use_sytem_line_break;
+        return oldValue;
+    }
+
+    /**
+     * Specifies an output stream to which the document should be
+     * serialized. This method should not be called while the
+     * serializer is in the process of serializing a document.
+     * <p>
+     * The encoding specified in the output properties is used, or
+     * if no encoding was specified, the default for the selected
+     * output method.
+     *
+     * @param output The output stream
+     */
+    public void setOutputStream(OutputStream output)
+    {
+        setOutputStreamInternal(output, true);
+    }
+    
+    private void setOutputStreamInternal(OutputStream output, boolean setByUser)
+    {
+        m_outputStream = output;
+        String encoding = getOutputProperty(OutputKeys.ENCODING);        
+        if (Encodings.DEFAULT_MIME_ENCODING.equalsIgnoreCase(encoding))
+        {
+            // We wrap the OutputStream with a writer, but
+            // not one set by the user
+            setWriterInternal(new WriterToUTF8Buffered(output), false);
+        } else if (
+                "WINDOWS-1250".equals(encoding)
+                || "US-ASCII".equals(encoding)
+                || "ASCII".equals(encoding))
+        {
+            setWriterInternal(new WriterToASCI(output), false);
+        } else if (encoding != null) {
+            Writer osw = null;
+                try
+                {
+                    osw = Encodings.getWriter(output, encoding);
+                }
+                catch (UnsupportedEncodingException uee)
+                {
+                    osw = null;
+                }
+
+            
+            if (osw == null) {
+                System.out.println(
+                    "Warning: encoding \""
+                        + encoding
+                        + "\" not supported"
+                        + ", using "
+                        + Encodings.DEFAULT_MIME_ENCODING);
+
+                encoding = Encodings.DEFAULT_MIME_ENCODING;
+                setEncoding(encoding);
+                try {
+                    osw = Encodings.getWriter(output, encoding);
+                } catch (UnsupportedEncodingException e) {
+                    // We can't really get here, UTF-8 is always supported
+                    // This try-catch exists to make the compiler happy
+                    e.printStackTrace();
+                }
+            }
+            setWriterInternal(osw,false);
+        }
+        else {
+            // don't have any encoding, but we have an OutputStream
+            Writer osw = new OutputStreamWriter(output);
+            setWriterInternal(osw,false);
+        }
+    }
+
+    /**
+     * @see SerializationHandler#setEscaping(boolean)
+     */
+    public boolean setEscaping(boolean escape)
+    {
+        final boolean temp = m_escaping;
+        m_escaping = escape;
+        return temp;
+
+    }
+
+
+    /**
+     * Might print a newline character and the indentation amount
+     * of the given depth.
+     * 
+     * @param depth the indentation depth (element nesting depth)
+     *
+     * @throws org.xml.sax.SAXException if an error occurs during writing.
+     */
+    protected void indent(int depth) throws IOException
+    {
+
+        if (m_startNewLine)
+            outputLineSep();
+        /* For m_indentAmount > 0 this extra test might be slower
+         * but Xalan's default value is 0, so this extra test
+         * will run faster in that situation.
+         */
+        if (m_indentAmount > 0)
+            printSpace(depth * m_indentAmount);
+
+    }
+    
+    /**
+     * Indent at the current element nesting depth.
+     * @throws IOException
+     */
+    protected void indent() throws IOException
+    {
+        indent(m_elemContext.m_currentElemDepth);
+    }
+    /**
+     * Prints <var>n</var> spaces.
+     * @param n         Number of spaces to print.
+     *
+     * @throws org.xml.sax.SAXException if an error occurs when writing.
+     */
+    private void printSpace(int n) throws IOException
+    {
+        final java.io.Writer writer = m_writer;
+        for (int i = 0; i < n; i++)
+        {
+            writer.write(' ');
+        }
+
+    }
+
+    /**
+     * Report an attribute type declaration.
+     *
+     * <p>Only the effective (first) declaration for an attribute will
+     * be reported.  The type will be one of the strings "CDATA",
+     * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+     * "ENTITIES", or "NOTATION", or a parenthesized token group with
+     * the separator "|" and all whitespace removed.</p>
+     *
+     * @param eName The name of the associated element.
+     * @param aName The name of the attribute.
+     * @param type A string representing the attribute type.
+     * @param valueDefault A string representing the attribute default
+     *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+     *        none of these applies.
+     * @param value A string representing the attribute's default value,
+     *        or null if there is none.
+     * @exception SAXException The application may raise an exception.
+     */
+    public void attributeDecl(
+        String eName,
+        String aName,
+        String type,
+        String valueDefault,
+        String value)
+        throws SAXException
+    {
+        // Do not inline external DTD
+        if (m_inExternalDTD)
+            return;
+        try
+        {
+            final java.io.Writer writer = m_writer;
+            DTDprolog();
+
+            writer.write("<!ATTLIST ");
+            writer.write(eName);
+            writer.write(' ');
+
+            writer.write(aName);
+            writer.write(' ');
+            writer.write(type);
+            if (valueDefault != null)
+            {
+                writer.write(' ');
+                writer.write(valueDefault);
+            }
+
+            //writer.write(" ");
+            //writer.write(value);
+            writer.write('>');
+            writer.write(m_lineSep, 0, m_lineSepLen);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     * Get the character stream where the events will be serialized to.
+     *
+     * @return Reference to the result Writer, or null.
+     */
+    public Writer getWriter()
+    {
+        return m_writer;
+    }
+
+    /**
+     * Report a parsed external entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param publicId The declared public identifier of the entity, or
+     *        null if none was declared.
+     * @param systemId The declared system identifier of the entity.
+     * @exception SAXException The application may raise an exception.
+     * @see #internalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void externalEntityDecl(
+        String name,
+        String publicId,
+        String systemId)
+        throws SAXException
+    {
+        try {
+            DTDprolog();
+            
+            m_writer.write("<!ENTITY ");            
+            m_writer.write(name);
+            if (publicId != null) {
+                m_writer.write(" PUBLIC \"");
+                m_writer.write(publicId);
+  
+            }
+            else {
+                m_writer.write(" SYSTEM \"");
+                m_writer.write(systemId);
+            }
+            m_writer.write("\" >");
+            m_writer.write(m_lineSep, 0, m_lineSepLen);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * Tell if this character can be written without escaping.
+     */
+    protected boolean escapingNotNeeded(char ch)
+    {
+        final boolean ret;
+        if (ch < 127)
+        {
+            // This is the old/fast code here, but is this 
+            // correct for all encodings?
+            if (ch >= CharInfo.S_SPACE || (CharInfo.S_LINEFEED == ch || 
+                    CharInfo.S_CARRIAGERETURN == ch || CharInfo.S_HORIZONAL_TAB == ch))
+                ret= true;
+            else
+                ret = false;
+        }
+        else {            
+            ret = m_encodingInfo.isInEncoding(ch);
+        }
+        return ret;
+    }
+
+    /**
+     * Once a surrogate has been detected, write out the pair of
+     * characters if it is in the encoding, or if there is no
+     * encoding, otherwise write out an entity reference
+     * of the value of the unicode code point of the character
+     * represented by the high/low surrogate pair.
+     * <p>
+     * An exception is thrown if there is no low surrogate in the pair,
+     * because the array ends unexpectely, or if the low char is there
+     * but its value is such that it is not a low surrogate.
+     *
+     * @param c the first (high) part of the surrogate, which
+     * must be confirmed before calling this method.
+     * @param ch Character array.
+     * @param i position Where the surrogate was detected.
+     * @param end The end index of the significant characters.
+     * @return 0 if the pair of characters was written out as-is,
+     * the unicode code point of the character represented by
+     * the surrogate pair if an entity reference with that value
+     * was written out. 
+     * 
+     * @throws IOException
+     * @throws org.xml.sax.SAXException if invalid UTF-16 surrogate detected.
+     */
+    protected int writeUTF16Surrogate(char c, char ch[], int i, int end)
+        throws IOException
+    {
+        int codePoint = 0;
+        if (i + 1 >= end)
+        {
+            throw new IOException(
+                Utils.messages.createMessage(
+                    MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    new Object[] { Integer.toHexString((int) c)}));
+        }
+        
+        final char high = c;
+        final char low = ch[i+1];
+        if (!Encodings.isLowUTF16Surrogate(low)) {
+            throw new IOException(
+                Utils.messages.createMessage(
+                    MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    new Object[] {
+                        Integer.toHexString((int) c)
+                            + " "
+                            + Integer.toHexString(low)}));
+        }
+
+        final java.io.Writer writer = m_writer;
+                
+        // If we make it to here we have a valid high, low surrogate pair
+        if (m_encodingInfo.isInEncoding(c,low)) {
+            // If the character formed by the surrogate pair
+            // is in the encoding, so just write it out
+            writer.write(ch,i,2);
+        }
+        else {
+            // Don't know what to do with this char, it is
+            // not in the encoding and not a high char in
+            // a surrogate pair, so write out as an entity ref
+            final String encoding = getEncoding();
+            if (encoding != null) {
+                /* The output encoding is known, 
+                 * so somthing is wrong.
+                  */
+                codePoint = Encodings.toCodePoint(high, low);
+                // not in the encoding, so write out a character reference
+                writer.write('&');
+                writer.write('#');
+                writer.write(Integer.toString(codePoint));
+                writer.write(';');
+            } else {
+                /* The output encoding is not known,
+                 * so just write it out as-is.
+                 */
+                writer.write(ch, i, 2);
+            }
+        }
+        // non-zero only if character reference was written out.
+        return codePoint;
+    }
+
+    /**
+     * Handle one of the default entities, return false if it
+     * is not a default entity.
+     *
+     * @param ch character to be escaped.
+     * @param i index into character array.
+     * @param chars non-null reference to character array.
+     * @param len length of chars.
+     * @param fromTextNode true if the characters being processed
+     * are from a text node, false if they are from an attribute value
+     * @param escLF true if the linefeed should be escaped.
+     *
+     * @return i+1 if the character was written, else i.
+     *
+     * @throws java.io.IOException
+     */
+    int accumDefaultEntity(
+        java.io.Writer writer,
+        char ch,
+        int i,
+        char[] chars,
+        int len,
+        boolean fromTextNode,
+        boolean escLF)
+        throws IOException
+    {
+
+        if (!escLF && CharInfo.S_LINEFEED == ch)
+        {
+            writer.write(m_lineSep, 0, m_lineSepLen);
+        }
+        else
+        {
+            // if this is text node character and a special one of those,
+            // or if this is a character from attribute value and a special one of those
+            if ((fromTextNode && m_charInfo.shouldMapTextChar(ch)) || (!fromTextNode && m_charInfo.shouldMapAttrChar(ch)))
+            {
+                String outputStringForChar = m_charInfo.getOutputStringForChar(ch);
+
+                if (null != outputStringForChar)
+                {
+                    writer.write(outputStringForChar);
+                }
+                else
+                    return i;
+            }
+            else
+                return i;
+        }
+
+        return i + 1;
+
+    }
+    /**
+     * Normalize the characters, but don't escape.
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @param isCData true if a CDATA block should be built around the characters.
+     * @param useSystemLineSeparator true if the operating systems 
+     * end-of-line separator should be output rather than a new-line character.
+     *
+     * @throws IOException
+     * @throws org.xml.sax.SAXException
+     */
+    void writeNormalizedChars(
+        char ch[],
+        int start,
+        int length,
+        boolean isCData,
+        boolean useSystemLineSeparator)
+        throws IOException, org.xml.sax.SAXException
+    {
+        final java.io.Writer writer = m_writer;
+        int end = start + length;
+
+        for (int i = start; i < end; i++)
+        {
+            char c = ch[i];
+
+            if (CharInfo.S_LINEFEED == c && useSystemLineSeparator)
+            {
+                writer.write(m_lineSep, 0, m_lineSepLen);
+            }
+            else if (isCData && (!escapingNotNeeded(c)))
+            {
+                //                if (i != 0)
+                if (m_cdataTagOpen)
+                    closeCDATA();
+
+                // This needs to go into a function... 
+                if (Encodings.isHighUTF16Surrogate(c))
+                {
+                    writeUTF16Surrogate(c, ch, i, end);
+                    i++ ; // process two input characters
+                }
+                else
+                {
+                    writer.write("&#");
+
+                    String intStr = Integer.toString((int) c);
+
+                    writer.write(intStr);
+                    writer.write(';');
+                }
+
+                //                if ((i != 0) && (i < (end - 1)))
+                //                if (!m_cdataTagOpen && (i < (end - 1)))
+                //                {
+                //                    writer.write(CDATA_DELIMITER_OPEN);
+                //                    m_cdataTagOpen = true;
+                //                }
+            }
+            else if (
+                isCData
+                    && ((i < (end - 2))
+                        && (']' == c)
+                        && (']' == ch[i + 1])
+                        && ('>' == ch[i + 2])))
+            {
+                writer.write(CDATA_CONTINUE);
+
+                i += 2;
+            }
+            else
+            {
+                if (escapingNotNeeded(c))
+                {
+                    if (isCData && !m_cdataTagOpen)
+                    {
+                        writer.write(CDATA_DELIMITER_OPEN);
+                        m_cdataTagOpen = true;
+                    }
+                    writer.write(c);
+                }
+
+                // This needs to go into a function... 
+                else if (Encodings.isHighUTF16Surrogate(c))
+                {
+                    if (m_cdataTagOpen)
+                        closeCDATA();
+                    writeUTF16Surrogate(c, ch, i, end);
+                    i++; // process two input characters
+                }
+                else
+                {
+                    if (m_cdataTagOpen)
+                        closeCDATA();
+                    writer.write("&#");
+
+                    String intStr = Integer.toString((int) c);
+
+                    writer.write(intStr);
+                    writer.write(';');
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Ends an un-escaping section.
+     *
+     * @see #startNonEscaping
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void endNonEscaping() throws org.xml.sax.SAXException
+    {
+        m_disableOutputEscapingStates.pop();
+    }
+
+    /**
+     * Starts an un-escaping section. All characters printed within an un-
+     * escaping section are printed as is, without escaping special characters
+     * into entity references. Only XML and HTML serializers need to support
+     * this method.
+     * <p> The contents of the un-escaping section will be delivered through the
+     * regular <tt>characters</tt> event.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void startNonEscaping() throws org.xml.sax.SAXException
+    {
+        m_disableOutputEscapingStates.push(true);
+    }
+
+    /**
+     * Receive notification of cdata.
+     *
+     * <p>The Parser will call this method to report each chunk of
+     * character data.  SAX parsers may return all contiguous character
+     * data in a single chunk, or they may split it into several
+     * chunks; however, all of the characters in any single event
+     * must come from the same external entity, so that the Locator
+     * provides useful information.</p>
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Note that some parsers will report whitespace using the
+     * ignorableWhitespace() method rather than this one (validating
+     * parsers must do so).</p>
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #ignorableWhitespace
+     * @see org.xml.sax.Locator
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void cdata(char ch[], int start, final int length)
+        throws org.xml.sax.SAXException
+    {
+
+        try
+        {
+            final int old_start = start;
+            if (m_elemContext.m_startTagOpen)
+            {
+                closeStartTag();
+                m_elemContext.m_startTagOpen = false;
+            }
+            m_ispreserve = true;
+
+            if (shouldIndent())
+                indent();
+
+            boolean writeCDataBrackets =
+                (((length >= 1) && escapingNotNeeded(ch[start])));
+
+            /* Write out the CDATA opening delimiter only if
+             * we are supposed to, and if we are not already in
+             * the middle of a CDATA section  
+             */
+            if (writeCDataBrackets && !m_cdataTagOpen)
+            {
+                m_writer.write(CDATA_DELIMITER_OPEN);
+                m_cdataTagOpen = true;
+            }
+
+            // writer.write(ch, start, length);
+            if (isEscapingDisabled())
+            {
+                charactersRaw(ch, start, length);
+            }
+            else
+                writeNormalizedChars(ch, start, length, true, m_lineSepUse);
+
+            /* used to always write out CDATA closing delimiter here,
+             * but now we delay, so that we can merge CDATA sections on output.    
+             * need to write closing delimiter later
+             */
+            if (writeCDataBrackets)
+            {
+                /* if the CDATA section ends with ] don't leave it open
+                 * as there is a chance that an adjacent CDATA sections
+                 * starts with ]>.  
+                 * We don't want to merge ]] with > , or ] with ]> 
+                 */
+                if (ch[start + length - 1] == ']')
+                    closeCDATA();
+            }
+
+            // time to fire off CDATA event
+            if (m_tracer != null)
+                super.fireCDATAEvent(ch, old_start, length);
+        }
+        catch (IOException ioe)
+        {
+            throw new org.xml.sax.SAXException(
+                Utils.messages.createMessage(
+                    MsgKey.ER_OIERROR,
+                    null),
+                ioe);
+            //"IO error", ioe);
+        }
+    }
+
+    /**
+     * Tell if the character escaping should be disabled for the current state.
+     *
+     * @return true if the character escaping should be disabled.
+     */
+    private boolean isEscapingDisabled()
+    {
+        return m_disableOutputEscapingStates.peekOrFalse();
+    }
+
+    /**
+     * If available, when the disable-output-escaping attribute is used,
+     * output raw text without escaping.
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void charactersRaw(char ch[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+
+        if (m_inEntityRef)
+            return;
+        try
+        {
+            if (m_elemContext.m_startTagOpen)
+            {
+                closeStartTag();
+                m_elemContext.m_startTagOpen = false;
+            }
+
+            m_ispreserve = true;
+
+            m_writer.write(ch, start, length);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * <p>The Parser will call this method to report each chunk of
+     * character data.  SAX parsers may return all contiguous character
+     * data in a single chunk, or they may split it into several
+     * chunks; however, all of the characters in any single event
+     * must come from the same external entity, so that the Locator
+     * provides useful information.</p>
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Note that some parsers will report whitespace using the
+     * ignorableWhitespace() method rather than this one (validating
+     * parsers must do so).</p>
+     *
+     * @param chars The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #ignorableWhitespace
+     * @see org.xml.sax.Locator
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void characters(final char chars[], final int start, final int length)
+        throws org.xml.sax.SAXException
+    {
+        // It does not make sense to continue with rest of the method if the number of 
+        // characters to read from array is 0.
+        // Section 7.6.1 of XSLT 1.0 (http://www.w3.org/TR/xslt#value-of) suggest no text node
+        // is created if string is empty.	
+        if (length == 0 || (m_inEntityRef && !m_expandDTDEntities))
+            return;
+            
+        m_docIsEmpty = false;
+        
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+        else if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+        }
+
+        if (m_cdataStartCalled || m_elemContext.m_isCdataSection)
+        {
+            /* either due to startCDATA() being called or due to 
+             * cdata-section-elements atribute, we need this as cdata
+             */
+            cdata(chars, start, length);
+
+            return;
+        }
+
+        if (m_cdataTagOpen)
+            closeCDATA();
+        
+        if (m_disableOutputEscapingStates.peekOrFalse() || (!m_escaping))
+        {
+            charactersRaw(chars, start, length);
+
+            // time to fire off characters generation event
+            if (m_tracer != null)
+                super.fireCharEvent(chars, start, length);
+
+            return;
+        }
+
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+
+        
+        try
+        {
+            int i;
+            int startClean;
+            
+            // skip any leading whitspace 
+            // don't go off the end and use a hand inlined version
+            // of isWhitespace(ch)
+            final int end = start + length;
+            int lastDirtyCharProcessed = start - 1; // last non-clean character that was processed
+													// that was processed
+            final Writer writer = m_writer;
+            boolean isAllWhitespace = true;
+
+            // process any leading whitspace
+            i = start;
+            while (i < end && isAllWhitespace) {
+                char ch1 = chars[i];
+
+                if (m_charInfo.shouldMapTextChar(ch1)) {
+                    // The character is supposed to be replaced by a String
+                    // so write out the clean whitespace characters accumulated
+                    // so far
+                    // then the String.
+                    writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                    String outputStringForChar = m_charInfo
+                            .getOutputStringForChar(ch1);
+                    writer.write(outputStringForChar);
+                    // We can't say that everything we are writing out is
+                    // all whitespace, we just wrote out a String.
+                    isAllWhitespace = false;
+                    lastDirtyCharProcessed = i; // mark the last non-clean
+                    // character processed
+                    i++;
+                } else {
+                    // The character is clean, but is it a whitespace ?
+                    switch (ch1) {
+                    // TODO: Any other whitespace to consider?
+                    case CharInfo.S_SPACE:
+                        // Just accumulate the clean whitespace
+                        i++;
+                        break;
+                    case CharInfo.S_LINEFEED:
+                        lastDirtyCharProcessed = processLineFeed(chars, i,
+                                lastDirtyCharProcessed, writer);
+                        i++;
+                        break;
+                    case CharInfo.S_CARRIAGERETURN:
+                        writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                        writer.write("&#13;");
+                        lastDirtyCharProcessed = i;
+                        i++;
+                        break;
+                    case CharInfo.S_HORIZONAL_TAB:
+                        // Just accumulate the clean whitespace
+                        i++;
+                        break;
+                    default:
+                        // The character was clean, but not a whitespace
+                        // so break the loop to continue with this character
+                        // (we don't increment index i !!)
+                        isAllWhitespace = false;
+                        break;
+                    }
+                }
+            }
+
+            /* If there is some non-whitespace, mark that we may need
+             * to preserve this. This is only important if we have indentation on.
+             */            
+            if (i < end || !isAllWhitespace) 
+                m_ispreserve = true;
+            
+            
+            for (; i < end; i++)
+            {
+                char ch = chars[i];
+                
+                if (m_charInfo.shouldMapTextChar(ch)) {
+                    // The character is supposed to be replaced by a String
+                    // e.g.   '&'  -->  "&amp;"
+                    // e.g.   '<'  -->  "&lt;"
+                    writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                    String outputStringForChar = m_charInfo.getOutputStringForChar(ch);
+                    writer.write(outputStringForChar);
+                    lastDirtyCharProcessed = i;
+                }
+                else {
+                    if (ch <= 0x1F) {
+                        // Range 0x00 through 0x1F inclusive
+                        //
+                        // This covers the non-whitespace control characters
+                        // in the range 0x1 to 0x1F inclusive.
+                        // It also covers the whitespace control characters in the same way:
+                        // 0x9   TAB
+                        // 0xA   NEW LINE
+                        // 0xD   CARRIAGE RETURN
+                        //
+                        // We also cover 0x0 ... It isn't valid
+                        // but we will output "&#0;" 
+                        
+                        // The default will handle this just fine, but this
+                        // is a little performance boost to handle the more
+                        // common TAB, NEW-LINE, CARRIAGE-RETURN
+                        switch (ch) {
+
+                        case CharInfo.S_HORIZONAL_TAB:
+                            // Leave whitespace TAB as a real character
+                            break;
+                        case CharInfo.S_LINEFEED:
+                            lastDirtyCharProcessed = processLineFeed(chars, i, lastDirtyCharProcessed, writer);
+                            break;
+                        case CharInfo.S_CARRIAGERETURN:
+                        	writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                        	writer.write("&#13;");
+                        	lastDirtyCharProcessed = i;
+                            // Leave whitespace carriage return as a real character
+                            break;
+                        default:
+                            writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                            writer.write("&#");
+                            writer.write(Integer.toString(ch));
+                            writer.write(';');
+                            lastDirtyCharProcessed = i;
+                            break;
+
+                        }
+                    }
+                    else if (ch < 0x7F) {  
+                        // Range 0x20 through 0x7E inclusive
+                        // Normal ASCII chars, do nothing, just add it to
+                        // the clean characters
+                            
+                    }
+                    else if (ch <= 0x9F){
+                        // Range 0x7F through 0x9F inclusive
+                        // More control characters, including NEL (0x85)
+                        writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                        writer.write("&#");
+                        writer.write(Integer.toString(ch));
+                        writer.write(';');
+                        lastDirtyCharProcessed = i;
+                    }
+                    else if (ch == CharInfo.S_LINE_SEPARATOR) {
+                        // LINE SEPARATOR
+                        writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                        writer.write("&#8232;");
+                        lastDirtyCharProcessed = i;
+                    }
+                    else if (m_encodingInfo.isInEncoding(ch)) {
+                        // If the character is in the encoding, and
+                        // not in the normal ASCII range, we also
+                        // just leave it get added on to the clean characters
+                        
+                    }
+                    else {
+                        // This is a fallback plan, we should never get here
+                        // but if the character wasn't previously handled
+                        // (i.e. isn't in the encoding, etc.) then what
+                        // should we do?  We choose to write out an entity
+                        writeOutCleanChars(chars, i, lastDirtyCharProcessed);
+                        writer.write("&#");
+                        writer.write(Integer.toString(ch));
+                        writer.write(';');
+                        lastDirtyCharProcessed = i;
+                    }
+                }
+            }
+            
+            // we've reached the end. Any clean characters at the
+            // end of the array than need to be written out?
+            startClean = lastDirtyCharProcessed + 1;
+            if (i > startClean)
+            {
+                int lengthClean = i - startClean;
+                m_writer.write(chars, startClean, lengthClean);
+            }
+
+            // For indentation purposes, mark that we've just writen text out
+            m_isprevtext = true;
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+        // time to fire off characters generation event
+        if (m_tracer != null)
+            super.fireCharEvent(chars, start, length);
+    }
+
+	private int processLineFeed(final char[] chars, int i, int lastProcessed, final Writer writer) throws IOException {
+		if (!m_lineSepUse 
+		|| (m_lineSepLen ==1 && m_lineSep[0] == CharInfo.S_LINEFEED)){
+		    // We are leaving the new-line alone, and it is just
+		    // being added to the 'clean' characters,
+			// so the last dirty character processed remains unchanged
+		}
+		else {
+		    writeOutCleanChars(chars, i, lastProcessed);
+		    writer.write(m_lineSep, 0, m_lineSepLen);
+		    lastProcessed = i;
+		}
+		return lastProcessed;
+	}
+
+    private void writeOutCleanChars(final char[] chars, int i, int lastProcessed) throws IOException {
+        int startClean;
+        startClean = lastProcessed + 1;
+        if (startClean < i)
+        {
+            int lengthClean = i - startClean;
+            m_writer.write(chars, startClean, lengthClean);
+        }
+    }     
+    /**
+     * This method checks if a given character is between C0 or C1 range
+     * of Control characters.
+     * This method is added to support Control Characters for XML 1.1
+     * If a given character is TAB (0x09), LF (0x0A) or CR (0x0D), this method
+     * return false. Since they are whitespace characters, no special processing is needed.
+     * 
+     * @param ch
+     * @return boolean
+     */
+    private static boolean isCharacterInC0orC1Range(char ch)
+    {
+        if(ch == 0x09 || ch == 0x0A || ch == 0x0D)
+        	return false;
+        else        	    	
+        	return (ch >= 0x7F && ch <= 0x9F)|| (ch >= 0x01 && ch <= 0x1F);
+    }
+    /**
+     * This method checks if a given character either NEL (0x85) or LSEP (0x2028)
+     * These are new end of line charcters added in XML 1.1.  These characters must be
+     * written as Numeric Character References (NCR) in XML 1.1 output document.
+     * 
+     * @param ch
+     * @return boolean
+     */
+    private static boolean isNELorLSEPCharacter(char ch)
+    {
+        return (ch == 0x85 || ch == 0x2028);
+    }
+    /**
+     * Process a dirty character and any preeceding clean characters
+     * that were not yet processed.
+     * @param chars array of characters being processed
+     * @param end one (1) beyond the last character 
+     * in chars to be processed
+     * @param i the index of the dirty character
+     * @param ch the character in chars[i]
+     * @param lastDirty the last dirty character previous to i
+     * @param fromTextNode true if the characters being processed are
+     * from a text node, false if they are from an attribute value.
+     * @return the index of the last character processed
+     */
+    private int processDirty(
+        char[] chars, 
+        int end,
+        int i, 
+        char ch,
+        int lastDirty,
+        boolean fromTextNode) throws IOException
+    {
+        int startClean = lastDirty + 1;
+        // if we have some clean characters accumulated
+        // process them before the dirty one.                   
+        if (i > startClean)
+        {
+            int lengthClean = i - startClean;
+            m_writer.write(chars, startClean, lengthClean);
+        }
+
+        // process the "dirty" character
+        if (CharInfo.S_LINEFEED == ch && fromTextNode)
+        {
+            m_writer.write(m_lineSep, 0, m_lineSepLen);
+        }
+        else
+        {
+            startClean =
+                accumDefaultEscape(
+                    m_writer,
+                    (char)ch,
+                    i,
+                    chars,
+                    end,
+                    fromTextNode,
+                    false);
+            i = startClean - 1;
+        }
+        // Return the index of the last character that we just processed 
+        // which is a dirty character.
+        return i;
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param s The string of characters to process.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void characters(String s) throws org.xml.sax.SAXException
+    {
+        if (m_inEntityRef && !m_expandDTDEntities)
+            return;
+        final int length = s.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length * 2 + 1];
+        }
+        s.getChars(0, length, m_charsBuff, 0);
+        characters(m_charsBuff, 0, length);
+    }
+
+    /**
+     * Escape and writer.write a character.
+     *
+     * @param ch character to be escaped.
+     * @param i index into character array.
+     * @param chars non-null reference to character array.
+     * @param len length of chars.
+     * @param fromTextNode true if the characters being processed are
+     * from a text node, false if the characters being processed are from
+     * an attribute value.
+     * @param escLF true if the linefeed should be escaped.
+     *
+     * @return i+1 if a character was written, i+2 if two characters
+     * were written out, else return i.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    private int accumDefaultEscape(
+        Writer writer,
+        char ch,
+        int i,
+        char[] chars,
+        int len,
+        boolean fromTextNode,
+        boolean escLF)
+        throws IOException
+    {
+
+        int pos = accumDefaultEntity(writer, ch, i, chars, len, fromTextNode, escLF);
+
+        if (i == pos)
+        {
+            if (Encodings.isHighUTF16Surrogate(ch))
+            {
+
+                // Should be the UTF-16 low surrogate of the hig/low pair.
+                char next;
+                // Unicode code point formed from the high/low pair.
+                int codePoint = 0;
+
+                if (i + 1 >= len)
+                {
+                    throw new IOException(
+                        Utils.messages.createMessage(
+                            MsgKey.ER_INVALID_UTF16_SURROGATE,
+                            new Object[] { Integer.toHexString(ch)}));
+                    //"Invalid UTF-16 surrogate detected: "
+
+                    //+Integer.toHexString(ch)+ " ?");
+                }
+                else
+                {
+                    next = chars[++i];
+
+                    if (!(Encodings.isLowUTF16Surrogate(next)))
+                        throw new IOException(
+                            Utils.messages.createMessage(
+                                MsgKey
+                                    .ER_INVALID_UTF16_SURROGATE,
+                                new Object[] {
+                                    Integer.toHexString(ch)
+                                        + " "
+                                        + Integer.toHexString(next)}));
+                    //"Invalid UTF-16 surrogate detected: "
+
+                    //+Integer.toHexString(ch)+" "+Integer.toHexString(next));
+                    codePoint = Encodings.toCodePoint(ch,next);
+                }
+
+                writer.write("&#");
+                writer.write(Integer.toString(codePoint));
+                writer.write(';');
+                pos += 2; // count the two characters that went into writing out this entity
+            }
+            else
+            {
+                /*  This if check is added to support control characters in XML 1.1.
+                 *  If a character is a Control Character within C0 and C1 range, it is desirable
+                 *  to write it out as Numeric Character Reference(NCR) regardless of XML Version
+                 *  being used for output document.
+                 */ 
+                if (isCharacterInC0orC1Range(ch) || isNELorLSEPCharacter(ch))
+                {
+                    writer.write("&#");
+                    writer.write(Integer.toString(ch));
+                    writer.write(';');
+                }
+                else if ((!escapingNotNeeded(ch) || 
+                    (  (fromTextNode && m_charInfo.shouldMapTextChar(ch))
+                     || (!fromTextNode && m_charInfo.shouldMapAttrChar(ch)))) 
+                && m_elemContext.m_currentElemDepth > 0)
+                {
+                    writer.write("&#");
+                    writer.write(Integer.toString(ch));
+                    writer.write(';');
+                }
+                else
+                {
+                    writer.write(ch);
+                }
+                pos++;  // count the single character that was processed
+            }
+
+        }
+        return pos;
+    }
+
+    /**
+     * Receive notification of the beginning of an element, although this is a
+     * SAX method additional namespace or attribute information can occur before
+     * or after this call, that is associated with this element.
+     *
+     *
+     * @param namespaceURI The Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed.
+     * @param localName The local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed.
+     * @param name The element type name.
+     * @param atts The attributes attached to the element, if any.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#startElement
+     * @see org.xml.sax.ContentHandler#endElement
+     * @see org.xml.sax.AttributeList
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void startElement(
+        String namespaceURI,
+        String localName,
+        String name,
+        Attributes atts)
+        throws org.xml.sax.SAXException
+    {
+        if (m_inEntityRef)
+            return;
+
+        if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+            m_needToCallStartDocument = false;
+            m_docIsEmpty = false;
+        }
+        else if (m_cdataTagOpen)
+            closeCDATA();
+        try
+        {
+            if (m_needToOutputDocTypeDecl) {
+                if(null != getDoctypeSystem()) {
+                    outputDocTypeDecl(name, true);
+                }
+                m_needToOutputDocTypeDecl = false;
+            }
+        
+            /* before we over-write the current elementLocalName etc.
+             * lets close out the old one (if we still need to)
+             */
+            if (m_elemContext.m_startTagOpen)
+            {
+                closeStartTag();
+                m_elemContext.m_startTagOpen = false;
+            }
+
+            if (namespaceURI != null)
+                ensurePrefixIsDeclared(namespaceURI, name);
+                
+            m_ispreserve = false;
+
+            if (shouldIndent() && m_startNewLine)
+            {
+                indent();
+            }
+
+            m_startNewLine = true;
+
+            final java.io.Writer writer = m_writer;
+            writer.write('<');
+            writer.write(name);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+        // process the attributes now, because after this SAX call they might be gone
+        if (atts != null)
+            addAttributes(atts);
+            
+        m_elemContext = m_elemContext.push(namespaceURI,localName,name);
+        m_isprevtext = false;
+
+        if (m_tracer != null)
+            firePseudoAttributes();
+    }
+
+    /**
+      * Receive notification of the beginning of an element, additional
+      * namespace or attribute information can occur before or after this call,
+      * that is associated with this element.
+      *
+      *
+      * @param elementNamespaceURI The Namespace URI, or the empty string if the
+      *        element has no Namespace URI or if Namespace
+      *        processing is not being performed.
+      * @param elementLocalName The local name (without prefix), or the
+      *        empty string if Namespace processing is not being
+      *        performed.
+      * @param elementName The element type name.
+      * @throws org.xml.sax.SAXException Any SAX exception, possibly
+      *            wrapping another exception.
+      * @see org.xml.sax.ContentHandler#startElement
+      * @see org.xml.sax.ContentHandler#endElement
+      * @see org.xml.sax.AttributeList
+      *
+      * @throws org.xml.sax.SAXException
+      */
+    public void startElement(
+        String elementNamespaceURI,
+        String elementLocalName,
+        String elementName)
+        throws SAXException
+    {
+        startElement(elementNamespaceURI, elementLocalName, elementName, null);
+    }
+
+    public void startElement(String elementName) throws SAXException
+    {
+        startElement(null, null, elementName, null);
+    }
+
+    /**
+     * Output the doc type declaration.
+     *
+     * @param name non-null reference to document type name.
+     * NEEDSDOC @param closeDecl
+     *
+     * @throws java.io.IOException
+     */
+    void outputDocTypeDecl(String name, boolean closeDecl) throws SAXException
+    {
+        if (m_cdataTagOpen)
+            closeCDATA();
+        try
+        {
+            final java.io.Writer writer = m_writer;
+            writer.write("<!DOCTYPE ");
+            writer.write(name);
+
+            String doctypePublic = getDoctypePublic();
+            if (null != doctypePublic)
+            {
+                writer.write(" PUBLIC \"");
+                writer.write(doctypePublic);
+                writer.write('\"');
+            }
+
+            String doctypeSystem = getDoctypeSystem();
+            if (null != doctypeSystem)
+            {
+                if (null == doctypePublic)
+                    writer.write(" SYSTEM \"");
+                else
+                    writer.write(" \"");
+
+                writer.write(doctypeSystem);
+
+                if (closeDecl)
+                {
+                    writer.write("\">");
+                    writer.write(m_lineSep, 0, m_lineSepLen);
+                    closeDecl = false; // done closing
+                }
+                else
+                    writer.write('\"');
+            }
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     * Process the attributes, which means to write out the currently
+     * collected attributes to the writer. The attributes are not
+     * cleared by this method
+     * 
+     * @param writer the writer to write processed attributes to.
+     * @param nAttrs the number of attributes in m_attributes 
+     * to be processed
+     *
+     * @throws java.io.IOException
+     * @throws org.xml.sax.SAXException
+     */
+    public void processAttributes(java.io.Writer writer, int nAttrs) throws IOException, SAXException
+    {
+            /* real SAX attributes are not passed in, so process the 
+             * attributes that were collected after the startElement call.
+             * _attribVector is a "cheap" list for Stream serializer output
+             * accumulated over a series of calls to attribute(name,value)
+             */
+
+            String encoding = getEncoding();
+            for (int i = 0; i < nAttrs; i++)
+            {
+                // elementAt is JDK 1.1.8
+                final String name = m_attributes.getQName(i);
+                final String value = m_attributes.getValue(i);
+                writer.write(' ');
+                writer.write(name);
+                writer.write("=\"");
+                writeAttrString(writer, value, encoding);
+                writer.write('\"');
+            }
+    }
+
+    /**
+     * Returns the specified <var>string</var> after substituting <VAR>specials</VAR>,
+     * and UTF-16 surrogates for chracter references <CODE>&amp;#xnn</CODE>.
+     *
+     * @param   string      String to convert to XML format.
+     * @param   encoding    CURRENTLY NOT IMPLEMENTED.
+     *
+     * @throws java.io.IOException
+     */
+    public void writeAttrString(
+        Writer writer,
+        String string,
+        String encoding)
+        throws IOException
+    {
+        final int len = string.length();
+        if (len > m_attrBuff.length)
+        {
+           m_attrBuff = new char[len*2 + 1];             
+        }
+        string.getChars(0,len, m_attrBuff, 0);   
+        final char[] stringChars = m_attrBuff;
+
+        for (int i = 0; i < len; i++)
+        {
+            char ch = stringChars[i];
+            
+            if (m_charInfo.shouldMapAttrChar(ch)) {
+                // The character is supposed to be replaced by a String
+                // e.g.   '&'  -->  "&amp;"
+                // e.g.   '<'  -->  "&lt;"
+                accumDefaultEscape(writer, ch, i, stringChars, len, false, true);
+            }
+            else {
+                if (0x0 <= ch && ch <= 0x1F) {
+                    // Range 0x00 through 0x1F inclusive
+                    // This covers the non-whitespace control characters
+                    // in the range 0x1 to 0x1F inclusive.
+                    // It also covers the whitespace control characters in the same way:
+                    // 0x9   TAB
+                    // 0xA   NEW LINE
+                    // 0xD   CARRIAGE RETURN
+                    //
+                    // We also cover 0x0 ... It isn't valid
+                    // but we will output "&#0;" 
+                    
+                    // The default will handle this just fine, but this
+                    // is a little performance boost to handle the more
+                    // common TAB, NEW-LINE, CARRIAGE-RETURN
+                    switch (ch) {
+
+                    case CharInfo.S_HORIZONAL_TAB:
+                        writer.write("&#9;");
+                        break;
+                    case CharInfo.S_LINEFEED:
+                        writer.write("&#10;");
+                        break;
+                    case CharInfo.S_CARRIAGERETURN:
+                        writer.write("&#13;");
+                        break;
+                    default:
+                        writer.write("&#");
+                        writer.write(Integer.toString(ch));
+                        writer.write(';');
+                        break;
+
+                    }
+                }
+                else if (ch < 0x7F) {   
+                    // Range 0x20 through 0x7E inclusive
+                    // Normal ASCII chars
+                        writer.write(ch);
+                }
+                else if (ch <= 0x9F){
+                    // Range 0x7F through 0x9F inclusive
+                    // More control characters
+                    writer.write("&#");
+                    writer.write(Integer.toString(ch));
+                    writer.write(';');
+                }
+                else if (ch == CharInfo.S_LINE_SEPARATOR) {
+                    // LINE SEPARATOR
+                    writer.write("&#8232;");
+                }
+                else if (m_encodingInfo.isInEncoding(ch)) {
+                    // If the character is in the encoding, and
+                    // not in the normal ASCII range, we also
+                    // just write it out
+                    writer.write(ch);
+                }
+                else {
+                    // This is a fallback plan, we should never get here
+                    // but if the character wasn't previously handled
+                    // (i.e. isn't in the encoding, etc.) then what
+                    // should we do?  We choose to write out a character ref
+                    writer.write("&#");
+                    writer.write(Integer.toString(ch));
+                    writer.write(';');
+                }
+                    
+            }
+        }
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     *
+     * @param namespaceURI The Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed.
+     * @param localName The local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed.
+     * @param name The element type name
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void endElement(String namespaceURI, String localName, String name)
+        throws org.xml.sax.SAXException
+    {
+        if (m_inEntityRef)
+            return;
+
+        // namespaces declared at the current depth are no longer valid
+        // so get rid of them    
+        m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth, null);
+
+        try
+        {
+            final java.io.Writer writer = m_writer;
+            if (m_elemContext.m_startTagOpen)
+            {
+                if (m_tracer != null)
+                    super.fireStartElem(m_elemContext.m_elementName);
+                int nAttrs = m_attributes.getLength();
+                if (nAttrs > 0)
+                {
+                    processAttributes(m_writer, nAttrs);
+                    // clear attributes object for re-use with next element
+                    m_attributes.clear();
+                }
+                if (m_spaceBeforeClose)
+                    writer.write(" />");
+                else
+                    writer.write("/>");
+                /* don't need to pop cdataSectionState because
+                 * this element ended so quickly that we didn't get
+                 * to push the state.
+                 */
+
+            }
+            else
+            {
+                if (m_cdataTagOpen)
+                    closeCDATA();
+
+                if (shouldIndent())
+                    indent(m_elemContext.m_currentElemDepth - 1);
+                writer.write('<');
+                writer.write('/');
+                writer.write(name);
+                writer.write('>');
+            }
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+        if (!m_elemContext.m_startTagOpen && m_doIndent)
+        {
+            m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
+        }
+
+        m_isprevtext = false;
+
+        // fire off the end element event
+        if (m_tracer != null)
+            super.fireEndElem(name);
+        m_elemContext = m_elemContext.m_prev;
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     * @param name The element type name
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *     wrapping another exception.
+     */
+    public void endElement(String name) throws org.xml.sax.SAXException
+    {
+        endElement(null, null, name);
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping
+     * just before another element is about to start.
+     * This call will close any open tags so that the prefix mapping
+     * will not apply to the current element, but the up comming child.
+     * 
+     * @see org.xml.sax.ContentHandler#startPrefixMapping
+     * 
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     * 
+     * @throws org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     * 
+     */
+    public void startPrefixMapping(String prefix, String uri)
+        throws org.xml.sax.SAXException
+    {
+        // the "true" causes the flush of any open tags
+        startPrefixMapping(prefix, uri, true);
+    }
+
+    /**
+     * Handle a prefix/uri mapping, which is associated with a startElement()
+     * that is soon to follow. Need to close any open start tag to make
+     * sure than any name space attributes due to this event are associated wih
+     * the up comming element, not the current one.
+     * @see ExtendedContentHandler#startPrefixMapping
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     * @param shouldFlush true if any open tags need to be closed first, this
+     * will impact which element the mapping applies to (open parent, or its up
+     * comming child)
+     * @return returns true if the call made a change to the current 
+     * namespace information, false if it did not change anything, e.g. if the
+     * prefix/namespace mapping was already in scope from before.
+     * 
+     * @throws org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     *
+     *
+     */
+    public boolean startPrefixMapping(
+        String prefix,
+        String uri,
+        boolean shouldFlush)
+        throws org.xml.sax.SAXException
+    {
+
+        /* Remember the mapping, and at what depth it was declared
+         * This is one greater than the current depth because these
+         * mappings will apply to the next depth. This is in
+         * consideration that startElement() will soon be called
+         */
+
+        boolean pushed;
+        int pushDepth;
+        if (shouldFlush)
+        {
+            flushPending();
+            // the prefix mapping applies to the child element (one deeper)
+            pushDepth = m_elemContext.m_currentElemDepth + 1;
+        }
+        else
+        {
+            // the prefix mapping applies to the current element
+            pushDepth = m_elemContext.m_currentElemDepth;
+        }
+        pushed = m_prefixMap.pushNamespace(prefix, uri, pushDepth);
+
+        if (pushed)
+        {
+            /* Brian M.: don't know if we really needto do this. The
+             * callers of this object should have injected both
+             * startPrefixMapping and the attributes.  We are 
+             * just covering our butt here.
+             */
+            String name;
+            if (EMPTYSTRING.equals(prefix))
+            {
+                name = "xmlns";
+                addAttributeAlways(XMLNS_URI, name, name, "CDATA", uri, false);
+            }
+            else
+            {
+                if (!EMPTYSTRING.equals(uri))
+                    // hack for XSLTC attribset16 test
+                { // that maps ns1 prefix to "" URI
+                    name = "xmlns:" + prefix;
+
+                    /* for something like xmlns:abc="w3.pretend.org"
+                     *  the      uri is the value, that is why we pass it in the
+                     * value, or 5th slot of addAttributeAlways()
+                     */
+                    addAttributeAlways(XMLNS_URI, prefix, name, "CDATA", uri, false);
+                }
+            }
+        }
+        return pushed;
+    }
+
+    /**
+     * Receive notification of an XML comment anywhere in the document. This
+     * callback will be used for comments inside or outside the document
+     * element, including comments in the external DTD subset (if read).
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use from the array.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     */
+    public void comment(char ch[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+
+        int start_old = start;
+        if (m_inEntityRef)
+            return;
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+        else if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+            m_needToCallStartDocument = false;
+        }
+
+        try
+        {
+            final int limit = start + length;
+            boolean wasDash = false;
+            if (m_cdataTagOpen)
+                closeCDATA();
+            
+            if (shouldIndent())
+                indent();
+            
+            final java.io.Writer writer = m_writer;    
+            writer.write(COMMENT_BEGIN);
+            // Detect occurrences of two consecutive dashes, handle as necessary.
+            for (int i = start; i < limit; i++)
+            {
+                if (wasDash && ch[i] == '-')
+                {
+                    writer.write(ch, start, i - start);
+                    writer.write(" -");
+                    start = i + 1;
+                }
+                wasDash = (ch[i] == '-');
+            }
+
+            // if we have some chars in the comment
+            if (length > 0)
+            {
+                // Output the remaining characters (if any)
+                final int remainingChars = (limit - start);
+                if (remainingChars > 0)
+                    writer.write(ch, start, remainingChars);
+                // Protect comment end from a single trailing dash
+                if (ch[limit - 1] == '-')
+                    writer.write(' ');
+            }
+            writer.write(COMMENT_END);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+        /*
+         * Don't write out any indentation whitespace now,
+         * because there may be non-whitespace text after this.
+         * 
+         * Simply mark that at this point if we do decide
+         * to indent that we should 
+         * add a newline on the end of the current line before
+         * the indentation at the start of the next line.
+         */ 
+        m_startNewLine = true;
+        // time to generate comment event
+        if (m_tracer != null)
+            super.fireCommentEvent(ch, start_old,length);
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     *
+     *  @see  #startCDATA
+     */
+    public void endCDATA() throws org.xml.sax.SAXException
+    {
+        if (m_cdataTagOpen)
+            closeCDATA();
+        m_cdataStartCalled = false;
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     * @see #startDTD
+     */
+    public void endDTD() throws org.xml.sax.SAXException
+    {
+        try
+        {
+            if (m_needToOutputDocTypeDecl)
+            {
+                outputDocTypeDecl(m_elemContext.m_elementName, false);
+                m_needToOutputDocTypeDecl = false;
+            }
+            final java.io.Writer writer = m_writer;
+            if (!m_inDoctype)
+                writer.write("]>");
+            else
+            {
+                writer.write('>');
+            }
+
+            writer.write(m_lineSep, 0, m_lineSepLen);
+        }
+        catch (IOException e)
+        {
+            throw new SAXException(e);
+        }
+
+    }
+
+    /**
+     * End the scope of a prefix-URI Namespace mapping.
+     * @see org.xml.sax.ContentHandler#endPrefixMapping
+     * 
+     * @param prefix The prefix that was being mapping.
+     * @throws org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException
+    { // do nothing
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     * 
+     * Not sure how to get this invoked quite yet.
+     * 
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #characters
+     * 
+     * @throws org.xml.sax.SAXException
+     */
+    public void ignorableWhitespace(char ch[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+
+        if (0 == length)
+            return;
+        characters(ch, start, length);
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     * @see org.xml.sax.ContentHandler#skippedEntity
+     * 
+     * @param name The name of the skipped entity.  If it is a
+     *       parameter                   entity, the name will begin with '%',
+     * and if it is the external DTD subset, it will be the string
+     * "[dtd]".
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly wrapping
+     * another exception.
+     */
+    public void skippedEntity(String name) throws org.xml.sax.SAXException
+    { // TODO: Should handle
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     * 
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     * @see #endCDATA
+     */
+    public void startCDATA() throws org.xml.sax.SAXException
+    {
+        m_cdataStartCalled = true;
+    }
+
+    /**
+     * Report the beginning of an entity.
+     * 
+     * The start and end of the document entity are not reported.
+     * The start and end of the external DTD subset are reported
+     * using the pseudo-name "[dtd]".  All other events must be
+     * properly nested within start/end entity events.
+     * 
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @throws org.xml.sax.SAXException The application may raise an exception.
+     * @see #endEntity
+     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+     */
+    public void startEntity(String name) throws org.xml.sax.SAXException
+    {
+        if (name.equals("[dtd]"))
+            m_inExternalDTD = true;
+
+        if (!m_expandDTDEntities && !m_inExternalDTD) {
+            /* Only leave the entity as-is if
+             * we've been told not to expand them
+             * and this is not the magic [dtd] name.
+             */
+            startNonEscaping();
+            characters("&" + name + ';');
+            endNonEscaping();
+        }
+
+        m_inEntityRef = true;
+    }
+
+    /**
+     * For the enclosing elements starting tag write out
+     * out any attributes followed by ">"
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void closeStartTag() throws SAXException
+    {
+
+        if (m_elemContext.m_startTagOpen)
+        {
+
+            try
+            {
+                if (m_tracer != null)
+                    super.fireStartElem(m_elemContext.m_elementName);
+                int nAttrs = m_attributes.getLength();
+                if (nAttrs > 0)
+                {
+                    processAttributes(m_writer, nAttrs);
+                    // clear attributes object for re-use with next element
+                    m_attributes.clear();
+                }
+                m_writer.write('>');
+            }
+            catch (IOException e)
+            {
+                throw new SAXException(e);
+            }
+
+            /* whether Xalan or XSLTC, we have the prefix mappings now, so
+             * lets determine if the current element is specified in the cdata-
+             * section-elements list.
+             */
+            if (m_CdataElems != null)
+                m_elemContext.m_isCdataSection = isCdataSection();
+
+            if (m_doIndent)
+            {
+                m_isprevtext = false;
+                m_preserves.push(m_ispreserve);
+            }
+        }
+
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * Any declarations are assumed to be in the internal subset unless
+     * otherwise indicated.
+     * 
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the
+     *        external DTD subset, or null if none was declared.
+     * @param systemId The declared system identifier for the
+     *        external DTD subset, or null if none was declared.
+     * @throws org.xml.sax.SAXException The application may raise an
+     *            exception.
+     * @see #endDTD
+     * @see #startEntity
+     */
+    public void startDTD(String name, String publicId, String systemId)
+        throws org.xml.sax.SAXException
+    {
+        setDoctypeSystem(systemId);
+        setDoctypePublic(publicId);
+
+        m_elemContext.m_elementName = name;
+        m_inDoctype = true;
+    }
+
+    /**
+     * Returns the m_indentAmount.
+     * @return int
+     */
+    public int getIndentAmount()
+    {
+        return m_indentAmount;
+    }
+
+    /**
+     * Sets the m_indentAmount.
+     * 
+     * @param m_indentAmount The m_indentAmount to set
+     */
+    public void setIndentAmount(int m_indentAmount)
+    {
+        this.m_indentAmount = m_indentAmount;
+    }
+
+    /**
+     * Tell if, based on space preservation constraints and the doIndent property,
+     * if an indent should occur.
+     *
+     * @return True if an indent should occur.
+     */
+    protected boolean shouldIndent()
+    {
+        return m_doIndent && (!m_ispreserve && !m_isprevtext) && m_elemContext.m_currentElemDepth > 0;
+    }
+
+    /**
+     * Searches for the list of qname properties with the specified key in the
+     * property list. If the key is not found in this property list, the default
+     * property list, and its defaults, recursively, are then checked. The
+     * method returns <code>null</code> if the property is not found.
+     *
+     * @param   key   the property key.
+     * @param props the list of properties to search in.
+     * 
+     * Sets the vector of local-name/URI pairs of the cdata section elements
+     * specified in the cdata-section-elements property.
+     * 
+     * This method is essentially a copy of getQNameProperties() from
+     * OutputProperties. Eventually this method should go away and a call
+     * to setCdataSectionElements(Vector v) should be made directly.
+     */
+    private void setCdataSectionElements(String key, Properties props)
+    {
+
+        String s = props.getProperty(key);
+
+        if (null != s)
+        {
+            // Vector of URI/LocalName pairs
+            Vector v = new Vector();
+            int l = s.length();
+            boolean inCurly = false;
+            StringBuffer buf = new StringBuffer();
+
+            // parse through string, breaking on whitespaces.  I do this instead
+            // of a tokenizer so I can track whitespace inside of curly brackets,
+            // which theoretically shouldn't happen if they contain legal URLs.
+            for (int i = 0; i < l; i++)
+            {
+                char c = s.charAt(i);
+
+                if (Character.isWhitespace(c))
+                {
+                    if (!inCurly)
+                    {
+                        if (buf.length() > 0)
+                        {
+                            addCdataSectionElement(buf.toString(), v);
+                            buf.setLength(0);
+                        }
+                        continue;
+                    }
+                }
+                else if ('{' == c)
+                    inCurly = true;
+                else if ('}' == c)
+                    inCurly = false;
+
+                buf.append(c);
+            }
+
+            if (buf.length() > 0)
+            {
+                addCdataSectionElement(buf.toString(), v);
+                buf.setLength(0);
+            }
+            // call the official, public method to set the collected names
+            setCdataSectionElements(v);
+        }
+
+    }
+
+    /**
+     * Adds a URI/LocalName pair of strings to the list.
+     *
+     * @param URI_and_localName String of the form "{uri}local" or "local" 
+     * 
+     * @return a QName object
+     */
+    private void addCdataSectionElement(String URI_and_localName, Vector v)
+    {
+
+        StringTokenizer tokenizer =
+            new StringTokenizer(URI_and_localName, "{}", false);
+        String s1 = tokenizer.nextToken();
+        String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+
+        if (null == s2)
+        {
+            // add null URI and the local name
+            v.addElement(null);
+            v.addElement(s1);
+        }
+        else
+        {
+            // add URI, then local name
+            v.addElement(s1);
+            v.addElement(s2);
+        }
+    }
+
+    /**
+     * Remembers the cdata sections specified in the cdata-section-elements.
+     * The "official way to set URI and localName pairs. 
+     * This method should be used by both Xalan and XSLTC.
+     * 
+     * @param URI_and_localNames a vector of pairs of Strings (URI/local)
+     */
+    public void setCdataSectionElements(Vector URI_and_localNames)
+    {
+        // convert to the new way.
+        if (URI_and_localNames != null)
+        {
+            final int len = URI_and_localNames.size() - 1;
+            if (len > 0)
+            {
+                final StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < len; i += 2)
+                {
+                    // whitspace separated "{uri1}local1 {uri2}local2 ..."
+                    if (i != 0)
+                        sb.append(' ');
+                    final String uri = (String) URI_and_localNames.elementAt(i);
+                    final String localName =
+                        (String) URI_and_localNames.elementAt(i + 1);
+                    if (uri != null)
+                    {
+                        // If there is no URI don't put this in, just the localName then.
+                        sb.append('{');
+                        sb.append(uri);
+                        sb.append('}');
+                    }
+                    sb.append(localName);
+                }
+                m_StringOfCDATASections = sb.toString();
+            }
+        }
+        initCdataElems(m_StringOfCDATASections);
+    }
+
+    /**
+     * Makes sure that the namespace URI for the given qualified attribute name
+     * is declared.
+     * @param ns the namespace URI
+     * @param rawName the qualified name 
+     * @return returns null if no action is taken, otherwise it returns the
+     * prefix used in declaring the namespace. 
+     * @throws SAXException
+     */
+    protected String ensureAttributesNamespaceIsDeclared(
+        String ns,
+        String localName,
+        String rawName)
+        throws org.xml.sax.SAXException
+    {
+
+        if (ns != null && ns.length() > 0)
+        {
+
+            // extract the prefix in front of the raw name
+            int index = 0;
+            String prefixFromRawName =
+                (index = rawName.indexOf(":")) < 0
+                    ? ""
+                    : rawName.substring(0, index);
+
+            if (index > 0)
+            {
+                // we have a prefix, lets see if it maps to a namespace 
+                String uri = m_prefixMap.lookupNamespace(prefixFromRawName);
+                if (uri != null && uri.equals(ns))
+                {
+                    // the prefix in the raw name is already maps to the given namespace uri
+                    // so we don't need to do anything
+                    return null;
+                }
+                else
+                {
+                    // The uri does not map to the prefix in the raw name,
+                    // so lets make the mapping.
+                    this.startPrefixMapping(prefixFromRawName, ns, false);
+                    this.addAttribute(
+                        "http://www.w3.org/2000/xmlns/",
+                        prefixFromRawName,
+                        "xmlns:" + prefixFromRawName,
+                        "CDATA",
+                        ns, false);
+                    return prefixFromRawName;
+                }
+            }
+            else
+            {
+                // we don't have a prefix in the raw name.
+                // Does the URI map to a prefix already?
+                String prefix = m_prefixMap.lookupPrefix(ns);
+                if (prefix == null)
+                {
+                    // uri is not associated with a prefix,
+                    // so lets generate a new prefix to use
+                    prefix = m_prefixMap.generateNextPrefix();
+                    this.startPrefixMapping(prefix, ns, false);
+                    this.addAttribute(
+                        "http://www.w3.org/2000/xmlns/",
+                        prefix,
+                        "xmlns:" + prefix,
+                        "CDATA",
+                        ns, false);
+                }
+
+                return prefix;
+
+            }
+        }
+        return null;
+    }
+
+    void ensurePrefixIsDeclared(String ns, String rawName)
+        throws org.xml.sax.SAXException
+    {
+
+        if (ns != null && ns.length() > 0)
+        {
+            int index;
+            final boolean no_prefix = ((index = rawName.indexOf(":")) < 0);
+            String prefix = (no_prefix) ? "" : rawName.substring(0, index);
+
+            if (null != prefix)
+            {
+                String foundURI = m_prefixMap.lookupNamespace(prefix);
+
+                if ((null == foundURI) || !foundURI.equals(ns))
+                {
+                    this.startPrefixMapping(prefix, ns);
+
+                    // Bugzilla1133: Generate attribute as well as namespace event.
+                    // SAX does expect both.
+
+                    this.addAttributeAlways(
+                        "http://www.w3.org/2000/xmlns/",
+                        no_prefix ? "xmlns" : prefix,  // local name
+                        no_prefix ? "xmlns" : ("xmlns:"+ prefix), // qname
+                        "CDATA",
+                        ns,
+                        false);
+                }
+
+            }
+        }
+    }
+
+    /**
+     * This method flushes any pending events, which can be startDocument()
+     * closing the opening tag of an element, or closing an open CDATA section.
+     */
+    public void flushPending() throws SAXException
+    {
+            if (m_needToCallStartDocument)
+            {
+                startDocumentInternal();
+                m_needToCallStartDocument = false;
+            }
+            if (m_elemContext.m_startTagOpen)
+            {
+                closeStartTag();
+                m_elemContext.m_startTagOpen = false;
+            }
+
+            if (m_cdataTagOpen)
+            {
+                closeCDATA();
+                m_cdataTagOpen = false;
+            }
+            if (m_writer != null) {
+                try {
+                    m_writer.flush();
+                }
+                catch(IOException e) {
+                    // what? me worry?
+                }
+            }
+    }
+
+    public void setContentHandler(ContentHandler ch)
+    {
+        // this method is really only useful in the ToSAXHandler classes but it is
+        // in the interface.  If the method defined here is ever called
+        // we are probably in trouble.
+    }
+
+    /**
+     * Adds the given attribute to the set of attributes, even if there is
+     * no currently open element. This is useful if a SAX startPrefixMapping()
+     * should need to add an attribute before the element name is seen.
+     * 
+     * This method is a copy of its super classes method, except that some
+     * tracing of events is done.  This is so the tracing is only done for
+     * stream serializers, not for SAX ones.
+     *
+     * @param uri the URI of the attribute
+     * @param localName the local name of the attribute
+     * @param rawName   the qualified name of the attribute
+     * @param type the type of the attribute (probably CDATA)
+     * @param value the value of the attribute
+     * @param xslAttribute true if this attribute is coming from an xsl:attribute element.
+     * @return true if the attribute value was added, 
+     * false if the attribute already existed and the value was
+     * replaced with the new value.
+     */
+    public boolean addAttributeAlways(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean xslAttribute)
+    {
+        boolean was_added;
+        int index;
+        if (uri == null || localName == null || uri.length() == 0)
+            index = m_attributes.getIndex(rawName);
+        else {
+            index = m_attributes.getIndex(uri, localName);
+        }
+
+        if (index >= 0)
+        {
+            String old_value = null;
+            if (m_tracer != null)
+            {
+                old_value = m_attributes.getValue(index);
+                if (value.equals(old_value))
+                    old_value = null;
+            }
+
+            /* We've seen the attribute before.
+             * We may have a null uri or localName, but all we really
+             * want to re-set is the value anyway.
+             */
+            m_attributes.setValue(index, value);
+            was_added = false;
+            if (old_value != null)
+                firePseudoAttributes();
+
+        }
+        else
+        {
+            // the attribute doesn't exist yet, create it
+            if (xslAttribute)
+            {
+                /*
+                 * This attribute is from an xsl:attribute element so we take some care in
+                 * adding it, e.g.
+                 *   <elem1  foo:attr1="1" xmlns:foo="uri1">
+                 *       <xsl:attribute name="foo:attr2">2</xsl:attribute>
+                 *   </elem1>
+                 * 
+                 * We are adding attr1 and attr2 both as attributes of elem1,
+                 * and this code is adding attr2 (the xsl:attribute ).
+                 * We could have a collision with the prefix like in the example above.
+                 */
+
+                // In the example above, is there a prefix like foo ?
+                final int colonIndex = rawName.indexOf(':');
+                if (colonIndex > 0)
+                {
+                    String prefix = rawName.substring(0,colonIndex);
+                    NamespaceMappings.MappingRecord existing_mapping = m_prefixMap.getMappingFromPrefix(prefix);
+
+                    /* Before adding this attribute (foo:attr2),
+                     * is the prefix for it (foo) already mapped at the current depth?
+                     */
+                    if (existing_mapping != null 
+                    && existing_mapping.m_declarationDepth == m_elemContext.m_currentElemDepth
+                    && !existing_mapping.m_uri.equals(uri))
+                    {
+                        /*
+                         * There is an existing mapping of this prefix,
+                         * it differs from the one we need,
+                         * and unfortunately it is at the current depth so we 
+                         * can not over-ride it.
+                         */
+
+                        /*
+                         * Are we lucky enough that an existing other prefix maps to this URI ?
+                         */
+                        prefix = m_prefixMap.lookupPrefix(uri);
+                        if (prefix == null)
+                        {
+                            /* Unfortunately there is no existing prefix that happens to map to ours,
+                             * so to avoid a prefix collision we must generated a new prefix to use. 
+                             * This is OK because the prefix URI mapping
+                             * defined in the xsl:attribute is short in scope, 
+                             * just the xsl:attribute element itself, 
+                             * and at this point in serialization the body of the
+                             * xsl:attribute, if any, is just a String. Right?
+                             *   . . . I sure hope so - Brian M. 
+                             */
+                            prefix = m_prefixMap.generateNextPrefix();
+                        }
+
+                        rawName = prefix + ':' + localName;
+                    }
+                }
+
+                try
+                {
+                    /* This is our last chance to make sure the namespace for this
+                     * attribute is declared, especially if we just generated an alternate
+                     * prefix to avoid a collision (the new prefix/rawName will go out of scope
+                     * soon and be lost ...  last chance here.
+                     */
+                    String prefixUsed =
+                        ensureAttributesNamespaceIsDeclared(
+                            uri,
+                            localName,
+                            rawName);
+                }
+                catch (SAXException e)
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+            m_attributes.addAttribute(uri, localName, rawName, type, value);
+            was_added = true;
+            if (m_tracer != null)
+                firePseudoAttributes();
+        }
+        return was_added;
+    }
+
+    /**
+     * To fire off the pseudo characters of attributes, as they currently
+     * exist. This method should be called everytime an attribute is added,
+     * or when an attribute value is changed, or an element is created.
+     */
+
+    protected void firePseudoAttributes()
+    {
+        if (m_tracer != null)
+        {
+            try
+            {
+                // flush out the "<elemName" if not already flushed
+                m_writer.flush();
+                
+                // make a StringBuffer to write the name="value" pairs to.
+                StringBuffer sb = new StringBuffer();
+                int nAttrs = m_attributes.getLength();
+                if (nAttrs > 0)
+                {
+                    // make a writer that internally appends to the same
+                    // StringBuffer
+                    java.io.Writer writer =
+                        new ToStream.WritertoStringBuffer(sb);
+
+                    processAttributes(writer, nAttrs);
+                    // Don't clear the attributes! 
+                    // We only want to see what would be written out
+                    // at this point, we don't want to loose them.
+                }
+                sb.append('>');  // the potential > after the attributes.
+                // convert the StringBuffer to a char array and
+                // emit the trace event that these characters "might"
+                // be written                
+                char ch[] = sb.toString().toCharArray();
+                m_tracer.fireGenerateEvent(
+                    SerializerTrace.EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS,
+                    ch,
+                    0,
+                    ch.length);                
+            }
+            catch (IOException ioe)
+            {
+                // ignore ?
+            }
+            catch (SAXException se)
+            {
+                // ignore ?
+            }
+        }
+    }
+
+    /**
+     * This inner class is used only to collect attribute values
+     * written by the method writeAttrString() into a string buffer.
+     * In this manner trace events, and the real writing of attributes will use
+     * the same code.
+     */
+    private class WritertoStringBuffer extends java.io.Writer
+    {
+        final private StringBuffer m_stringbuf;
+        /**
+         * @see java.io.Writer#write(char[], int, int)
+         */
+        WritertoStringBuffer(StringBuffer sb)
+        {
+            m_stringbuf = sb;
+        }
+
+        public void write(char[] arg0, int arg1, int arg2) throws IOException
+        {
+            m_stringbuf.append(arg0, arg1, arg2);
+        }
+        /**
+         * @see java.io.Writer#flush()
+         */
+        public void flush() throws IOException
+        {
+        }
+        /**
+         * @see java.io.Writer#close()
+         */
+        public void close() throws IOException
+        {
+        }
+
+        public void write(int i)
+        {
+            m_stringbuf.append((char) i);
+        }
+        
+        public void write(String s)
+        {
+            m_stringbuf.append(s);
+        }
+    }
+
+    /**
+     * @see SerializationHandler#setTransformer(Transformer)
+     */
+    public void setTransformer(Transformer transformer) {
+        super.setTransformer(transformer);
+        if (m_tracer != null
+         && !(m_writer instanceof SerializerTraceWriter)  )
+            setWriterInternal(new SerializerTraceWriter(m_writer, m_tracer), false);        
+        
+        
+    }
+    /**
+     * Try's to reset the super class and reset this class for 
+     * re-use, so that you don't need to create a new serializer 
+     * (mostly for performance reasons).
+     * 
+     * @return true if the class was successfuly reset.
+     */
+    public boolean reset()
+    {
+        boolean wasReset = false;
+        if (super.reset())
+        {
+            resetToStream();
+            wasReset = true;
+        }
+        return wasReset;
+    }
+    
+    /**
+     * Reset all of the fields owned by ToStream class
+     *
+     */
+    private void resetToStream()
+    {
+         this.m_cdataStartCalled = false;
+         /* The stream is being reset. It is one of
+          * ToXMLStream, ToHTMLStream ... and this type can't be changed
+          * so neither should m_charInfo which is associated with the
+          * type of Stream. Just leave m_charInfo as-is for the next re-use.
+          * 
+          */
+         // this.m_charInfo = null; // don't set to null 
+         this.m_disableOutputEscapingStates.clear();
+         // this.m_encodingInfo = null; // don't set to null
+         
+         this.m_escaping = true;
+         // Leave m_format alone for now - Brian M.
+         // this.m_format = null;
+         this.m_expandDTDEntities = true; 
+         this.m_inDoctype = false;
+         this.m_ispreserve = false;
+         this.m_isprevtext = false;
+         this.m_isUTF8 = false; //  ?? used anywhere ??
+         this.m_lineSep = s_systemLineSep;
+         this.m_lineSepLen = s_systemLineSep.length;
+         this.m_lineSepUse = true;
+         // this.m_outputStream = null; // Don't reset it may be re-used
+         this.m_preserves.clear();
+         this.m_shouldFlush = true;
+         this.m_spaceBeforeClose = false;
+         this.m_startNewLine = false;
+         this.m_writer_set_by_user = false;
+    }        
+    
+    /**
+      * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
+      * @param encoding the character encoding
+      */
+     public void setEncoding(String encoding)
+     {
+         setOutputProperty(OutputKeys.ENCODING,encoding);
+     }
+     
+    /**
+     * Simple stack for boolean values.
+     * 
+     * This class is a copy of the one in org.apache.xml.utils. 
+     * It exists to cut the serializers dependancy on that package.
+     * A minor changes from that package are:
+     * doesn't implement Clonable
+     *  
+     * @xsl.usage internal
+     */
+    static final class BoolStack
+    {
+
+      /** Array of boolean values          */
+      private boolean m_values[];
+
+      /** Array size allocated           */
+      private int m_allocatedSize;
+
+      /** Index into the array of booleans          */
+      private int m_index;
+
+      /**
+       * Default constructor.  Note that the default
+       * block size is very small, for small lists.
+       */
+      public BoolStack()
+      {
+        this(32);
+      }
+
+      /**
+       * Construct a IntVector, using the given block size.
+       *
+       * @param size array size to allocate
+       */
+      public BoolStack(int size)
+      {
+
+        m_allocatedSize = size;
+        m_values = new boolean[size];
+        m_index = -1;
+      }
+
+      /**
+       * Get the length of the list.
+       *
+       * @return Current length of the list
+       */
+      public final int size()
+      {
+        return m_index + 1;
+      }
+
+      /**
+       * Clears the stack.
+       *
+       */
+      public final void clear()
+      {
+        m_index = -1;
+      }
+
+      /**
+       * Pushes an item onto the top of this stack.
+       *
+       *
+       * @param val the boolean to be pushed onto this stack.
+       * @return  the <code>item</code> argument.
+       */
+      public final boolean push(boolean val)
+      {
+
+        if (m_index == m_allocatedSize - 1)
+          grow();
+
+        return (m_values[++m_index] = val);
+      }
+
+      /**
+       * Removes the object at the top of this stack and returns that
+       * object as the value of this function.
+       *
+       * @return     The object at the top of this stack.
+       * @throws  EmptyStackException  if this stack is empty.
+       */
+      public final boolean pop()
+      {
+        return m_values[m_index--];
+      }
+
+      /**
+       * Removes the object at the top of this stack and returns the
+       * next object at the top as the value of this function.
+       *
+       *
+       * @return Next object to the top or false if none there
+       */
+      public final boolean popAndTop()
+      {
+
+        m_index--;
+
+        return (m_index >= 0) ? m_values[m_index] : false;
+      }
+
+      /**
+       * Set the item at the top of this stack  
+       *
+       *
+       * @param b Object to set at the top of this stack
+       */
+      public final void setTop(boolean b)
+      {
+        m_values[m_index] = b;
+      }
+
+      /**
+       * Looks at the object at the top of this stack without removing it
+       * from the stack.
+       *
+       * @return     the object at the top of this stack.
+       * @throws  EmptyStackException  if this stack is empty.
+       */
+      public final boolean peek()
+      {
+        return m_values[m_index];
+      }
+
+      /**
+       * Looks at the object at the top of this stack without removing it
+       * from the stack.  If the stack is empty, it returns false.
+       *
+       * @return     the object at the top of this stack.
+       */
+      public final boolean peekOrFalse()
+      {
+        return (m_index > -1) ? m_values[m_index] : false;
+      }
+
+      /**
+       * Looks at the object at the top of this stack without removing it
+       * from the stack.  If the stack is empty, it returns true.
+       *
+       * @return     the object at the top of this stack.
+       */
+      public final boolean peekOrTrue()
+      {
+        return (m_index > -1) ? m_values[m_index] : true;
+      }
+
+      /**
+       * Tests if this stack is empty.
+       *
+       * @return  <code>true</code> if this stack is empty;
+       *          <code>false</code> otherwise.
+       */
+      public boolean isEmpty()
+      {
+        return (m_index == -1);
+      }
+
+      /**
+       * Grows the size of the stack
+       *
+       */
+      private void grow()
+      {
+
+        m_allocatedSize *= 2;
+
+        boolean newVector[] = new boolean[m_allocatedSize];
+
+        System.arraycopy(m_values, 0, newVector, 0, m_index + 1);
+
+        m_values = newVector;
+      }
+    }
+    
+    // Implement DTDHandler
+    /**
+     * If this method is called, the serializer is used as a
+     * DTDHandler, which changes behavior how the serializer 
+     * handles document entities. 
+     * @see org.xml.sax.DTDHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void notationDecl(String name, String pubID, String sysID) throws SAXException {
+        // TODO Auto-generated method stub
+        try {
+            DTDprolog();
+            
+            m_writer.write("<!NOTATION ");            
+            m_writer.write(name);
+            if (pubID != null) {
+                m_writer.write(" PUBLIC \"");
+                m_writer.write(pubID);
+  
+            }
+            else {
+                m_writer.write(" SYSTEM \"");
+                m_writer.write(sysID);
+            }
+            m_writer.write("\" >");
+            m_writer.write(m_lineSep, 0, m_lineSepLen);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * If this method is called, the serializer is used as a
+     * DTDHandler, which changes behavior how the serializer 
+     * handles document entities. 
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void unparsedEntityDecl(String name, String pubID, String sysID, String notationName) throws SAXException {
+        // TODO Auto-generated method stub
+        try {
+            DTDprolog();       
+            
+            m_writer.write("<!ENTITY ");            
+            m_writer.write(name);
+            if (pubID != null) {
+                m_writer.write(" PUBLIC \"");
+                m_writer.write(pubID);
+  
+            }
+            else {
+                m_writer.write(" SYSTEM \"");
+                m_writer.write(sysID);
+            }
+            m_writer.write("\" NDATA ");
+            m_writer.write(notationName);
+            m_writer.write(" >");
+            m_writer.write(m_lineSep, 0, m_lineSepLen);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }        
+    }
+    
+    /**
+     * A private helper method to output the 
+     * @throws SAXException
+     * @throws IOException
+     */
+    private void DTDprolog() throws SAXException, IOException {
+        final java.io.Writer writer = m_writer;
+        if (m_needToOutputDocTypeDecl)
+        {
+            outputDocTypeDecl(m_elemContext.m_elementName, false);
+            m_needToOutputDocTypeDecl = false;
+        }
+        if (m_inDoctype)
+        {
+            writer.write(" [");
+            writer.write(m_lineSep, 0, m_lineSepLen);
+            m_inDoctype = false;
+        }
+    }
+    
+    /**
+     * If set to false the serializer does not expand DTD entities,
+     * but leaves them as is, the default value is true;
+     */
+    public void setDTDEntityExpansion(boolean expand) { 
+        m_expandDTDEntities = expand;     
+    }
+        
+    /**
+     * Sets the end of line characters to be used during serialization
+     * @param eolChars A character array corresponding to the characters to be used.
+     */    
+    public void setNewLine (char[] eolChars) {
+        m_lineSep = eolChars;
+        m_lineSepLen = eolChars.length;
+    }
+
+    /**
+     * Remembers the cdata sections specified in the cdata-section-elements by appending the given
+     * cdata section elements to the list. This method can be called multiple times, but once an
+     * element is put in the list of cdata section elements it can not be removed.
+     * This method should be used by both Xalan and XSLTC.
+     * 
+     * @param URI_and_localNames a whitespace separated list of element names, each element
+     * is a URI in curly braces (optional) and a local name. An example of such a parameter is:
+     * "{http://company.com}price {myURI2}book chapter"
+     */
+    public void addCdataSectionElements(String URI_and_localNames)
+    {
+        if (URI_and_localNames != null)
+            initCdataElems(URI_and_localNames);
+        if (m_StringOfCDATASections == null)
+            m_StringOfCDATASections = URI_and_localNames;
+        else
+            m_StringOfCDATASections += (" " + URI_and_localNames);
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToTextSAXHandler.java b/src/main/java/org/apache/xml/serializer/ToTextSAXHandler.java
new file mode 100644
index 0000000..f472a6d
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToTextSAXHandler.java
@@ -0,0 +1,413 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToTextSAXHandler.java 475978 2006-11-16 23:31:20Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Properties;
+
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class converts SAX-like event to SAX events for
+ * xsl:output method "text". 
+ * 
+ * This class is only to be used internally. This class is not a public API.
+ * 
+ * @deprecated As of Xalan 2.7.1, replaced by the use of {@link ToXMLSAXHandler}.
+ * 
+ * @xsl.usage internal
+ */
+public final class ToTextSAXHandler extends ToSAXHandler 
+{
+    /**
+     * From XSLTC
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public void endElement(String elemName) throws SAXException
+    {
+        if (m_tracer != null)
+            super.fireEndElem(elemName);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
+     */
+    public void endElement(String arg0, String arg1, String arg2)
+        throws SAXException
+    {
+		if (m_tracer != null)
+            super.fireEndElem(arg2);    	
+    }
+
+    public ToTextSAXHandler(ContentHandler hdlr, LexicalHandler lex, String encoding)
+    {
+        super(hdlr, lex, encoding);
+    }
+    
+        /**
+     * From XSLTC
+     */
+    public ToTextSAXHandler(ContentHandler handler, String encoding)
+    {
+        super(handler,encoding);
+    }
+
+    public void comment(char ch[], int start, int length)
+        throws org.xml.sax.SAXException
+    {
+        if (m_tracer != null)
+            super.fireCommentEvent(ch, start, length);
+    }
+
+    public void comment(String data) throws org.xml.sax.SAXException
+    {
+        final int length = data.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length*2 + 1];
+        }
+        data.getChars(0, length, m_charsBuff, 0);
+        comment(m_charsBuff, 0, length);
+    }
+
+    /**
+     * @see Serializer#getOutputFormat()
+     */
+    public Properties getOutputFormat()
+    {
+        return null;
+    }
+
+    /**
+     * @see Serializer#getOutputStream()
+     */
+    public OutputStream getOutputStream()
+    {
+        return null;
+    }
+
+    /**
+     * @see Serializer#getWriter()
+     */
+    public Writer getWriter()
+    {
+        return null;
+    }
+
+    /**
+     * Does nothing because 
+     * the indent attribute is ignored for text output.
+     *
+     */
+    public void indent(int n) throws SAXException
+    {
+    }
+
+    /**
+     * @see Serializer#reset()
+     */
+    public boolean reset()
+    {
+        return false;
+    }
+
+    /**
+     * @see DOMSerializer#serialize(Node)
+     */
+    public void serialize(Node node) throws IOException
+    {
+    }
+
+    /**
+     * @see SerializationHandler#setEscaping(boolean)
+     */
+    public boolean setEscaping(boolean escape)
+    {
+        return false;
+    }
+
+    /**
+     * @see SerializationHandler#setIndent(boolean)
+     */
+    public void setIndent(boolean indent)
+    {
+    }
+
+    /**
+     * @see Serializer#setOutputFormat(Properties)
+     */
+    public void setOutputFormat(Properties format)
+    {
+    }
+
+    /**
+     * @see Serializer#setOutputStream(OutputStream)
+     */
+    public void setOutputStream(OutputStream output)
+    {
+    }
+
+    /**
+     * @see Serializer#setWriter(Writer)
+     */
+    public void setWriter(Writer writer)
+    {
+    }
+
+    /**
+     * @see ExtendedContentHandler#addAttribute(String, String, String, String, String)
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String, String, String)
+     */
+    public void attributeDecl(
+        String arg0,
+        String arg1,
+        String arg2,
+        String arg3,
+        String arg4)
+        throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#elementDecl(String, String)
+     */
+    public void elementDecl(String arg0, String arg1) throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(String, String, String)
+     */
+    public void externalEntityDecl(String arg0, String arg1, String arg2)
+        throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl(String, String)
+     */
+    public void internalEntityDecl(String arg0, String arg1)
+        throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endPrefixMapping(String)
+     */
+    public void endPrefixMapping(String arg0) throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+     */
+    public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
+        throws SAXException
+    {
+    }
+
+    /**
+     * From XSLTC
+     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
+     */
+    public void processingInstruction(String arg0, String arg1)
+        throws SAXException
+    {
+        if (m_tracer != null)
+            super.fireEscapingEvent(arg0, arg1);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
+     */
+    public void setDocumentLocator(Locator arg0)
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#skippedEntity(String)
+     */
+    public void skippedEntity(String arg0) throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
+     */
+    public void startElement(
+        String arg0,
+        String arg1,
+        String arg2,
+        Attributes arg3)
+        throws SAXException
+    {
+        flushPending();
+        super.startElement(arg0, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+     */
+    public void endCDATA() throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#endDTD()
+     */
+    public void endDTD() throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+     */
+    public void startCDATA() throws SAXException
+    {
+    }
+
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
+     */
+    public void startEntity(String arg0) throws SAXException
+    {
+    }
+
+
+    /**
+     * From XSLTC
+     * @see ExtendedContentHandler#startElement(String)
+     */
+    public void startElement(
+    String elementNamespaceURI,
+    String elementLocalName,
+    String elementName) throws SAXException
+    {
+        super.startElement(elementNamespaceURI, elementLocalName, elementName);
+    }
+    
+    public void startElement(
+    String elementName) throws SAXException
+    {
+        super.startElement(elementName);
+    }
+    
+
+    /**
+     * From XSLTC
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException { 
+        
+        flushPending();
+        m_saxHandler.endDocument();
+		
+        if (m_tracer != null)
+            super.fireEndDoc();
+    }
+ 
+    /**
+	 *	
+     * @see ExtendedContentHandler#characters(String)
+     */
+    public void characters(String characters) 
+    throws SAXException 
+    { 
+        final int length = characters.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length*2 + 1];
+        }
+        characters.getChars(0, length, m_charsBuff, 0);
+   
+        m_saxHandler.characters(m_charsBuff, 0, length);
+    
+    }
+    /**
+	 * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+     */
+    public void characters(char[] characters, int offset, int length)
+    throws SAXException 
+    { 
+    
+        m_saxHandler.characters(characters, offset, length);
+
+        // time to fire off characters event
+		if (m_tracer != null)
+            super.fireCharEvent(characters, offset, length);                
+    }
+
+    /**
+     * From XSLTC
+     */
+    public void addAttribute(String name, String value) 
+    {
+        // do nothing
+    }
+
+
+    public boolean startPrefixMapping(
+        String prefix,
+        String uri,
+        boolean shouldFlush)
+        throws SAXException
+    {
+        // no namespace support for HTML
+        return false;
+    }
+
+
+    public void startPrefixMapping(String prefix, String uri)
+        throws org.xml.sax.SAXException
+    {
+        // no namespace support for HTML
+    }
+
+
+    public void namespaceAfterStartElement(
+        final String prefix,
+        final String uri)
+        throws SAXException
+    {
+        // no namespace support for HTML
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToTextStream.java b/src/main/java/org/apache/xml/serializer/ToTextStream.java
new file mode 100644
index 0000000..b0d066e
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToTextStream.java
@@ -0,0 +1,634 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToTextStream.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This class is not a public API.
+ * It is only public because it is used in other packages. 
+ * This class converts SAX or SAX-like calls to a 
+ * serialized document for xsl:output method of "text".
+ * @xsl.usage internal
+ */
+public class ToTextStream extends ToStream 
+{ 
+
+       
+  /**
+   * Default constructor.
+   */
+  public ToTextStream()
+  {
+    super();
+  }
+
+ 
+ 
+  /**
+   * Receive notification of the beginning of a document.
+   *
+   * <p>The SAX parser will invoke this method only once, before any
+   * other methods in this interface or in DTDHandler (except for
+   * setDocumentLocator).</p>
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void startDocumentInternal() throws org.xml.sax.SAXException
+  {
+    super.startDocumentInternal();
+
+    m_needToCallStartDocument = false;
+
+    // No action for the moment.
+  }
+
+  /**
+   * Receive notification of the end of a document.
+   *
+   * <p>The SAX parser will invoke this method only once, and it will
+   * be the last method invoked during the parse.  The parser shall
+   * not invoke this method until it has either abandoned parsing
+   * (because of an unrecoverable error) or reached the end of
+   * input.</p>
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void endDocument() throws org.xml.sax.SAXException
+  {
+    flushPending();
+    flushWriter();
+    if (m_tracer != null)
+        super.fireEndDoc();
+  }
+
+  /**
+   * Receive notification of the beginning of an element.
+   *
+   * <p>The Parser will invoke this method at the beginning of every
+   * element in the XML document; there will be a corresponding
+   * endElement() event for every startElement() event (even when the
+   * element is empty). All of the element's content will be
+   * reported, in order, before the corresponding endElement()
+   * event.</p>
+   *
+   * <p>If the element name has a namespace prefix, the prefix will
+   * still be attached.  Note that the attribute list provided will
+   * contain only attributes with explicit values (specified or
+   * defaulted): #IMPLIED attributes will be omitted.</p>
+   *
+   *
+   * @param namespaceURI The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param name The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @param atts The attributes attached to the element, if any.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see #endElement
+   * @see org.xml.sax.AttributeList
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void startElement(
+          String namespaceURI, String localName, String name, Attributes atts)
+            throws org.xml.sax.SAXException
+  {
+    // time to fire off startElement event
+    if (m_tracer != null) {
+        super.fireStartElem(name);
+        this.firePseudoAttributes();
+    }
+    return;
+  }
+
+  /**
+   * Receive notification of the end of an element.
+   *
+   * <p>The SAX parser will invoke this method at the end of every
+   * element in the XML document; there will be a corresponding
+   * startElement() event for every endElement() event (even when the
+   * element is empty).</p>
+   *
+   * <p>If the element name has a namespace prefix, the prefix will
+   * still be attached to the name.</p>
+   *
+   *
+   * @param namespaceURI The Namespace URI, or the empty string if the
+   *        element has no Namespace URI or if Namespace
+   *        processing is not being performed.
+   * @param localName The local name (without prefix), or the
+   *        empty string if Namespace processing is not being
+   *        performed.
+   * @param name The qualified name (with prefix), or the
+   *        empty string if qualified names are not available.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void endElement(String namespaceURI, String localName, String name)
+          throws org.xml.sax.SAXException
+  {
+        if (m_tracer != null)
+            super.fireEndElem(name);           
+  }
+
+  /**
+   * Receive notification of character data.
+   *
+   * <p>The Parser will call this method to report each chunk of
+   * character data.  SAX parsers may return all contiguous character
+   * data in a single chunk, or they may split it into several
+   * chunks; however, all of the characters in any single event
+   * must come from the same external entity, so that the Locator
+   * provides useful information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * <p>Note that some parsers will report whitespace using the
+   * ignorableWhitespace() method rather than this one (validating
+   * parsers must do so).</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see #ignorableWhitespace
+   * @see org.xml.sax.Locator
+   */
+  public void characters(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    flushPending();    
+    
+    try
+    {
+        if (inTemporaryOutputState()) {
+            /* leave characters un-processed as we are
+             * creating temporary output, the output generated by
+             * this serializer will be input to a final serializer 
+             * later on and it will do the processing in final
+             * output state (not temporary output state).
+             * 
+             * A "temporary" ToTextStream serializer is used to
+             * evaluate attribute value templates (for example),
+             * and the result of evaluating such a thing
+             * is fed into a final serializer later on.
+             */
+            m_writer.write(ch, start, length);
+        }
+        else {
+            // In final output state we do process the characters!
+            writeNormalizedChars(ch, start, length, m_lineSepUse);
+        }
+            
+        if (m_tracer != null)
+            super.fireCharEvent(ch, start, length);      
+    }
+    catch(IOException ioe)
+    {
+      throw new SAXException(ioe);
+    }
+  }
+
+  /**
+   * If available, when the disable-output-escaping attribute is used,
+   * output raw text without escaping.
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   *
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void charactersRaw(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      writeNormalizedChars(ch, start, length, m_lineSepUse);
+    }
+    catch(IOException ioe)
+    {
+      throw new SAXException(ioe);
+    }
+  }
+  
+    /**
+     * Normalize the characters, but don't escape.  Different from 
+     * SerializerToXML#writeNormalizedChars because it does not attempt to do 
+     * XML escaping at all.
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param length The number of characters to read from the array.
+     * @param useLineSep true if the operating systems 
+     * end-of-line separator should be output rather than a new-line character.
+     * 
+     * @throws IOException
+     * @throws org.xml.sax.SAXException
+     */
+    void writeNormalizedChars(
+        final char ch[],
+            final int start,
+            final int length,
+            final boolean useLineSep)
+            throws IOException, org.xml.sax.SAXException 
+    {
+        final String encoding = getEncoding();
+        final java.io.Writer writer = m_writer;
+        final int end = start + length;
+
+        /* copy a few "constants" before the loop for performance */
+        final char S_LINEFEED = CharInfo.S_LINEFEED;
+
+        // This for() loop always increments i by one at the end
+        // of the loop.  Additional increments of i adjust for when
+        // two input characters (a high/low UTF16 surrogate pair)
+        // are processed.
+        for (int i = start; i < end; i++) {
+            final char c = ch[i];
+
+            if (S_LINEFEED == c && useLineSep) {
+                writer.write(m_lineSep, 0, m_lineSepLen);
+                // one input char processed
+            } else if (m_encodingInfo.isInEncoding(c)) {
+                writer.write(c);
+                // one input char processed    
+            } else if (Encodings.isHighUTF16Surrogate(c)) {
+                final int codePoint = writeUTF16Surrogate(c, ch, i, end);
+                if (codePoint != 0) {
+                    // I think we can just emit the message,
+                    // not crash and burn.
+                    final String integralValue = Integer.toString(codePoint);
+                    final String msg = Utils.messages.createMessage(
+                        MsgKey.ER_ILLEGAL_CHARACTER,
+                        new Object[] { integralValue, encoding });
+                      
+                    //Older behavior was to throw the message,
+                    //but newer gentler behavior is to write a message to System.err
+                    //throw new SAXException(msg);
+                    System.err.println(msg);                            
+
+                }
+                i++; // two input chars processed               
+            } else {
+                // Don't know what to do with this char, it is
+                // not in the encoding and not a high char in
+                // a surrogate pair, so write out as an entity ref
+                if (encoding != null) {
+                    /* The output encoding is known, 
+                     * so somthing is wrong.
+                     */
+
+                    // not in the encoding, so write out a character reference
+                    writer.write('&');
+                    writer.write('#');
+                    writer.write(Integer.toString(c));
+                    writer.write(';');
+
+                    // I think we can just emit the message,
+                    // not crash and burn.
+                    final String integralValue = Integer.toString(c);
+                    final String msg = Utils.messages.createMessage(
+                        MsgKey.ER_ILLEGAL_CHARACTER,
+                        new Object[] { integralValue, encoding });
+                      
+                    //Older behavior was to throw the message,
+                    //but newer gentler behavior is to write a message to System.err
+                    //throw new SAXException(msg);
+                    System.err.println(msg); 
+                } else {
+                    /* The output encoding is not known,
+                     * so just write it out as-is.
+                     */
+                    writer.write(c);
+                }
+
+                // one input char was processed
+            }
+        }
+    }
+
+  /**
+   * Receive notification of cdata.
+   *
+   * <p>The Parser will call this method to report each chunk of
+   * character data.  SAX parsers may return all contiguous character
+   * data in a single chunk, or they may split it into several
+   * chunks; however, all of the characters in any single event
+   * must come from the same external entity, so that the Locator
+   * provides useful information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * <p>Note that some parsers will report whitespace using the
+   * ignorableWhitespace() method rather than this one (validating
+   * parsers must do so).</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see #ignorableWhitespace
+   * @see org.xml.sax.Locator
+   */
+  public void cdata(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+    try
+    {
+        writeNormalizedChars(ch, start, length, m_lineSepUse);
+        if (m_tracer != null)
+            super.fireCDATAEvent(ch, start, length);              
+    }
+    catch(IOException ioe)
+    {
+      throw new SAXException(ioe);
+    }
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   * <p>Validating Parsers must use this method to report each chunk
+   * of ignorable whitespace (see the W3C XML 1.0 recommendation,
+   * section 2.10): non-validating parsers may also use this method
+   * if they are capable of parsing and using content models.</p>
+   *
+   * <p>SAX parsers may return all contiguous whitespace in a single
+   * chunk, or they may split it into several chunks; however, all of
+   * the characters in any single event must come from the same
+   * external entity, so that the Locator provides useful
+   * information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see #characters
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    try
+    {
+      writeNormalizedChars(ch, start, length, m_lineSepUse);
+    }
+    catch(IOException ioe)
+    {
+      throw new SAXException(ioe);
+    }
+  }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   * <p>The Parser will invoke this method once for each processing
+   * instruction found: note that processing instructions may occur
+   * before or after the main document element.</p>
+   *
+   * <p>A SAX parser should never report an XML declaration (XML 1.0,
+   * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+   * using this method.</p>
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *        none was supplied.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void processingInstruction(String target, String data)
+          throws org.xml.sax.SAXException
+  {
+    // flush anything pending first
+    flushPending();  
+    
+    if (m_tracer != null)
+        super.fireEscapingEvent(target, data);  
+  }
+
+  /**
+   * Called when a Comment is to be constructed.
+   * Note that Xalan will normally invoke the other version of this method.
+   * %REVIEW% In fact, is this one ever needed, or was it a mistake?
+   *
+   * @param   data  The comment data.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void comment(String data) throws org.xml.sax.SAXException
+  {
+      final int length = data.length();
+      if (length > m_charsBuff.length)
+      {
+          m_charsBuff = new char[length*2 + 1];
+      }
+      data.getChars(0, length, m_charsBuff, 0);
+      comment(m_charsBuff, 0, length);
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   * @throws org.xml.sax.SAXException The application may raise an exception.
+   */
+  public void comment(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+
+    flushPending();
+    if (m_tracer != null)
+        super.fireCommentEvent(ch, start, length);
+  }
+
+  /**
+   * Receive notivication of a entityReference.
+   *
+   * @param name non-null reference to the name of the entity.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void entityReference(String name) throws org.xml.sax.SAXException
+  {
+        if (m_tracer != null)
+            super.fireEntityReference(name);    
+  }
+  
+    /**
+     * @see ExtendedContentHandler#addAttribute(String, String, String, String, String)
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+    {
+        // do nothing, just forget all about the attribute
+    }
+ 
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+     */
+    public void endCDATA() throws SAXException
+    {
+        // do nothing
+    }
+
+    /**
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public void endElement(String elemName) throws SAXException
+    {
+        if (m_tracer != null)
+            super.fireEndElem(elemName);                       
+    }
+ 
+    /**
+     * From XSLTC
+     */
+    public void startElement(
+    String elementNamespaceURI,
+    String elementLocalName,
+    String elementName) 
+    throws SAXException 
+    {
+        if (m_needToCallStartDocument)
+            startDocumentInternal();        
+        // time to fire off startlement event.
+        if (m_tracer != null) {
+            super.fireStartElem(elementName);
+            this.firePseudoAttributes();
+        }
+        
+        return;
+    }
+
+
+    /**
+     * From XSLTC
+     */
+    public void characters(String characters) 
+    throws SAXException 
+    { 
+        final int length = characters.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length*2 + 1];
+        }
+        characters.getChars(0, length, m_charsBuff, 0);
+        characters(m_charsBuff, 0, length); 
+    }
+
+
+    /**
+     * From XSLTC
+     */
+    public void addAttribute(String name, String value)
+    {
+        // do nothing, forget about the attribute
+    }
+    
+    /**
+     * Add a unique attribute
+     */
+    public void addUniqueAttribute(String qName, String value, int flags)
+        throws SAXException
+    {
+        // do nothing, forget about the attribute 
+    }
+
+    public boolean startPrefixMapping(
+        String prefix,
+        String uri,
+        boolean shouldFlush)
+        throws SAXException
+    {
+        // no namespace support for HTML
+        return false;
+    }
+
+
+    public void startPrefixMapping(String prefix, String uri)
+        throws org.xml.sax.SAXException
+    {
+        // no namespace support for HTML
+    }
+
+
+    public void namespaceAfterStartElement(
+        final String prefix,
+        final String uri)
+        throws SAXException
+    {
+        // no namespace support for HTML
+    }    
+
+    public void flushPending() throws org.xml.sax.SAXException
+    {
+            if (m_needToCallStartDocument)
+            {
+                startDocumentInternal();
+                m_needToCallStartDocument = false;
+            }
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToUnknownStream.java b/src/main/java/org/apache/xml/serializer/ToUnknownStream.java
new file mode 100644
index 0000000..baa1ca2
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToUnknownStream.java
@@ -0,0 +1,1316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToUnknownStream.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Transformer;
+
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+
+/**
+ *This class wraps another SerializationHandler. The wrapped object will either
+ * handler XML or HTML, which is not known until a little later when the first XML
+ * tag is seen.  If the first tag is <html> then the wrapped object is an HTML
+ * handler, otherwise it is an XML handler.
+ *
+ * This class effectively caches the first few calls to it then passes them
+ * on to the wrapped handler (once it exists).  After that subsequent calls a
+ * simply passed directly to the wrapped handler.
+ *
+ * The user of this class doesn't know if the output is ultimatley XML or HTML.
+ * 
+ * This class is not a public API, it is public because it is used within Xalan.
+ * @xsl.usage internal
+ */
+public final class ToUnknownStream extends SerializerBase
+{
+
+    /**
+     * The wrapped handler, initially XML but possibly switched to HTML
+     */
+    private SerializationHandler m_handler;
+
+    /**
+     * A String with no characters
+     */
+    private static final String EMPTYSTRING = "";
+
+    /**
+     * true if the underlying handler (XML or HTML) is fully initialized
+     */
+    private boolean m_wrapped_handler_not_initialized = false;
+
+
+    /**
+     * the prefix of the very first tag in the document
+     */
+    private String m_firstElementPrefix;
+    /**
+     * the element name (including any prefix) of the very first tag in the document
+     */
+    private String m_firstElementName;
+
+    /**
+     * the namespace URI associated with the first element
+     */
+    private String m_firstElementURI;
+    
+    /**
+     * the local name (no prefix) associated with the first element
+     */
+    private String m_firstElementLocalName = null;
+
+    /**
+     * true if the first tag has been emitted to the wrapped handler
+     */
+    private boolean m_firstTagNotEmitted = true;
+
+    /**
+     * A collection of namespace URI's (only for first element).
+     * _namespacePrefix has the matching prefix for these URI's
+     */
+    private Vector m_namespaceURI = null;
+    /**
+     * A collection of namespace Prefix (only for first element)
+     * _namespaceURI has the matching URIs for these prefix'
+     */
+    private Vector m_namespacePrefix = null;
+
+    /**
+     * true if startDocument() was called before the underlying handler
+     * was initialized
+     */
+    private boolean m_needToCallStartDocument = false;
+    /**
+     * true if setVersion() was called before the underlying handler
+     * was initialized
+     */
+    private boolean m_setVersion_called = false;
+    /**
+     * true if setDoctypeSystem() was called before the underlying handler
+     * was initialized
+     */
+    private boolean m_setDoctypeSystem_called = false;
+    /**
+     * true if setDoctypePublic() was called before the underlying handler
+     * was initialized
+     */
+    private boolean m_setDoctypePublic_called = false;
+    /**
+     * true if setMediaType() was called before the underlying handler
+     * was initialized
+     */
+    private boolean m_setMediaType_called = false;
+
+    /**
+     * Default constructor.
+     * Initially this object wraps an XML Stream object, so _handler is never null.
+     * That may change later to an HTML Stream object.
+     */
+    public ToUnknownStream()
+    {
+        m_handler = new ToXMLStream();
+    }
+
+    /**
+     * @see Serializer#asContentHandler()
+     * @return the wrapped XML or HTML handler
+     */
+    public ContentHandler asContentHandler() throws IOException
+    {
+        /* don't return the real handler ( m_handler ) because
+         * that would expose the real handler to the outside.
+         * Keep m_handler private so it can be internally swapped
+         * to an HTML handler.
+         */
+        return this;
+    }
+
+    /**
+     * @see SerializationHandler#close()
+     */
+    public void close()
+    {
+        m_handler.close();
+    }
+
+    /**
+     * @see Serializer#getOutputFormat()
+     * @return the properties of the underlying handler
+     */
+    public Properties getOutputFormat()
+    {
+        return m_handler.getOutputFormat();
+    }
+
+    /**
+     * @see Serializer#getOutputStream()
+     * @return the OutputStream of the underlying XML or HTML handler
+     */
+    public OutputStream getOutputStream()
+    {
+        return m_handler.getOutputStream();
+    }
+
+    /**
+     * @see Serializer#getWriter()
+     * @return the Writer of the underlying XML or HTML handler
+     */
+    public Writer getWriter()
+    {
+        return m_handler.getWriter();
+    }
+
+    /**
+     * passes the call on to the underlying HTML or XML handler
+     * @see Serializer#reset()
+     * @return ???
+     */
+    public boolean reset()
+    {
+        return m_handler.reset();
+    }
+
+    /**
+     * Converts the DOM node to output
+     * @param node the DOM node to transform to output
+     * @see DOMSerializer#serialize(Node)
+     *
+     */
+    public void serialize(Node node) throws IOException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.serialize(node);
+    }
+
+    /**
+     * @see SerializationHandler#setEscaping(boolean)
+     */
+    public boolean setEscaping(boolean escape) throws SAXException
+    {
+        return m_handler.setEscaping(escape);
+    }
+
+    /**
+     * Set the properties of the handler
+     * @param format the output properties to set
+     * @see Serializer#setOutputFormat(Properties)
+     */
+    public void setOutputFormat(Properties format)
+    {
+        m_handler.setOutputFormat(format);
+    }
+
+    /**
+     * Sets the output stream to write to
+     * @param output the OutputStream to write to
+     * @see Serializer#setOutputStream(OutputStream)
+     */
+    public void setOutputStream(OutputStream output)
+    {
+        m_handler.setOutputStream(output);
+    }
+
+    /**
+     * Sets the writer to write to
+     * @param writer the writer to write to
+     * @see Serializer#setWriter(Writer)
+     */
+    public void setWriter(Writer writer)
+    {
+        m_handler.setWriter(writer);
+    }
+
+    /**
+     * Adds an attribute to the currenly open tag
+     * @param uri the URI of a namespace
+     * @param localName the attribute name, without prefix
+     * @param rawName the attribute name, with prefix (if any)
+     * @param type the type of the attribute, typically "CDATA"
+     * @param value the value of the parameter
+     * @param XSLAttribute true if this attribute is coming from an xsl:attribute element
+     * @see ExtendedContentHandler#addAttribute(String, String, String, String, String)
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.addAttribute(uri, localName, rawName, type, value, XSLAttribute);
+    }
+    /**
+     * Adds an attribute to the currenly open tag
+     * @param rawName the attribute name, with prefix (if any)
+     * @param value the value of the parameter
+     * @see ExtendedContentHandler#addAttribute(String, String)
+     */
+    public void addAttribute(String rawName, String value)
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.addAttribute(rawName, value);
+ 
+    }
+
+    /**
+     * Adds a unique attribute to the currenly open tag
+     */
+    public void addUniqueAttribute(String rawName, String value, int flags)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.addUniqueAttribute(rawName, value, flags);
+ 
+    }
+
+    /**
+     * Converts the String to a character array and calls the SAX method 
+     * characters(char[],int,int);
+     * 
+     * @see ExtendedContentHandler#characters(String)
+     */
+    public void characters(String chars) throws SAXException
+    {
+        final int length = chars.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length*2 + 1];
+        }
+        chars.getChars(0, length, m_charsBuff, 0);
+        this.characters(m_charsBuff, 0, length);  
+    }    
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public void endElement(String elementName) throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.endElement(elementName);
+    }
+
+
+    /**
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
+     * @param prefix The prefix that maps to the URI
+     * @param uri The URI for the namespace
+     */
+    public void startPrefixMapping(String prefix, String uri) throws SAXException
+    {
+        this.startPrefixMapping(prefix,uri, true);
+    }
+
+    /**
+     * This method is used when a prefix/uri namespace mapping
+     * is indicated after the element was started with a
+     * startElement() and before and endElement().
+     * startPrefixMapping(prefix,uri) would be used before the
+     * startElement() call.
+     * @param uri the URI of the namespace
+     * @param prefix the prefix associated with the given URI.
+     *
+     * @see ExtendedContentHandler#namespaceAfterStartElement(String, String)
+     */    
+    public void namespaceAfterStartElement(String prefix, String uri)
+        throws SAXException 
+    {  
+        // hack for XSLTC with finding URI for default namespace
+        if (m_firstTagNotEmitted && m_firstElementURI == null && m_firstElementName != null)
+        {
+            String prefix1 = getPrefixPart(m_firstElementName);
+            if (prefix1 == null && EMPTYSTRING.equals(prefix))
+            {
+                // the elements URI is not known yet, and it
+                // doesn't have a prefix, and we are currently
+                // setting the uri for prefix "", so we have
+                // the uri for the element... lets remember it
+                m_firstElementURI = uri;
+            }
+        }         
+        startPrefixMapping(prefix,uri, false);          
+    }
+    
+    public boolean startPrefixMapping(String prefix, String uri, boolean shouldFlush)
+        throws SAXException
+    {
+        boolean pushed = false;
+        if (m_firstTagNotEmitted)
+        {
+            if (m_firstElementName != null && shouldFlush)
+            {
+                /* we've already seen a startElement, and this is a prefix mapping
+                 * for the up coming element, so flush the old element
+                 * then send this event on its way.
+                 */
+                flush();
+                pushed = m_handler.startPrefixMapping(prefix, uri, shouldFlush);
+            } 
+            else 
+            {           
+                if (m_namespacePrefix == null)
+                {
+                    m_namespacePrefix = new Vector();
+                    m_namespaceURI = new Vector();
+                }
+                m_namespacePrefix.addElement(prefix);
+                m_namespaceURI.addElement(uri);
+            
+                if (m_firstElementURI == null)
+                {
+                    if (prefix.equals(m_firstElementPrefix))
+                        m_firstElementURI = uri;
+                }
+            }
+
+        }
+        else
+        {
+           pushed = m_handler.startPrefixMapping(prefix, uri, shouldFlush);
+        }
+        return pushed;
+    }
+
+    /**
+      * This method cannot be cached because default is different in
+      * HTML and XML (we need more than a boolean).
+      */
+
+    public void setVersion(String version)
+    {
+        m_handler.setVersion(version);
+
+        // Cache call to setVersion()
+        //       super.setVersion(version);
+        m_setVersion_called = true;
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException
+    {
+        m_needToCallStartDocument = true;
+    }
+
+ 
+    
+    public void startElement(String qName) throws SAXException
+    {
+        this.startElement(null, null, qName, null);
+    }
+    
+    public void startElement(String namespaceURI, String localName, String qName) throws SAXException
+    {
+        this.startElement(namespaceURI, localName, qName, null);
+    }
+
+    public void startElement(
+        String namespaceURI,
+        String localName,
+        String elementName,
+        Attributes atts) throws SAXException
+    {
+        /* we are notified of the start of an element */
+        if (m_firstTagNotEmitted)
+        {
+            /* we have not yet sent the first element on its way */
+            if (m_firstElementName != null) 
+            {
+                /* this is not the first element, but a later one.
+                 * But we have the old element pending, so flush it out,
+                 * then send this one on its way. 
+                 */
+                flush();
+                m_handler.startElement(namespaceURI, localName, elementName,  atts);                
+            }
+            else
+            {
+                /* this is the very first element that we have seen, 
+                 * so save it for flushing later.  We may yet get to know its
+                 * URI due to added attributes.
+                 */
+                 
+                m_wrapped_handler_not_initialized = true;
+                m_firstElementName = elementName;
+                
+                // null if not known
+                m_firstElementPrefix = getPrefixPartUnknown(elementName);
+                
+                // null if not known
+                m_firstElementURI = namespaceURI;
+                
+                // null if not known
+                m_firstElementLocalName = localName;
+
+                if (m_tracer != null)
+                    firePseudoElement(elementName);
+                    
+                /* we don't want to call our own addAttributes, which
+                 * merely delegates to the wrapped handler, but we want to
+                 * add these attributes to m_attributes. So me must call super.
+                 * addAttributes() In this case m_attributes is only used for the
+                 * first element, after that this class totally delegates to the
+                 * wrapped handler which is either XML or HTML.
+                 */
+                if (atts != null)   
+                    super.addAttributes(atts);
+                
+                // if there are attributes, then lets make the flush()
+                // call the startElement on the handler and send the
+                // attributes on their way.
+                if (atts != null)   
+                    flush();
+                
+            }
+        }
+        else
+        {
+            // this is not the first element, but a later one, so just
+            // send it on its way.
+            m_handler.startElement(namespaceURI, localName, elementName,  atts);
+        }
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see ExtendedLexicalHandler#comment(String)
+     */
+    public void comment(String comment) throws SAXException
+    {
+        if (m_firstTagNotEmitted && m_firstElementName != null)
+        {
+            emitFirstTag();
+        }
+        else if (m_needToCallStartDocument)
+        {
+            m_handler.startDocument();
+            m_needToCallStartDocument = false;
+        }
+
+        m_handler.comment(comment);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getDoctypePublic()
+     */
+    public String getDoctypePublic()
+    {
+
+        return m_handler.getDoctypePublic();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getDoctypeSystem()
+     */
+    public String getDoctypeSystem()
+    {
+        return m_handler.getDoctypeSystem();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getEncoding()
+     */
+    public String getEncoding()
+    {
+        return m_handler.getEncoding();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getIndent()
+     */
+    public boolean getIndent()
+    {
+        return m_handler.getIndent();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getIndentAmount()
+     */
+    public int getIndentAmount()
+    {
+        return m_handler.getIndentAmount();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getMediaType()
+     */
+    public String getMediaType()
+    {
+        return m_handler.getMediaType();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getOmitXMLDeclaration()
+     */
+    public boolean getOmitXMLDeclaration()
+    {
+        return m_handler.getOmitXMLDeclaration();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getStandalone()
+     */
+    public String getStandalone()
+    {
+        return m_handler.getStandalone();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#getVersion()
+     */
+    public String getVersion()
+    {
+        return m_handler.getVersion();
+    }
+
+    /**
+     * @see XSLOutputAttributes#setDoctype(String, String)
+     */
+    public void setDoctype(String system, String pub)
+    {
+        m_handler.setDoctypePublic(pub);
+        m_handler.setDoctypeSystem(system);
+    }
+
+    /**
+     * Set the doctype in the underlying XML handler. Remember that this method
+     * was called, just in case we need to transfer this doctype to an HTML handler
+     * @param doctype the public doctype to set
+     * @see XSLOutputAttributes#setDoctypePublic(String)
+     */
+    public void setDoctypePublic(String doctype)
+    {
+        m_handler.setDoctypePublic(doctype);
+        m_setDoctypePublic_called = true;
+    }
+
+    /**
+     * Set the doctype in the underlying XML handler. Remember that this method
+     * was called, just in case we need to transfer this doctype to an HTML handler
+     * @param doctype the system doctype to set
+     * @see XSLOutputAttributes#setDoctypeSystem(String)
+     */
+    public void setDoctypeSystem(String doctype)
+    {
+        m_handler.setDoctypeSystem(doctype);
+        m_setDoctypeSystem_called = true;
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#setEncoding(String)
+     */
+    public void setEncoding(String encoding)
+    {
+        m_handler.setEncoding(encoding);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#setIndent(boolean)
+     */
+    public void setIndent(boolean indent)
+    {
+        m_handler.setIndent(indent);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     */
+    public void setIndentAmount(int value)
+    {
+        m_handler.setIndentAmount(value);
+    }
+
+    /**
+     * @see XSLOutputAttributes#setMediaType(String)
+     */
+    public void setMediaType(String mediaType)
+    {
+        m_handler.setMediaType(mediaType);
+        m_setMediaType_called = true;
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#setOmitXMLDeclaration(boolean)
+     */
+    public void setOmitXMLDeclaration(boolean b)
+    {
+        m_handler.setOmitXMLDeclaration(b);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see XSLOutputAttributes#setStandalone(String)
+     */
+    public void setStandalone(String standalone)
+    {
+        m_handler.setStandalone(standalone);
+    }
+
+    /**
+     * @see XSLOutputAttributes#setVersion(String)
+     */
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String, String, String)
+     */
+    public void attributeDecl(
+        String arg0,
+        String arg1,
+        String arg2,
+        String arg3,
+        String arg4)
+        throws SAXException
+    {
+        m_handler.attributeDecl(arg0, arg1, arg2, arg3, arg4);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.DeclHandler#elementDecl(String, String)
+     */
+    public void elementDecl(String arg0, String arg1) throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            emitFirstTag();
+        }
+        m_handler.elementDecl(arg0, arg1);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(String, String, String)
+     */
+    public void externalEntityDecl(
+        String name,
+        String publicId,
+        String systemId)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.externalEntityDecl(name, publicId, systemId);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl(String, String)
+     */
+    public void internalEntityDecl(String arg0, String arg1)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.internalEntityDecl(arg0, arg1);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+     */
+    public void characters(char[] characters, int offset, int length)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+
+        m_handler.characters(characters, offset, length);
+
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+
+        m_handler.endDocument();
+        
+    
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
+     */
+    public void endElement(String namespaceURI, String localName, String qName)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+            if (namespaceURI == null && m_firstElementURI != null)
+                namespaceURI = m_firstElementURI;
+
+
+            if (localName == null && m_firstElementLocalName != null)
+                localName = m_firstElementLocalName;
+        }
+        
+        m_handler.endElement(namespaceURI, localName, qName);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#endPrefixMapping(String)
+     */
+    public void endPrefixMapping(String prefix) throws SAXException
+    {
+        m_handler.endPrefixMapping(prefix);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+     */
+    public void ignorableWhitespace(char[] ch, int start, int length)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+        m_handler.ignorableWhitespace(ch, start, length);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
+     */
+    public void processingInstruction(String target, String data)
+        throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+
+        m_handler.processingInstruction(target, data);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
+     */
+    public void setDocumentLocator(Locator locator)
+    {
+        m_handler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ContentHandler#skippedEntity(String)
+     */
+    public void skippedEntity(String name) throws SAXException
+    {
+        m_handler.skippedEntity(name);
+    }
+
+
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+     */
+    public void comment(char[] ch, int start, int length) throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            flush();
+        }
+
+        m_handler.comment(ch, start, length);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+     */
+    public void endCDATA() throws SAXException
+    {
+
+        m_handler.endCDATA();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#endDTD()
+     */
+    public void endDTD() throws SAXException
+    {
+
+        m_handler.endDTD();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#endEntity(String)
+     */
+    public void endEntity(String name) throws SAXException
+    {
+        if (m_firstTagNotEmitted)
+        {
+            emitFirstTag();
+        }
+        m_handler.endEntity(name);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+     */
+    public void startCDATA() throws SAXException
+    {
+        m_handler.startCDATA();
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String)
+     */
+    public void startDTD(String name, String publicId, String systemId)
+        throws SAXException
+    {
+        m_handler.startDTD(name, publicId, systemId);
+    }
+
+    /**
+     * Pass the call on to the underlying handler
+     * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
+     */
+    public void startEntity(String name) throws SAXException
+    {
+        m_handler.startEntity(name);
+    }
+
+    /**
+     * Initialize the wrapped output stream (XML or HTML).
+     * If the stream handler should be HTML, then replace the XML handler with
+     * an HTML handler. After than send the starting method calls that were cached
+     * to the wrapped handler.
+     *
+     */
+    private void initStreamOutput() throws SAXException
+    {
+
+        // Try to rule out if this is an not to be an HTML document based on prefix
+        boolean firstElementIsHTML = isFirstElemHTML();
+
+        if (firstElementIsHTML)
+        {
+            // create an HTML output handler, and initialize it
+
+            // keep a reference to the old handler, ... it will soon be gone
+            SerializationHandler oldHandler = m_handler;
+
+            /* We have to make sure we get an output properties with the proper
+             * defaults for the HTML method.  The easiest way to do this is to
+             * have the OutputProperties class do it.
+             */
+
+            Properties htmlProperties =
+                OutputPropertiesFactory.getDefaultMethodProperties(Method.HTML);
+            Serializer serializer =
+                SerializerFactory.getSerializer(htmlProperties);
+
+            // The factory should be returning a ToStream
+            // Don't know what to do if it doesn't
+            // i.e. the user has over-ridden the content-handler property
+            // for html
+            m_handler = (SerializationHandler) serializer;
+            //m_handler = new ToHTMLStream();
+
+            Writer writer = oldHandler.getWriter();
+
+            if (null != writer)
+                m_handler.setWriter(writer);
+            else
+            {
+                OutputStream os = oldHandler.getOutputStream();
+
+                if (null != os)
+                    m_handler.setOutputStream(os);
+            }
+
+            // need to copy things from the old handler to the new one here
+
+            //            if (_setVersion_called)
+            //            {
+            m_handler.setVersion(oldHandler.getVersion());
+            //            }
+            //            if (_setDoctypeSystem_called)
+            //            {
+            m_handler.setDoctypeSystem(oldHandler.getDoctypeSystem());
+            //            }
+            //            if (_setDoctypePublic_called)
+            //            {
+            m_handler.setDoctypePublic(oldHandler.getDoctypePublic());
+            //            }
+            //            if (_setMediaType_called)
+            //            {
+            m_handler.setMediaType(oldHandler.getMediaType());
+            //            }
+            
+            m_handler.setTransformer(oldHandler.getTransformer());
+        }
+
+        /* Now that we have a real wrapped handler (XML or HTML) lets
+         * pass any cached calls to it
+         */
+        // Call startDocument() if necessary
+        if (m_needToCallStartDocument)
+        {
+            m_handler.startDocument();
+            m_needToCallStartDocument = false;
+        }
+
+        // the wrapped handler is now fully initialized
+        m_wrapped_handler_not_initialized = false;
+    }
+
+    private void emitFirstTag() throws SAXException
+    {   
+        if (m_firstElementName != null)
+        {
+            if (m_wrapped_handler_not_initialized)
+            {
+                initStreamOutput();
+                m_wrapped_handler_not_initialized = false;
+            }
+            // Output first tag
+            m_handler.startElement(m_firstElementURI, null, m_firstElementName, m_attributes);
+            // don't need the collected attributes of the first element anymore.
+            m_attributes = null;
+
+            // Output namespaces of first tag
+            if (m_namespacePrefix != null)
+            {
+                final int n = m_namespacePrefix.size();
+                for (int i = 0; i < n; i++)
+                {
+                    final String prefix =
+                        (String) m_namespacePrefix.elementAt(i);
+                    final String uri = (String) m_namespaceURI.elementAt(i);
+                    m_handler.startPrefixMapping(prefix, uri, false);
+                }
+                m_namespacePrefix = null;
+                m_namespaceURI = null;
+            }
+            m_firstTagNotEmitted = false;
+        }
+    }
+
+    /**
+     * Utility function for calls to local-name().
+     *
+     * Don't want to override static function on SerializerBase
+     * So added Unknown suffix to method name.
+     */
+    private String getLocalNameUnknown(String value)
+    {
+        int idx = value.lastIndexOf(':');
+        if (idx >= 0)
+            value = value.substring(idx + 1);
+        idx = value.lastIndexOf('@');
+        if (idx >= 0)
+            value = value.substring(idx + 1);
+        return (value);
+    }
+
+    /**
+         * Utility function to return prefix
+         *
+         * Don't want to override static function on SerializerBase
+         * So added Unknown suffix to method name.
+         */
+    private String getPrefixPartUnknown(String qname)
+    {
+        final int index = qname.indexOf(':');
+        return (index > 0) ? qname.substring(0, index) : EMPTYSTRING;
+    }
+
+    /**
+     * Determine if the firts element in the document is <html> or <HTML>
+     * This uses the cached first element name, first element prefix and the
+     * cached namespaces from previous method calls
+     *
+     * @return true if the first element is an opening <html> tag
+     */
+    private boolean isFirstElemHTML()
+    {
+        boolean isHTML;
+
+        // is the first tag html, not considering the prefix ?
+        isHTML =
+            getLocalNameUnknown(m_firstElementName).equalsIgnoreCase("html");
+
+        // Try to rule out if this is not to be an HTML document based on URI
+        if (isHTML
+            && m_firstElementURI != null
+            && !EMPTYSTRING.equals(m_firstElementURI))
+        {
+            // the <html> element has a non-trivial namespace
+            isHTML = false;
+        }
+        // Try to rule out if this is an not to be an HTML document based on prefix
+        if (isHTML && m_namespacePrefix != null)
+        {
+            /* the first element has a name of "html", but lets check the prefix.
+             * If the prefix points to a namespace with a URL that is not ""
+             * then the doecument doesn't start with an <html> tag, and isn't html
+             */
+            final int max = m_namespacePrefix.size();
+            for (int i = 0; i < max; i++)
+            {
+                final String prefix = (String) m_namespacePrefix.elementAt(i);
+                final String uri = (String) m_namespaceURI.elementAt(i);
+
+                if (m_firstElementPrefix != null
+                    && m_firstElementPrefix.equals(prefix)
+                    && !EMPTYSTRING.equals(uri))
+                {
+                    // The first element has a prefix, so it can't be <html>
+                    isHTML = false;
+                    break;
+                }
+            }
+
+        }
+        return isHTML;
+    }
+    /**
+     * @see Serializer#asDOMSerializer()
+     */
+    public DOMSerializer asDOMSerializer() throws IOException
+    {
+        return m_handler.asDOMSerializer();
+    }
+
+    /**
+     * @param URI_and_localNames Vector a list of pairs of URI/localName
+     * specified in the cdata-section-elements attribute.
+     * @see SerializationHandler#setCdataSectionElements(java.util.Vector)
+     */
+    public void setCdataSectionElements(Vector URI_and_localNames)
+    {
+        m_handler.setCdataSectionElements(URI_and_localNames);
+    }
+    /**
+     * @see ExtendedContentHandler#addAttributes(org.xml.sax.Attributes)
+     */
+    public void addAttributes(Attributes atts) throws SAXException
+    {
+        m_handler.addAttributes(atts);
+    }
+
+    /**
+     * Get the current namespace mappings.
+     * Simply returns the mappings of the wrapped handler.
+     * @see ExtendedContentHandler#getNamespaceMappings()
+     */
+    public NamespaceMappings getNamespaceMappings()
+    {
+        NamespaceMappings mappings = null;
+        if (m_handler != null)
+        {
+            mappings = m_handler.getNamespaceMappings();
+        }
+        return mappings;
+    }
+    /**
+     * @see SerializationHandler#flushPending()
+     */
+    public void flushPending() throws SAXException
+    {
+ 
+        flush();
+      
+        m_handler.flushPending();
+    }
+    
+    private void flush()
+    {
+        try
+        {
+        if (m_firstTagNotEmitted)
+        {
+            emitFirstTag();
+        }
+        if (m_needToCallStartDocument)
+        {
+            m_handler.startDocument();
+            m_needToCallStartDocument = false;
+        }
+        }
+        catch(SAXException e)
+        {
+            throw new RuntimeException(e.toString());
+        }
+          
+    
+    }
+
+    /**
+     * @see ExtendedContentHandler#getPrefix
+     */
+    public String getPrefix(String namespaceURI)
+    {
+        return m_handler.getPrefix(namespaceURI);
+    }
+    /**
+     * @see ExtendedContentHandler#entityReference(java.lang.String)
+     */
+    public void entityReference(String entityName) throws SAXException
+    {
+        m_handler.entityReference(entityName);
+    }
+
+    /**
+     * @see ExtendedContentHandler#getNamespaceURI(java.lang.String, boolean)
+     */
+    public String getNamespaceURI(String qname, boolean isElement)
+    {
+        return m_handler.getNamespaceURI(qname, isElement);
+    }
+
+    public String getNamespaceURIFromPrefix(String prefix)
+    {
+        return m_handler.getNamespaceURIFromPrefix(prefix);
+    }
+
+    public void setTransformer(Transformer t)
+    {       
+        m_handler.setTransformer(t);
+        if ((t instanceof SerializerTrace) &&
+            (((SerializerTrace) t).hasTraceListeners())) {
+           m_tracer = (SerializerTrace) t;
+        } else {
+           m_tracer = null;
+        }        
+    }
+    public Transformer getTransformer()
+    {
+        return m_handler.getTransformer();
+    }
+
+    /**
+     * @see SerializationHandler#setContentHandler(org.xml.sax.ContentHandler)
+     */
+    public void setContentHandler(ContentHandler ch)
+    {
+        m_handler.setContentHandler(ch);
+    }
+    /**
+     * This method is used to set the source locator, which might be used to
+     * generated an error message.
+     * @param locator the source locator
+     *
+     * @see ExtendedContentHandler#setSourceLocator(javax.xml.transform.SourceLocator)
+     */    
+    public void setSourceLocator(SourceLocator locator)
+    {
+        m_handler.setSourceLocator(locator);
+    }
+
+    protected void firePseudoElement(String elementName)
+    {
+        
+        if (m_tracer != null) {
+            StringBuffer sb = new StringBuffer();
+                
+            sb.append('<');
+            sb.append(elementName);
+            
+            // convert the StringBuffer to a char array and
+            // emit the trace event that these characters "might"
+            // be written
+            char ch[] = sb.toString().toCharArray();
+            m_tracer.fireGenerateEvent(
+                SerializerTrace.EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS,
+                ch,
+                0,
+                ch.length);
+        }
+    }
+
+    /**
+     * @see org.apache.xml.serializer.Serializer#asDOM3Serializer()
+     */
+    public Object asDOM3Serializer() throws IOException
+    {
+        return m_handler.asDOM3Serializer();
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToXMLSAXHandler.java b/src/main/java/org/apache/xml/serializer/ToXMLSAXHandler.java
new file mode 100644
index 0000000..edb1e35
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToXMLSAXHandler.java
@@ -0,0 +1,774 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToXMLSAXHandler.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+ package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Properties;
+
+import javax.xml.transform.Result;
+
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class receives notification of SAX-like events, and with gathered
+ * information over these calls it will invoke the equivalent SAX methods
+ * on a handler, the ultimate xsl:output method is known to be "xml".
+ * 
+ * This class is not a public API.
+ * @xsl.usage internal
+ */
+public final class ToXMLSAXHandler extends ToSAXHandler
+{
+
+    /**
+     * Keeps track of whether output escaping is currently enabled
+     */
+    protected boolean m_escapeSetting = true;
+
+    public ToXMLSAXHandler()
+    {
+        // default constructor (need to set content handler ASAP !)
+        m_prefixMap = new NamespaceMappings();
+        initCDATA();
+    }
+
+    /**
+     * @see Serializer#getOutputFormat()
+     */
+    public Properties getOutputFormat()
+    {
+        return null;
+    }
+
+    /**
+     * @see Serializer#getOutputStream()
+     */
+    public OutputStream getOutputStream()
+    {
+        return null;
+    }
+
+    /**
+     * @see Serializer#getWriter()
+     */
+    public Writer getWriter()
+    {
+        return null;
+    }
+
+    /**
+     * Do nothing for SAX.
+     */
+    public void indent(int n) throws SAXException
+    {
+    }
+
+
+    /**
+     * @see DOMSerializer#serialize(Node)
+     */
+    public void serialize(Node node) throws IOException
+    {
+    }
+
+    /**
+     * @see SerializationHandler#setEscaping(boolean)
+     */
+    public boolean setEscaping(boolean escape) throws SAXException
+    {
+        boolean oldEscapeSetting = m_escapeSetting;
+        m_escapeSetting = escape;
+
+        if (escape) {
+            processingInstruction(Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+        } else {
+            processingInstruction(Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+        }
+
+        return oldEscapeSetting;
+    }
+
+    /**
+     * @see Serializer#setOutputFormat(Properties)
+     */
+    public void setOutputFormat(Properties format)
+    {
+    }
+
+    /**
+     * @see Serializer#setOutputStream(OutputStream)
+     */
+    public void setOutputStream(OutputStream output)
+    {
+    }
+
+    /**
+     * @see Serializer#setWriter(Writer)
+     */
+    public void setWriter(Writer writer)
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String, String, String)
+     */
+    public void attributeDecl(
+        String arg0,
+        String arg1,
+        String arg2,
+        String arg3,
+        String arg4)
+        throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#elementDecl(String, String)
+     */
+    public void elementDecl(String arg0, String arg1) throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(String, String, String)
+     */
+    public void externalEntityDecl(String arg0, String arg1, String arg2)
+        throws SAXException
+    {
+    }
+
+    /**
+     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl(String, String)
+     */
+    public void internalEntityDecl(String arg0, String arg1)
+        throws SAXException
+    {
+    }
+
+    /**
+     * Receives notification of the end of the document.
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException
+    {
+
+        flushPending();
+
+        // Close output document
+        m_saxHandler.endDocument();
+
+        if (m_tracer != null)
+            super.fireEndDoc();
+    }
+
+    /**
+     * This method is called when all the data needed for a call to the
+     * SAX handler's startElement() method has been gathered.
+     */
+    protected void closeStartTag() throws SAXException
+    {
+
+        m_elemContext.m_startTagOpen = false;
+
+        final String localName = getLocalName(m_elemContext.m_elementName);
+        final String uri = getNamespaceURI(m_elemContext.m_elementName, true);
+
+        // Now is time to send the startElement event
+        if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+        }
+        m_saxHandler.startElement(uri, localName, m_elemContext.m_elementName, m_attributes);
+        // we've sent the official SAX attributes on their way,
+        // now we don't need them anymore.
+        m_attributes.clear();
+
+        if(m_state != null)
+          m_state.setCurrentNode(null);
+    }
+
+    /**
+     * Closes ane open cdata tag, and
+     * unlike the this.endCDATA() method (from the LexicalHandler) interface,
+     * this "internal" method will send the endCDATA() call to the wrapped
+     * handler.
+     * 
+     */
+    public void closeCDATA() throws SAXException
+    {
+
+        // Output closing bracket - "]]>"
+        if (m_lexHandler != null && m_cdataTagOpen) {
+            m_lexHandler.endCDATA();
+        }
+        
+
+        // There are no longer any calls made to 
+        // m_lexHandler.startCDATA() without a balancing call to
+        // m_lexHandler.endCDATA()
+        // so we set m_cdataTagOpen to false to remember this.
+        m_cdataTagOpen = false;        
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
+     */
+    public void endElement(String namespaceURI, String localName, String qName)
+        throws SAXException
+    {
+        // Close any open elements etc.
+        flushPending();
+        
+        if (namespaceURI == null)
+        {
+            if (m_elemContext.m_elementURI != null)
+                namespaceURI = m_elemContext.m_elementURI;
+            else
+                namespaceURI = getNamespaceURI(qName, true);
+        }
+        
+        if (localName == null)
+        {
+            if (m_elemContext.m_elementLocalName != null)
+                localName = m_elemContext.m_elementLocalName;
+            else
+                localName = getLocalName(qName);
+        }
+
+        m_saxHandler.endElement(namespaceURI, localName, qName);
+
+        if (m_tracer != null)
+            super.fireEndElem(qName);       
+
+        /* Pop all namespaces at the current element depth.
+         * We are not waiting for official endPrefixMapping() calls.
+         */
+        m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth,
+            m_saxHandler);
+        m_elemContext = m_elemContext.m_prev;
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endPrefixMapping(String)
+     */
+    public void endPrefixMapping(String prefix) throws SAXException
+    {
+        /* poping all prefix mappings should have been done
+         * in endElement() already
+         */
+         return;
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+     */
+    public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
+        throws SAXException
+    {
+        m_saxHandler.ignorableWhitespace(arg0,arg1,arg2);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
+     */
+    public void setDocumentLocator(Locator arg0)
+    {
+        m_saxHandler.setDocumentLocator(arg0);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#skippedEntity(String)
+     */
+    public void skippedEntity(String arg0) throws SAXException
+    {
+        m_saxHandler.skippedEntity(arg0);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
+     * @param prefix The prefix that maps to the URI
+     * @param uri The URI for the namespace
+     */
+    public void startPrefixMapping(String prefix, String uri)
+        throws SAXException
+    {
+       startPrefixMapping(prefix, uri, true);
+    }
+
+    /**
+     * Remember the prefix/uri mapping at the current nested element depth.
+     *
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
+     * @param prefix The prefix that maps to the URI
+     * @param uri The URI for the namespace
+     * @param shouldFlush a flag indicating if the mapping applies to the
+     * current element or an up coming child (not used).
+     */
+
+    public boolean startPrefixMapping(
+        String prefix,
+        String uri,
+        boolean shouldFlush)
+        throws org.xml.sax.SAXException
+    {
+
+        /* Remember the mapping, and at what depth it was declared
+         * This is one greater than the current depth because these
+         * mappings will apply to the next depth. This is in
+         * consideration that startElement() will soon be called
+         */
+
+        boolean pushed;
+        int pushDepth;
+        if (shouldFlush)
+        {
+            flushPending();
+            // the prefix mapping applies to the child element (one deeper)
+            pushDepth = m_elemContext.m_currentElemDepth + 1;
+        }
+        else
+        {
+            // the prefix mapping applies to the current element
+            pushDepth = m_elemContext.m_currentElemDepth;
+        }
+        pushed = m_prefixMap.pushNamespace(prefix, uri, pushDepth);
+
+        if (pushed)
+        {
+            m_saxHandler.startPrefixMapping(prefix,uri);
+            
+            if (getShouldOutputNSAttr()) 
+            {
+
+	              /* I don't know if we really needto do this. The
+	               * callers of this object should have injected both
+	               * startPrefixMapping and the attributes.  We are
+	               * just covering our butt here.
+	               */
+	              String name;
+  	            if (EMPTYSTRING.equals(prefix))
+  	            {
+  	                name = "xmlns";
+  	                addAttributeAlways(XMLNS_URI, name, name,"CDATA",uri, false);
+  	            }
+  	            else 
+                {
+  	                if (!EMPTYSTRING.equals(uri)) // hack for attribset16 test
+  	                {                             // that maps ns1 prefix to "" URI 
+  	                    name = "xmlns:" + prefix;
+  	
+  	                    /* for something like xmlns:abc="w3.pretend.org"
+  	             	 	     *  the uri is the value, that is why we pass it in the
+  	             	 	     * value, or 5th slot of addAttributeAlways()
+  	                 	   */
+  	                    addAttributeAlways(XMLNS_URI, prefix, name,"CDATA",uri, false );
+  	                }
+  	            }
+            }
+        }
+        return pushed;
+    }
+        
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+     */
+    public void comment(char[] arg0, int arg1, int arg2) throws SAXException
+    {
+        flushPending();
+        if (m_lexHandler != null)
+            m_lexHandler.comment(arg0, arg1, arg2);
+            
+        if (m_tracer != null)            
+            super.fireCommentEvent(arg0, arg1, arg2);
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+     */
+    public void endCDATA() throws SAXException
+    {
+        /* Normally we would do somthing with this but we ignore it.
+         * The neccessary call to m_lexHandler.endCDATA() will be made
+         * in flushPending().
+         * 
+         * This is so that if we get calls like these:
+         *   this.startCDATA();
+         *   this.characters(chars1, off1, len1);
+         *   this.endCDATA();
+         *   this.startCDATA();
+         *   this.characters(chars2, off2, len2);
+         *   this.endCDATA();
+         * 
+         * that we will only make these calls to the wrapped handlers:
+         * 
+         *   m_lexHandler.startCDATA();
+         *   m_saxHandler.characters(chars1, off1, len1);
+         *   m_saxHandler.characters(chars1, off2, len2);
+         *   m_lexHandler.endCDATA();
+         * 
+         * We will merge adjacent CDATA blocks.
+         */ 
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#endDTD()
+     */
+    public void endDTD() throws SAXException
+    {
+        if (m_lexHandler != null)
+            m_lexHandler.endDTD();
+    }
+
+    /**
+     * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
+     */
+    public void startEntity(String arg0) throws SAXException
+    {
+        if (m_lexHandler != null)
+            m_lexHandler.startEntity(arg0);
+    }
+
+    /**
+     * @see ExtendedContentHandler#characters(String)
+     */
+    public void characters(String chars) throws SAXException
+    {
+        final int length = chars.length();
+        if (length > m_charsBuff.length)
+        {
+            m_charsBuff = new char[length*2 + 1];
+        }
+        chars.getChars(0, length, m_charsBuff, 0);
+        this.characters(m_charsBuff, 0, length); 
+    }
+
+    public ToXMLSAXHandler(ContentHandler handler, String encoding)
+    {
+        super(handler, encoding);
+
+        initCDATA();
+        // initNamespaces();
+        m_prefixMap = new NamespaceMappings();
+    }
+
+    public ToXMLSAXHandler(
+        ContentHandler handler,
+        LexicalHandler lex,
+        String encoding)
+    {
+        super(handler, lex, encoding);
+
+        initCDATA();
+        //      initNamespaces();
+        m_prefixMap = new NamespaceMappings();
+    }
+
+    /**
+     * Start an element in the output document. This might be an XML element
+     * (<elem>data</elem> type) or a CDATA section.
+     */
+    public void startElement(
+    String elementNamespaceURI,
+    String elementLocalName,
+    String elementName) throws SAXException
+    {
+        startElement(
+            elementNamespaceURI,elementLocalName,elementName, null);
+
+
+    }
+    public void startElement(String elementName) throws SAXException
+    {
+        startElement(null, null, elementName, null);
+    }
+
+
+    public void characters(char[] ch, int off, int len) throws SAXException
+    {
+        // We do the first two things in flushPending() but we don't
+        // close any open CDATA calls.        
+        if (m_needToCallStartDocument)
+        {
+            startDocumentInternal();
+            m_needToCallStartDocument = false;
+        }
+
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+
+        if (m_elemContext.m_isCdataSection && !m_cdataTagOpen
+        && m_lexHandler != null) 
+        {
+            m_lexHandler.startCDATA();
+            // We have made a call to m_lexHandler.startCDATA() with
+            // no balancing call to m_lexHandler.endCDATA()
+            // so we set m_cdataTagOpen true to remember this.
+            m_cdataTagOpen = true;
+        }
+        
+        /* If there are any occurances of "]]>" in the character data
+         * let m_saxHandler worry about it, we've already warned them with
+         * the previous call of m_lexHandler.startCDATA();
+         */ 
+        m_saxHandler.characters(ch, off, len);
+
+        // time to generate characters event
+        if (m_tracer != null)
+            fireCharEvent(ch, off, len);
+    }
+    
+
+    /**
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public void endElement(String elemName) throws SAXException
+    {
+        endElement(null, null, elemName);
+    }    
+
+
+    /**
+     * Send a namespace declaration in the output document. The namespace
+     * declaration will not be include if the namespace is already in scope
+     * with the same prefix.
+     */
+    public void namespaceAfterStartElement(
+        final String prefix,
+        final String uri)
+        throws SAXException
+    {
+        startPrefixMapping(prefix,uri,false);
+    }
+
+    /**
+     *
+     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
+     * Send a processing instruction to the output document
+     */
+    public void processingInstruction(String target, String data)
+        throws SAXException
+    {
+        flushPending();
+
+        // Pass the processing instruction to the SAX handler
+        m_saxHandler.processingInstruction(target, data);
+
+        // we don't want to leave serializer to fire off this event,
+        // so do it here.
+        if (m_tracer != null)
+            super.fireEscapingEvent(target, data);
+    }
+
+    /**
+     * Undeclare the namespace that is currently pointed to by a given
+     * prefix. Inform SAX handler if prefix was previously mapped.
+     */
+    protected boolean popNamespace(String prefix)
+    {
+        try
+        {
+            if (m_prefixMap.popNamespace(prefix))
+            {
+                m_saxHandler.endPrefixMapping(prefix);
+                return true;
+            }
+        }
+        catch (SAXException e)
+        {
+            // falls through
+        }
+        return false;
+    }
+
+    public void startCDATA() throws SAXException
+    {
+        /* m_cdataTagOpen can only be true here if we have ignored the
+         * previous call to this.endCDATA() and the previous call 
+         * this.startCDATA() before that is still "open". In this way
+         * we merge adjacent CDATA. If anything else happened after the 
+         * ignored call to this.endCDATA() and this call then a call to 
+         * flushPending() would have been made which would have
+         * closed the CDATA and set m_cdataTagOpen to false.
+         */
+        if (!m_cdataTagOpen ) 
+        {
+            flushPending();
+            if (m_lexHandler != null) {
+                m_lexHandler.startCDATA();
+
+                // We have made a call to m_lexHandler.startCDATA() with
+                // no balancing call to m_lexHandler.endCDATA()
+                // so we set m_cdataTagOpen true to remember this.                
+                m_cdataTagOpen = true;     
+            }              
+        }        
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
+     */
+    public void startElement(
+    String namespaceURI,
+    String localName,
+    String name,
+    Attributes atts)
+        throws SAXException
+    {
+        flushPending();
+        super.startElement(namespaceURI, localName, name, atts);
+
+        // Handle document type declaration (for first element only)
+         if (m_needToOutputDocTypeDecl)
+         {
+             String doctypeSystem = getDoctypeSystem();
+             if (doctypeSystem != null && m_lexHandler != null)
+             {
+                 String doctypePublic = getDoctypePublic();
+                 if (doctypeSystem != null)
+                     m_lexHandler.startDTD(
+                         name,
+                         doctypePublic,
+                         doctypeSystem);
+             }
+             m_needToOutputDocTypeDecl = false;
+         }
+        m_elemContext = m_elemContext.push(namespaceURI, localName, name);
+
+        // ensurePrefixIsDeclared depends on the current depth, so
+        // the previous increment is necessary where it is.
+        if (namespaceURI != null)
+            ensurePrefixIsDeclared(namespaceURI, name);
+
+        // add the attributes to the collected ones
+        if (atts != null)
+            addAttributes(atts);
+
+         
+        // do we really need this CDATA section state?
+        m_elemContext.m_isCdataSection = isCdataSection();
+   
+    }
+ 
+    private void ensurePrefixIsDeclared(String ns, String rawName)
+        throws org.xml.sax.SAXException
+    {
+
+        if (ns != null && ns.length() > 0)
+        {
+            int index;
+            final boolean no_prefix = ((index = rawName.indexOf(":")) < 0);
+            String prefix = (no_prefix) ? "" : rawName.substring(0, index);
+
+
+            if (null != prefix)
+            {
+                String foundURI = m_prefixMap.lookupNamespace(prefix);
+
+                if ((null == foundURI) || !foundURI.equals(ns))
+                {
+                    this.startPrefixMapping(prefix, ns, false);
+
+                    if (getShouldOutputNSAttr()) {
+                        // Bugzilla1133: Generate attribute as well as namespace event.
+                        // SAX does expect both.
+                        this.addAttributeAlways(
+                            "http://www.w3.org/2000/xmlns/",
+                            no_prefix ? "xmlns" : prefix,  // local name
+                            no_prefix ? "xmlns" : ("xmlns:"+ prefix), // qname
+                            "CDATA",
+                            ns,
+                            false);
+                    }
+                }
+
+            }
+        }
+    }
+    /**
+     * Adds the given attribute to the set of attributes, and also makes sure
+     * that the needed prefix/uri mapping is declared, but only if there is a
+     * currently open element.
+     * 
+     * @param uri the URI of the attribute
+     * @param localName the local name of the attribute
+     * @param rawName    the qualified name of the attribute
+     * @param type the type of the attribute (probably CDATA)
+     * @param value the value of the attribute
+     * @param XSLAttribute true if this attribute is coming from an xsl:attribute element
+     * @see ExtendedContentHandler#addAttribute(String, String, String, String, String)
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean XSLAttribute)
+        throws SAXException
+    {      
+        if (m_elemContext.m_startTagOpen)
+        {
+            ensurePrefixIsDeclared(uri, rawName);
+            addAttributeAlways(uri, localName, rawName, type, value, false);
+        }
+
+    } 
+       
+    /**
+     * Try's to reset the super class and reset this class for 
+     * re-use, so that you don't need to create a new serializer 
+     * (mostly for performance reasons).
+     * 
+     * @return true if the class was successfuly reset.
+     * @see Serializer#reset()
+     */
+    public boolean reset()
+    {
+        boolean wasReset = false;
+        if (super.reset())
+        {
+            resetToXMLSAXHandler();
+            wasReset = true;
+        }
+        return wasReset;
+    }
+    
+    /**
+     * Reset all of the fields owned by ToXMLSAXHandler class
+     *
+     */
+    private void resetToXMLSAXHandler()
+    {
+        this.m_escapeSetting = true;
+    }  
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/ToXMLStream.java b/src/main/java/org/apache/xml/serializer/ToXMLStream.java
new file mode 100644
index 0000000..d962189
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToXMLStream.java
@@ -0,0 +1,646 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ToXMLStream.java 469359 2006-10-31 03:43:19Z minchau $
+ */
+ package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.xml.sax.SAXException;
+
+/**
+ * This class converts SAX or SAX-like calls to a 
+ * serialized xml document.  The xsl:output method is "xml".
+ * 
+ * This class is used explicitly in code generated by XSLTC, 
+ * so it is "public", but it should 
+ * be viewed as internal or package private, this is not an API.
+ * 
+ * @xsl.usage internal
+ */
+public class ToXMLStream extends ToStream
+{
+    /**
+     * Map that tells which XML characters should have special treatment, and it
+     *  provides character to entity name lookup.
+     */
+    private CharInfo m_xmlcharInfo =
+        CharInfo.getCharInfo(CharInfo.XML_ENTITIES_RESOURCE, Method.XML);
+
+    /**
+     * Default constructor.
+     */
+    public ToXMLStream()
+    {
+        m_charInfo = m_xmlcharInfo;
+
+        initCDATA();
+        // initialize namespaces
+        m_prefixMap = new NamespaceMappings();
+
+    }
+
+    /**
+     * Copy properties from another SerializerToXML.
+     *
+     * @param xmlListener non-null reference to a SerializerToXML object.
+     */
+    public void CopyFrom(ToXMLStream xmlListener)
+    {
+
+        setWriter(xmlListener.m_writer);
+
+
+        // m_outputStream = xmlListener.m_outputStream;
+        String encoding = xmlListener.getEncoding();
+        setEncoding(encoding);
+
+        setOmitXMLDeclaration(xmlListener.getOmitXMLDeclaration());
+
+        m_ispreserve = xmlListener.m_ispreserve;
+        m_preserves = xmlListener.m_preserves;
+        m_isprevtext = xmlListener.m_isprevtext;
+        m_doIndent = xmlListener.m_doIndent;
+        setIndentAmount(xmlListener.getIndentAmount());
+        m_startNewLine = xmlListener.m_startNewLine;
+        m_needToOutputDocTypeDecl = xmlListener.m_needToOutputDocTypeDecl;
+        setDoctypeSystem(xmlListener.getDoctypeSystem());
+        setDoctypePublic(xmlListener.getDoctypePublic());        
+        setStandalone(xmlListener.getStandalone());
+        setMediaType(xmlListener.getMediaType());
+        m_encodingInfo = xmlListener.m_encodingInfo;
+        m_spaceBeforeClose = xmlListener.m_spaceBeforeClose;
+        m_cdataStartCalled = xmlListener.m_cdataStartCalled;
+
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void startDocumentInternal() throws org.xml.sax.SAXException
+    {
+
+        if (m_needToCallStartDocument)
+        { 
+            super.startDocumentInternal();
+            m_needToCallStartDocument = false;
+
+            if (m_inEntityRef)
+                return;
+
+            m_needToOutputDocTypeDecl = true;
+            m_startNewLine = false;
+            /* The call to getXMLVersion() might emit an error message
+             * and we should emit this message regardless of if we are 
+             * writing out an XML header or not.
+             */ 
+            final String version = getXMLVersion();
+            if (getOmitXMLDeclaration() == false)
+            {
+                String encoding = Encodings.getMimeEncoding(getEncoding());
+                String standalone;
+
+                if (m_standaloneWasSpecified)
+                {
+                    standalone = " standalone=\"" + getStandalone() + "\"";
+                }
+                else
+                {
+                    standalone = "";
+                }
+
+                try
+                {
+                    final java.io.Writer writer = m_writer;
+                    writer.write("<?xml version=\"");
+                    writer.write(version);
+                    writer.write("\" encoding=\"");
+                    writer.write(encoding);
+                    writer.write('\"');
+                    writer.write(standalone);
+                    writer.write("?>");
+                    if (m_doIndent) {
+                        if (m_standaloneWasSpecified
+                                || getDoctypePublic() != null
+                                || getDoctypeSystem() != null) {
+                            // We almost never put a newline after the XML
+                            // header because this XML could be used as
+                            // an extenal general parsed entity
+                            // and we don't know the context into which it
+                            // will be used in the future.  Only when
+                            // standalone, or a doctype system or public is
+                            // specified are we free to insert a new line
+                            // after the header.  Is it even worth bothering
+                            // in these rare cases?                           
+                            writer.write(m_lineSep, 0, m_lineSepLen);
+                        }
+                    }
+                } 
+                catch(IOException e)
+                {
+                    throw new SAXException(e);
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     *
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void endDocument() throws org.xml.sax.SAXException
+    {
+        flushPending();
+        if (m_doIndent && !m_isprevtext)
+        {
+            try
+            {
+            outputLineSep();
+            }
+            catch(IOException e)
+            {
+                throw new SAXException(e);
+            }
+        }
+
+        flushWriter();
+        
+        if (m_tracer != null)
+            super.fireEndDoc();
+    }
+
+    /**
+     * Starts a whitespace preserving section. All characters printed
+     * within a preserving section are printed without indentation and
+     * without consolidating multiple spaces. This is equivalent to
+     * the <tt>xml:space=&quot;preserve&quot;</tt> attribute. Only XML
+     * and HTML serializers need to support this method.
+     * <p>
+     * The contents of the whitespace preserving section will be delivered
+     * through the regular <tt>characters</tt> event.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void startPreserving() throws org.xml.sax.SAXException
+    {
+
+        // Not sure this is really what we want.  -sb
+        m_preserves.push(true);
+
+        m_ispreserve = true;
+    }
+
+    /**
+     * Ends a whitespace preserving section.
+     *
+     * @see #startPreserving
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void endPreserving() throws org.xml.sax.SAXException
+    {
+
+        // Not sure this is really what we want.  -sb
+        m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if
+     *        none was supplied.
+     * @throws org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void processingInstruction(String target, String data)
+        throws org.xml.sax.SAXException
+    {
+        if (m_inEntityRef)
+            return;
+        
+        flushPending();   
+
+        if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
+        {
+            startNonEscaping();
+        }
+        else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING))
+        {
+            endNonEscaping();
+        }
+        else
+        {
+            try
+            {
+                if (m_elemContext.m_startTagOpen)
+                {
+                    closeStartTag();
+                    m_elemContext.m_startTagOpen = false;
+                }
+                else if (m_needToCallStartDocument)
+                    startDocumentInternal();                
+
+                if (shouldIndent())
+                    indent();
+
+                final java.io.Writer writer = m_writer;
+                writer.write("<?");
+                writer.write(target);
+
+                if (data.length() > 0
+                    && !Character.isSpaceChar(data.charAt(0)))
+                    writer.write(' ');
+
+                int indexOfQLT = data.indexOf("?>");
+
+                if (indexOfQLT >= 0)
+                {
+
+                    // See XSLT spec on error recovery of "?>" in PIs.
+                    if (indexOfQLT > 0)
+                    {
+                        writer.write(data.substring(0, indexOfQLT));
+                    }
+
+                    writer.write("? >"); // add space between.
+
+                    if ((indexOfQLT + 2) < data.length())
+                    {
+                        writer.write(data.substring(indexOfQLT + 2));
+                    }
+                }
+                else
+                {
+                    writer.write(data);
+                }
+
+                writer.write('?');
+                writer.write('>');
+                
+                /*
+                 * Don't write out any indentation whitespace now,
+                 * because there may be non-whitespace text after this.
+                 * 
+                 * Simply mark that at this point if we do decide
+                 * to indent that we should 
+                 * add a newline on the end of the current line before
+                 * the indentation at the start of the next line.
+                 */ 
+                m_startNewLine = true;
+            }
+            catch(IOException e)
+            {
+                throw new SAXException(e);
+            }
+        }
+        
+        if (m_tracer != null)
+            super.fireEscapingEvent(target, data);  
+    }
+
+    /**
+     * Receive notivication of a entityReference.
+     *
+     * @param name The name of the entity.
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    public void entityReference(String name) throws org.xml.sax.SAXException
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            closeStartTag();
+            m_elemContext.m_startTagOpen = false;
+        }
+
+        try
+        {
+            if (shouldIndent())
+                indent();
+
+            final java.io.Writer writer = m_writer;
+            writer.write('&');
+            writer.write(name);
+            writer.write(';');
+        }
+        catch(IOException e)
+        {
+            throw new SAXException(e);
+        }
+        
+        if (m_tracer != null)
+            super.fireEntityReference(name);            
+    }
+
+    /**
+     * This method is used to add an attribute to the currently open element. 
+     * The caller has guaranted that this attribute is unique, which means that it
+     * not been seen before and will not be seen again.
+     * 
+     * @param name the qualified name of the attribute
+     * @param value the value of the attribute which can contain only
+     * ASCII printable characters characters in the range 32 to 127 inclusive.
+     * @param flags the bit values of this integer give optimization information.
+     */
+    public void addUniqueAttribute(String name, String value, int flags)
+        throws SAXException
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+           
+            try
+            {
+                final String patchedName = patchName(name);
+                final java.io.Writer writer = m_writer;
+                if ((flags & NO_BAD_CHARS) > 0 && m_xmlcharInfo.onlyQuotAmpLtGt)
+                {
+                    // "flags" has indicated that the characters
+                    // '>'  '<'   '&'  and '"' are not in the value and
+                    // m_htmlcharInfo has recorded that there are no other
+                    // entities in the range 32 to 127 so we write out the
+                    // value directly
+                    
+                    writer.write(' ');
+                    writer.write(patchedName);
+                    writer.write("=\"");
+                    writer.write(value);
+                    writer.write('"');
+                }
+                else
+                {
+                    writer.write(' ');
+                    writer.write(patchedName);
+                    writer.write("=\"");
+                    writeAttrString(writer, value, this.getEncoding());
+                    writer.write('"');
+                }
+            } catch (IOException e) {
+                throw new SAXException(e);
+            }
+        }
+    }
+
+    /**
+     * Add an attribute to the current element.
+     * @param uri the URI associated with the element name
+     * @param localName local part of the attribute name
+     * @param rawName   prefix:localName
+     * @param type
+     * @param value the value of the attribute
+     * @param xslAttribute true if this attribute is from an xsl:attribute,
+     * false if declared within the elements opening tag.
+     * @throws SAXException
+     */
+    public void addAttribute(
+        String uri,
+        String localName,
+        String rawName,
+        String type,
+        String value,
+        boolean xslAttribute)
+        throws SAXException
+    {
+        if (m_elemContext.m_startTagOpen)
+        {
+            boolean was_added = addAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
+            
+
+            /*
+             * We don't run this block of code if:
+             * 1. The attribute value was only replaced (was_added is false).
+             * 2. The attribute is from an xsl:attribute element (that is handled
+             *    in the addAttributeAlways() call just above.
+             * 3. The name starts with "xmlns", i.e. it is a namespace declaration.
+             */
+            if (was_added && !xslAttribute && !rawName.startsWith("xmlns"))
+            {
+                String prefixUsed =
+                    ensureAttributesNamespaceIsDeclared(
+                        uri,
+                        localName,
+                        rawName);
+                if (prefixUsed != null
+                    && rawName != null
+                    && !rawName.startsWith(prefixUsed))
+                {
+                    // use a different raw name, with the prefix used in the
+                    // generated namespace declaration
+                    rawName = prefixUsed + ":" + localName;
+
+                }
+            }
+            addAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
+        }
+        else
+        {
+            /*
+             * The startTag is closed, yet we are adding an attribute?
+             *
+             * Section: 7.1.3 Creating Attributes Adding an attribute to an
+             * element after a PI (for example) has been added to it is an
+             * error. The attributes can be ignored. The spec doesn't explicitly
+             * say this is disallowed, as it does for child elements, but it
+             * makes sense to have the same treatment.
+             *
+             * We choose to ignore the attribute which is added too late.
+             */
+            // Generate a warning of the ignored attributes
+
+            // Create the warning message
+            String msg = Utils.messages.createMessage(
+                    MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,new Object[]{ localName });
+
+            try {
+                // Prepare to issue the warning message
+                Transformer tran = super.getTransformer();
+                ErrorListener errHandler = tran.getErrorListener();
+
+
+                // Issue the warning message
+                if (null != errHandler && m_sourceLocator != null)
+                  errHandler.warning(new TransformerException(msg, m_sourceLocator));
+                else
+                  System.out.println(msg);
+                }
+            catch (TransformerException e){
+                // A user defined error handler, errHandler, may throw
+                // a TransformerException if it chooses to, and if it does
+                // we will wrap it with a SAXException and re-throw.
+                // Of course if the handler throws another type of
+                // exception, like a RuntimeException, then that is OK too.
+                SAXException se = new SAXException(e);
+                throw se;                
+            }             
+        }
+    }
+
+    /**
+     * @see ExtendedContentHandler#endElement(String)
+     */
+    public void endElement(String elemName) throws SAXException
+    {
+        endElement(null, null, elemName);
+    }
+
+    /**
+     * This method is used to notify the serializer of a namespace mapping (or node)
+     * that applies to the current element whose startElement() call has already been seen.
+     * The official SAX startPrefixMapping(prefix,uri) is to define a mapping for a child
+     * element that is soon to be seen with a startElement() call. The official SAX call 
+     * does not apply to the current element, hence the reason for this method.
+     */
+    public void namespaceAfterStartElement(
+        final String prefix,
+        final String uri)
+        throws SAXException
+    {
+
+        // hack for XSLTC with finding URI for default namespace
+        if (m_elemContext.m_elementURI == null)
+        {
+            String prefix1 = getPrefixPart(m_elemContext.m_elementName);
+            if (prefix1 == null && EMPTYSTRING.equals(prefix))
+            {
+                // the elements URI is not known yet, and it
+                // doesn't have a prefix, and we are currently
+                // setting the uri for prefix "", so we have
+                // the uri for the element... lets remember it
+                m_elemContext.m_elementURI = uri;
+            }
+        }            
+        startPrefixMapping(prefix,uri,false);
+        return;
+
+    }
+
+    /**
+     * From XSLTC
+     * Declare a prefix to point to a namespace URI. Inform SAX handler
+     * if this is a new prefix mapping.
+     */
+    protected boolean pushNamespace(String prefix, String uri)
+    {
+        try
+        {
+            if (m_prefixMap.pushNamespace(
+                prefix, uri, m_elemContext.m_currentElemDepth))
+            {
+                startPrefixMapping(prefix, uri);
+                return true;
+            }
+        }
+        catch (SAXException e)
+        {
+            // falls through
+        }
+        return false;
+    }
+    /**
+     * Try's to reset the super class and reset this class for 
+     * re-use, so that you don't need to create a new serializer 
+     * (mostly for performance reasons).
+     * 
+     * @return true if the class was successfuly reset.
+     */
+    public boolean reset()
+    {
+        boolean wasReset = false;
+        if (super.reset())
+        {
+            // Make this call when resetToXMLStream does
+            // something.
+            // resetToXMLStream();
+            wasReset = true;
+        }
+        return wasReset;
+    }
+    
+    /**
+     * Reset all of the fields owned by ToStream class
+     *
+     */
+    private void resetToXMLStream()
+    {
+        // This is an empty method, but is kept for future use
+        // as a place holder for a location to reset fields
+        // defined within this class
+        return;
+    }  
+
+    /**
+     * This method checks for the XML version of output document.
+     * If XML version of output document is not specified, then output 
+     * document is of version XML 1.0.
+     * If XML version of output doucment is specified, but it is not either 
+     * XML 1.0 or XML 1.1, a warning message is generated, the XML Version of
+     * output document is set to XML 1.0 and processing continues.
+     * @return string (XML version)
+     */
+    private String getXMLVersion()
+    {
+        String xmlVersion = getVersion();
+        if(xmlVersion == null || xmlVersion.equals(XMLVERSION10))
+        {
+            xmlVersion = XMLVERSION10;
+        }
+        else if(xmlVersion.equals(XMLVERSION11))
+        {
+            xmlVersion = XMLVERSION11;
+        }
+        else
+        {
+            String msg = Utils.messages.createMessage(
+                               MsgKey.ER_XML_VERSION_NOT_SUPPORTED,new Object[]{ xmlVersion });
+            try 
+            {
+                // Prepare to issue the warning message
+                Transformer tran = super.getTransformer();
+                ErrorListener errHandler = tran.getErrorListener();
+                // Issue the warning message
+                if (null != errHandler && m_sourceLocator != null)
+                    errHandler.warning(new TransformerException(msg, m_sourceLocator));
+                else
+                    System.out.println(msg);
+            }
+            catch (Exception e){}
+            xmlVersion = XMLVERSION10;								
+        }
+        return xmlVersion;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/TransformStateSetter.java b/src/main/java/org/apache/xml/serializer/TransformStateSetter.java
new file mode 100644
index 0000000..1342f35
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/TransformStateSetter.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TransformStateSetter.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import javax.xml.transform.Transformer;
+
+import org.w3c.dom.Node;
+/**
+ * This interface is meant to be used by a base interface to
+ * TransformState, but which as only the setters which have non Xalan
+ * specific types in their signature, so that there are no dependancies
+ * of the serializer on Xalan.
+ * 
+ * This interface is not a public API, it is only public because it is
+ * used by Xalan.
+ * 
+ * @see org.apache.xalan.transformer.TransformState
+ * @xsl.usage internal
+ */
+public interface TransformStateSetter
+{
+
+
+  /**
+   * Set the current node.
+   *
+   * @param n The current node.
+   */
+  void setCurrentNode(Node n);
+
+  /**
+   * Reset the state on the given transformer object.
+   *
+   * @param transformer
+   */
+  void resetState(Transformer transformer);
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/TreeWalker.java b/src/main/java/org/apache/xml/serializer/TreeWalker.java
new file mode 100644
index 0000000..bf9c568
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/TreeWalker.java
@@ -0,0 +1,527 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TreeWalker.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.File;
+
+import org.apache.xml.serializer.utils.AttList;
+import org.apache.xml.serializer.utils.DOM2Helper;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+
+/**
+ * This class does a pre-order walk of the DOM tree, calling a ContentHandler
+ * interface as it goes.
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ *  
+ * @xsl.usage internal
+ */
+
+public final class TreeWalker
+{
+
+  /** Local reference to a ContentHandler          */
+  final private ContentHandler m_contentHandler;
+  /** 
+   * If m_contentHandler is a SerializationHandler, then this is 
+   * a reference to the same object. 
+   */
+  final private SerializationHandler m_Serializer;
+
+  // ARGHH!!  JAXP Uses Xerces without setting the namespace processing to ON!
+  // DOM2Helper m_dh = new DOM2Helper();
+
+  /** DomHelper for this TreeWalker          */
+  final protected DOM2Helper m_dh;
+        
+  /** Locator object for this TreeWalker          */
+  final private LocatorImpl m_locator = new LocatorImpl();
+
+  /**
+   * Get the ContentHandler used for the tree walk.
+   *
+   * @return the ContentHandler used for the tree walk
+   */
+  public ContentHandler getContentHandler()
+  {
+    return m_contentHandler;
+  }
+  
+  public TreeWalker(ContentHandler ch) {
+      this(ch,null);
+  }
+  /**
+   * Constructor.
+   * @param   contentHandler The implemention of the
+   * contentHandler operation (toXMLString, digest, ...)
+   */
+  public TreeWalker(ContentHandler contentHandler, String systemId)
+  {
+      // Set the content handler
+      m_contentHandler = contentHandler;
+      if (m_contentHandler instanceof SerializationHandler) {
+          m_Serializer = (SerializationHandler) m_contentHandler;
+      }
+      else
+          m_Serializer = null;
+          
+      // Set the system ID, if it is given
+      m_contentHandler.setDocumentLocator(m_locator);
+      if (systemId != null)
+          m_locator.setSystemId(systemId);
+      else {
+          try {
+            // Bug see Bugzilla  26741
+            m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
+           }
+           catch (SecurityException se) {// user.dir not accessible from applet             
+           }
+      }
+          
+      // Set the document locator  
+                if (m_contentHandler != null)
+                        m_contentHandler.setDocumentLocator(m_locator);
+                try {
+                   // Bug see Bugzilla  26741
+                  m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
+                } 
+                catch (SecurityException se){// user.dir not accessible from applet
+                  
+    }
+    m_dh = new DOM2Helper();
+  }
+
+  /**
+   * Perform a pre-order traversal non-recursive style.  
+   *
+   * Note that TreeWalker assumes that the subtree is intended to represent 
+   * a complete (though not necessarily well-formed) document and, during a 
+   * traversal, startDocument and endDocument will always be issued to the 
+   * SAX listener.
+   *  
+   * @param pos Node in the tree where to start traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverse(Node pos) throws org.xml.sax.SAXException
+  {
+
+    this.m_contentHandler.startDocument();
+
+    Node top = pos;
+
+    while (null != pos)
+    {
+      startNode(pos);
+
+      Node nextNode = pos.getFirstChild();
+
+      while (null == nextNode)
+      {
+        endNode(pos);
+
+        if (top.equals(pos))
+          break;
+
+        nextNode = pos.getNextSibling();
+
+        if (null == nextNode)
+        {
+          pos = pos.getParentNode();
+
+          if ((null == pos) || (top.equals(pos)))
+          {
+            if (null != pos)
+              endNode(pos);
+
+            nextNode = null;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+    this.m_contentHandler.endDocument();
+  }
+
+  /**
+   * Perform a pre-order traversal non-recursive style.
+
+   * Note that TreeWalker assumes that the subtree is intended to represent 
+   * a complete (though not necessarily well-formed) document and, during a 
+   * traversal, startDocument and endDocument will always be issued to the 
+   * SAX listener.
+   *
+   * @param pos Node in the tree where to start traversal
+   * @param top Node in the tree where to end traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverse(Node pos, Node top) throws org.xml.sax.SAXException
+  {
+
+    this.m_contentHandler.startDocument();
+    
+    while (null != pos)
+    {
+      startNode(pos);
+
+      Node nextNode = pos.getFirstChild();
+
+      while (null == nextNode)
+      {
+        endNode(pos);
+
+        if ((null != top) && top.equals(pos))
+          break;
+
+        nextNode = pos.getNextSibling();
+
+        if (null == nextNode)
+        {
+          pos = pos.getParentNode();
+
+          if ((null == pos) || ((null != top) && top.equals(pos)))
+          {
+            nextNode = null;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+    this.m_contentHandler.endDocument();
+  }
+
+  /** Flag indicating whether following text to be processed is raw text          */
+  boolean nextIsRaw = false;
+  
+  /**
+   * Optimized dispatch of characters.
+   */
+  private final void dispatachChars(Node node)
+     throws org.xml.sax.SAXException
+  {
+    if(m_Serializer != null)
+    {
+      this.m_Serializer.characters(node);
+    }
+    else
+    {
+      String data = ((Text) node).getData();
+      this.m_contentHandler.characters(data.toCharArray(), 0, data.length());
+    }
+  }
+
+  /**
+   * Start processing given node
+   *
+   *
+   * @param node Node to process
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void startNode(Node node) throws org.xml.sax.SAXException
+  {
+
+//   TODO: <REVIEW>
+//    A Serializer implements ContentHandler, but not NodeConsumer
+//    so drop this reference to NodeConsumer which would otherwise
+//    pull in all sorts of things
+//    if (m_contentHandler instanceof NodeConsumer)
+//    {
+//      ((NodeConsumer) m_contentHandler).setOriginatingNode(node);
+//    }
+//    TODO: </REVIEW>
+                
+                if (node instanceof Locator)
+                {
+                        Locator loc = (Locator)node;
+                        m_locator.setColumnNumber(loc.getColumnNumber());
+                        m_locator.setLineNumber(loc.getLineNumber());
+                        m_locator.setPublicId(loc.getPublicId());
+                        m_locator.setSystemId(loc.getSystemId());
+                }
+                else
+                {
+                        m_locator.setColumnNumber(0);
+      m_locator.setLineNumber(0);
+                }
+
+    switch (node.getNodeType())
+    {
+    case Node.COMMENT_NODE :
+    {
+      String data = ((Comment) node).getData();
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+
+        lh.comment(data.toCharArray(), 0, data.length());
+      }
+    }
+    break;
+    case Node.DOCUMENT_FRAGMENT_NODE :
+
+      // ??;
+      break;
+    case Node.DOCUMENT_NODE :
+    
+      break;
+    case Node.ELEMENT_NODE :
+      Element elem_node = (Element) node;
+      {
+          // Make sure the namespace node
+          // for the element itself is declared
+          // to the ContentHandler
+          String uri = elem_node.getNamespaceURI();
+          if (uri != null) {
+              String prefix = elem_node.getPrefix();
+              if (prefix==null)
+                prefix="";
+              this.m_contentHandler.startPrefixMapping(prefix,uri);              
+          }
+      }
+      NamedNodeMap atts = elem_node.getAttributes();
+      int nAttrs = atts.getLength();
+      // System.out.println("TreeWalker#startNode: "+node.getNodeName());
+
+      
+      // Make sure the namespace node of
+      // each attribute is declared to the ContentHandler
+      for (int i = 0; i < nAttrs; i++)
+      {
+        final Node attr = atts.item(i);
+        final String attrName = attr.getNodeName();
+        final int colon = attrName.indexOf(':');
+        final String prefix;
+
+        // System.out.println("TreeWalker#startNode: attr["+i+"] = "+attrName+", "+attr.getNodeValue());
+        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
+        {
+          // Use "" instead of null, as Xerces likes "" for the 
+          // name of the default namespace.  Fix attributed 
+          // to "Steven Murray" <smurray@ebt.com>.
+          if (colon < 0)
+            prefix = "";
+          else
+            prefix = attrName.substring(colon + 1);
+
+          this.m_contentHandler.startPrefixMapping(prefix,
+                                                   attr.getNodeValue());
+        }
+        else if (colon > 0) {
+            prefix = attrName.substring(0,colon);
+            String uri = attr.getNamespaceURI();
+            if (uri != null)
+                this.m_contentHandler.startPrefixMapping(prefix,uri);
+        }        
+      }
+
+      String ns = m_dh.getNamespaceOfNode(node);
+      if(null == ns)
+        ns = "";
+      this.m_contentHandler.startElement(ns,
+                                         m_dh.getLocalNameOfNode(node),
+                                         node.getNodeName(),
+                                         new AttList(atts, m_dh));
+      break;
+    case Node.PROCESSING_INSTRUCTION_NODE :
+    {
+      ProcessingInstruction pi = (ProcessingInstruction) node;
+      String name = pi.getNodeName();
+
+      // String data = pi.getData();
+      if (name.equals("xslt-next-is-raw"))
+      {
+        nextIsRaw = true;
+      }
+      else
+      {
+        this.m_contentHandler.processingInstruction(pi.getNodeName(),
+                                                    pi.getData());
+      }
+    }
+    break;
+    case Node.CDATA_SECTION_NODE :
+    {
+      boolean isLexH = (m_contentHandler instanceof LexicalHandler);
+      LexicalHandler lh = isLexH
+                          ? ((LexicalHandler) this.m_contentHandler) : null;
+
+      if (isLexH)
+      {
+        lh.startCDATA();
+      }
+      
+      dispatachChars(node);
+
+      {
+        if (isLexH)
+        {
+          lh.endCDATA();
+        }
+      }
+    }
+    break;
+    case Node.TEXT_NODE :
+    {
+      //String data = ((Text) node).getData();
+
+      if (nextIsRaw)
+      {
+        nextIsRaw = false;
+
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+        dispatachChars(node);
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+      }
+      else
+      {
+        dispatachChars(node);
+      }
+    }
+    break;
+    case Node.ENTITY_REFERENCE_NODE :
+    {
+      EntityReference eref = (EntityReference) node;
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        ((LexicalHandler) this.m_contentHandler).startEntity(
+          eref.getNodeName());
+      }
+      else
+      {
+
+        // warning("Can not output entity to a pure SAX ContentHandler");
+      }
+    }
+    break;
+    default :
+    }
+  }
+
+  /**
+   * End processing of given node 
+   *
+   *
+   * @param node Node we just finished processing
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void endNode(Node node) throws org.xml.sax.SAXException
+  {
+
+    switch (node.getNodeType())
+    {
+    case Node.DOCUMENT_NODE :
+      break;
+      
+    case Node.ELEMENT_NODE :
+      String ns = m_dh.getNamespaceOfNode(node);
+      if(null == ns)
+        ns = "";
+      this.m_contentHandler.endElement(ns,
+                                         m_dh.getLocalNameOfNode(node),
+                                         node.getNodeName());
+
+      if (m_Serializer == null) {
+      // Don't bother with endPrefixMapping calls if the ContentHandler is a
+      // SerializationHandler because SerializationHandler's ignore the
+      // endPrefixMapping() calls anyways. . . .  This is an optimization.    
+      Element elem_node = (Element) node;    
+      NamedNodeMap atts = elem_node.getAttributes();
+      int nAttrs = atts.getLength();
+
+      // do the endPrefixMapping calls in reverse order 
+      // of the startPrefixMapping calls
+      for (int i = (nAttrs-1); 0 <= i; i--)
+      {
+        final Node attr = atts.item(i);
+        final String attrName = attr.getNodeName();
+        final int colon = attrName.indexOf(':');
+        final String prefix;
+
+        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
+        {
+          // Use "" instead of null, as Xerces likes "" for the 
+          // name of the default namespace.  Fix attributed 
+          // to "Steven Murray" <smurray@ebt.com>.
+          if (colon < 0)
+            prefix = "";
+          else
+            prefix = attrName.substring(colon + 1);
+
+          this.m_contentHandler.endPrefixMapping(prefix);
+        }
+        else if (colon > 0) {
+            prefix = attrName.substring(0, colon);
+            this.m_contentHandler.endPrefixMapping(prefix);
+        }
+      }
+      {
+          String uri = elem_node.getNamespaceURI();
+          if (uri != null) {
+              String prefix = elem_node.getPrefix();
+              if (prefix==null)
+                prefix="";
+              this.m_contentHandler.endPrefixMapping(prefix);              
+          }
+      }
+      }
+      break;
+    case Node.CDATA_SECTION_NODE :
+      break;
+    case Node.ENTITY_REFERENCE_NODE :
+    {
+      EntityReference eref = (EntityReference) node;
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+
+        lh.endEntity(eref.getNodeName());
+      }
+    }
+    break;
+    default :
+    }
+  }
+}  //TreeWalker
+
diff --git a/src/main/java/org/apache/xml/serializer/Version.java b/src/main/java/org/apache/xml/serializer/Version.java
new file mode 100644
index 0000000..17e73d5
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Version.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Version.java 477252 2006-11-20 16:52:00Z minchau $
+ */
+package org.apache.xml.serializer;
+
+/**
+ * Administrative class to keep track of the version number of
+ * the Serializer release.
+ * <P>This class implements the upcoming standard of having
+ * org.apache.project-name.Version.getVersion() be a standard way 
+ * to get version information.</P> 
+ * @xsl.usage general
+ */
+public final class Version
+{
+
+  /**
+   * Get the basic version string for the current Serializer.
+   * Version String formatted like 
+   * <CODE>"<B>Serializer</B> <B>Java</B> v.r[.dd| <B>D</B>nn]"</CODE>.
+   *
+   * Futurework: have this read version info from jar manifest.
+   *
+   * @return String denoting our current version
+   */
+  public static String getVersion()
+  {
+     return getProduct()+" "+getImplementationLanguage()+" "
+           +getMajorVersionNum()+"."+getReleaseVersionNum()+"."
+           +( (getDevelopmentVersionNum() > 0) ? 
+               ("D"+getDevelopmentVersionNum()) : (""+getMaintenanceVersionNum()));  
+  }
+
+  /**
+   * Print the processor version to the command line.
+   *
+   * @param argv command line arguments, unused.
+   */
+  public static void main(String argv[])
+  {
+    System.out.println(getVersion());
+  }
+  
+  /**
+   * Name of product: Serializer.
+   */
+  public static String getProduct()
+  {
+    return "Serializer";
+  }
+
+  /**
+   * Implementation Language: Java.
+   */
+  public static String getImplementationLanguage()
+  {
+    return "Java";
+  }
+  
+  
+  /**
+   * Major version number.
+   * Version number. This changes only when there is a
+   *          significant, externally apparent enhancement from
+   *          the previous release. 'n' represents the n'th
+   *          version.
+   *
+   *          Clients should carefully consider the implications
+   *          of new versions as external interfaces and behaviour
+   *          may have changed.
+   */
+  public static int getMajorVersionNum()
+  {
+    return 2;
+    
+  }  
+
+  /**
+   * Release Number.
+   * Release number. This changes when:
+   *            -  a new set of functionality is to be added, eg,
+   *               implementation of a new W3C specification.
+   *            -  API or behaviour change.
+   *            -  its designated as a reference release.
+   */
+  public static int getReleaseVersionNum()
+  {
+    return 7;
+  }
+  
+  /**
+   * Maintenance Drop Number.
+   * Optional identifier used to designate maintenance
+   *          drop applied to a specific release and contains
+   *          fixes for defects reported. It maintains compatibility
+   *          with the release and contains no API changes.
+   *          When missing, it designates the final and complete
+   *          development drop for a release.
+   */
+  public static int getMaintenanceVersionNum()
+  {
+    return 1;
+  }
+
+  /**
+   * Development Drop Number.
+   * Optional identifier designates development drop of
+   *          a specific release. D01 is the first development drop
+   *          of a new release.
+   *
+   *          Development drops are works in progress towards a
+   *          compeleted, final release. A specific development drop
+   *          may not completely implement all aspects of a new
+   *          feature, which may take several development drops to
+   *          complete. At the point of the final drop for the
+   *          release, the D suffix will be omitted.
+   *
+   *          Each 'D' drops can contain functional enhancements as
+   *          well as defect fixes. 'D' drops may not be as stable as
+   *          the final releases.
+   */
+  public static int getDevelopmentVersionNum()
+  { 
+    try {   
+        if ((new String("")).length() == 0)
+          return 0;
+        else  
+          return Integer.parseInt("");
+    } catch (NumberFormatException nfe) {
+           return 0;
+    }    
+  }      
+}
diff --git a/src/main/java/org/apache/xml/serializer/Version.src b/src/main/java/org/apache/xml/serializer/Version.src
new file mode 100644
index 0000000..46402cb
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/Version.src
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Version.src 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+/**
+ * Administrative class to keep track of the version number of
+ * the Serializer release.
+ * <P>This class implements the upcoming standard of having
+ * org.apache.project-name.Version.getVersion() be a standard way 
+ * to get version information.</P> 
+ * @xsl.usage general
+ */
+public final class Version
+{
+
+  /**
+   * Get the basic version string for the current Serializer.
+   * Version String formatted like 
+   * <CODE>"<B>Serializer</B> <B>Java</B> v.r[.dd| <B>D</B>nn]"</CODE>.
+   *
+   * Futurework: have this read version info from jar manifest.
+   *
+   * @return String denoting our current version
+   */
+  public static String getVersion()
+  {
+     return getProduct()+" "+getImplementationLanguage()+" "
+           +getMajorVersionNum()+"."+getReleaseVersionNum()+"."
+           +( (getDevelopmentVersionNum() > 0) ? 
+               ("D"+getDevelopmentVersionNum()) : (""+getMaintenanceVersionNum()));  
+  }
+
+  /**
+   * Print the processor version to the command line.
+   *
+   * @param argv command line arguments, unused.
+   */
+  public static void main(String argv[])
+  {
+    System.out.println(getVersion());
+  }
+  
+  /**
+   * Name of product: Serializer.
+   */
+  public static String getProduct()
+  {
+    return "Serializer";
+  }
+
+  /**
+   * Implementation Language: Java.
+   */
+  public static String getImplementationLanguage()
+  {
+    return "Java";
+  }
+  
+  
+  /**
+   * Major version number.
+   * Version number. This changes only when there is a
+   *          significant, externally apparent enhancement from
+   *          the previous release. 'n' represents the n'th
+   *          version.
+   *
+   *          Clients should carefully consider the implications
+   *          of new versions as external interfaces and behaviour
+   *          may have changed.
+   */
+  public static int getMajorVersionNum()
+  {
+    return @version.VERSION@;
+    
+  }  
+
+  /**
+   * Release Number.
+   * Release number. This changes when:
+   *            -  a new set of functionality is to be added, eg,
+   *               implementation of a new W3C specification.
+   *            -  API or behaviour change.
+   *            -  its designated as a reference release.
+   */
+  public static int getReleaseVersionNum()
+  {
+    return @version.RELEASE@;
+  }
+  
+  /**
+   * Maintenance Drop Number.
+   * Optional identifier used to designate maintenance
+   *          drop applied to a specific release and contains
+   *          fixes for defects reported. It maintains compatibility
+   *          with the release and contains no API changes.
+   *          When missing, it designates the final and complete
+   *          development drop for a release.
+   */
+  public static int getMaintenanceVersionNum()
+  {
+    return @version.MINOR@;
+  }
+
+  /**
+   * Development Drop Number.
+   * Optional identifier designates development drop of
+   *          a specific release. D01 is the first development drop
+   *          of a new release.
+   *
+   *          Development drops are works in progress towards a
+   *          compeleted, final release. A specific development drop
+   *          may not completely implement all aspects of a new
+   *          feature, which may take several development drops to
+   *          complete. At the point of the final drop for the
+   *          release, the D suffix will be omitted.
+   *
+   *          Each 'D' drops can contain functional enhancements as
+   *          well as defect fixes. 'D' drops may not be as stable as
+   *          the final releases.
+   */
+  public static int getDevelopmentVersionNum()
+  { 
+    try {   
+        if ((new String("@version.DEVELOPER@")).length() == 0)
+          return 0;
+        else  
+          return Integer.parseInt("@version.DEVELOPER@");
+    } catch (NumberFormatException nfe) {
+           return 0;
+    }    
+  }      
+}
diff --git a/src/main/java/org/apache/xml/serializer/WriterChain.java b/src/main/java/org/apache/xml/serializer/WriterChain.java
new file mode 100644
index 0000000..24246e6
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/WriterChain.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WriterChain.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+
+/**
+ * It is unfortunate that java.io.Writer is a class rather than an interface.
+ * The serializer has a number of classes that extend java.io.Writer
+ * and which send their ouput to a yet another wrapped Writer or OutputStream.
+ * 
+ * The purpose of this interface is to force such classes to over-ride all of
+ * the important methods defined on the java.io.Writer class, namely these:
+ * <code>
+ * write(int val)
+ * write(char[] chars)
+ * write(char[] chars, int start, int count)
+ * write(String chars)
+ * write(String chars, int start, int count)
+ * flush()
+ * close()
+ * </code>
+ * In this manner nothing will accidentally go directly to 
+ * the base class rather than to the wrapped Writer or OutputStream. 
+ * 
+ * The purpose of this class is to have a uniform way of chaining the output of one writer to
+ * the next writer in the chain. In addition there are methods to obtain the Writer or 
+ * OutputStream that this object sends its output to.
+ * 
+ * This interface is only for internal use withing the serializer. 
+ * @xsl.usage internal
+ */
+interface WriterChain
+{
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void write(int val) throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void write(char[] chars) throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void write(char[] chars, int start, int count) throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void write(String chars) throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void write(String chars, int start, int count) throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void flush() throws IOException;
+    /** This method forces us to over-ride the method defined in java.io.Writer */
+    public void close() throws IOException;
+
+    /**
+     * If this method returns null, getOutputStream() must return non-null.
+     * Get the writer that this writer sends its output to.
+     * 
+     * It is possible that the Writer returned by this method does not
+     * implement the WriterChain interface.
+     */
+    public java.io.Writer getWriter();
+    
+    /**
+     * If this method returns null, getWriter() must return non-null.
+     * Get the OutputStream that this writer sends its output to.
+     */
+    public java.io.OutputStream getOutputStream();
+}
diff --git a/src/main/java/org/apache/xml/serializer/WriterToASCI.java b/src/main/java/org/apache/xml/serializer/WriterToASCI.java
new file mode 100644
index 0000000..acc4f5a
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/WriterToASCI.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WriterToASCI.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+
+
+/**
+ * This class writes ASCII to a byte stream as quickly as possible.  For the
+ * moment it does not do buffering, though I reserve the right to do some
+ * buffering down the line if I can prove that it will be faster even if the
+ * output stream is buffered.
+ * 
+ * This class is only used internally within Xalan.
+ * 
+ * @xsl.usage internal
+ */
+class WriterToASCI extends Writer implements WriterChain
+{
+
+  /** The byte stream to write to.  */
+  private final OutputStream m_os;
+
+  /**
+   * Create an unbuffered ASCII writer.
+   *
+   *
+   * @param os The byte stream to write to.
+   */
+  public WriterToASCI(OutputStream os)
+  {
+    m_os = os;
+  }
+
+  /**
+   * Write a portion of an array of characters.
+   *
+   * @param  chars  Array of characters
+   * @param  start   Offset from which to start writing characters
+   * @param  length   Number of characters to write
+   *
+   * @exception  IOException  If an I/O error occurs
+   *
+   * @throws java.io.IOException
+   */
+  public void write(char chars[], int start, int length)
+          throws java.io.IOException
+  {
+
+    int n = length+start;
+
+    for (int i = start; i < n; i++)
+    {
+      m_os.write(chars[i]);
+    }
+  }
+
+  /**
+   * Write a single character.  The character to be written is contained in
+   * the 16 low-order bits of the given integer value; the 16 high-order bits
+   * are ignored.
+   *
+   * <p> Subclasses that intend to support efficient single-character output
+   * should override this method.
+   *
+   * @param c  int specifying a character to be written.
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void write(int c) throws IOException
+  {
+    m_os.write(c);
+  }
+
+  /**
+   * Write a string.
+   *
+   * @param  s String to be written
+   *
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void write(String s) throws IOException
+  {
+    int n = s.length();
+    for (int i = 0; i < n; i++)
+    {
+      m_os.write(s.charAt(i));
+    }
+  }
+
+  /**
+   * Flush the stream.  If the stream has saved any characters from the
+   * various write() methods in a buffer, write them immediately to their
+   * intended destination.  Then, if that destination is another character or
+   * byte stream, flush it.  Thus one flush() invocation will flush all the
+   * buffers in a chain of Writers and OutputStreams.
+   *
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void flush() throws java.io.IOException
+  {
+    m_os.flush();
+  }
+
+  /**
+   * Close the stream, flushing it first.  Once a stream has been closed,
+   * further write() or flush() invocations will cause an IOException to be
+   * thrown.  Closing a previously-closed stream, however, has no effect.
+   *
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void close() throws java.io.IOException
+  {
+    m_os.close();
+  }
+
+  /**
+   * Get the output stream where the events will be serialized to.
+   *
+   * @return reference to the result stream, or null of only a writer was
+   * set.
+   */
+  public OutputStream getOutputStream()
+  {
+    return m_os;
+  }
+
+  /**
+   * Get the writer that this writer directly chains to.
+   */
+  public Writer getWriter()
+  {
+      return null;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/WriterToUTF8Buffered.java b/src/main/java/org/apache/xml/serializer/WriterToUTF8Buffered.java
new file mode 100644
index 0000000..abff1b9
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/WriterToUTF8Buffered.java
@@ -0,0 +1,502 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WriterToUTF8Buffered.java 469356 2006-10-31 03:20:34Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+
+/**
+ * This class writes unicode characters to a byte stream (java.io.OutputStream)
+ * as quickly as possible. It buffers the output in an internal
+ * buffer which must be flushed to the OutputStream when done. This flushing
+ * is done via the close() flush() or flushBuffer() method. 
+ * 
+ * This class is only used internally within Xalan.
+ * 
+ * @xsl.usage internal
+ */
+final class WriterToUTF8Buffered extends Writer implements WriterChain
+{
+    
+  /** number of bytes that the byte buffer can hold.
+   * This is a fixed constant is used rather than m_outputBytes.lenght for performance.
+   */
+  private static final int BYTES_MAX=16*1024;
+  /** number of characters that the character buffer can hold.
+   * This is 1/3 of the number of bytes because UTF-8 encoding
+   * can expand one unicode character by up to 3 bytes.
+   */
+  private static final int CHARS_MAX=(BYTES_MAX/3);
+  
+ // private static final int 
+  
+  /** The byte stream to write to. (sc & sb remove final to compile in JDK 1.1.8) */
+  private final OutputStream m_os;
+
+  /**
+   * The internal buffer where data is stored.
+   * (sc & sb remove final to compile in JDK 1.1.8)
+   */
+  private final byte m_outputBytes[];
+  
+  private final char m_inputChars[];
+
+  /**
+   * The number of valid bytes in the buffer. This value is always
+   * in the range <tt>0</tt> through <tt>m_outputBytes.length</tt>; elements
+   * <tt>m_outputBytes[0]</tt> through <tt>m_outputBytes[count-1]</tt> contain valid
+   * byte data.
+   */
+  private int count;
+
+  /**
+   * Create an buffered UTF-8 writer.
+   *
+   *
+   * @param   out    the underlying output stream.
+   *
+   * @throws UnsupportedEncodingException
+   */
+  public WriterToUTF8Buffered(OutputStream out)
+  {
+      m_os = out;
+      // get 3 extra bytes to make buffer overflow checking simpler and faster
+      // we won't have to keep checking for a few extra characters
+      m_outputBytes = new byte[BYTES_MAX + 3];
+      
+      // Big enough to hold the input chars that will be transformed
+      // into output bytes in m_ouputBytes.
+      m_inputChars = new char[CHARS_MAX + 2];
+      count = 0;
+      
+//      the old body of this constructor, before the buffersize was changed to a constant      
+//      this(out, 8*1024);
+  }
+
+  /**
+   * Create an buffered UTF-8 writer to write data to the
+   * specified underlying output stream with the specified buffer
+   * size.
+   *
+   * @param   out    the underlying output stream.
+   * @param   size   the buffer size.
+   * @exception IllegalArgumentException if size <= 0.
+   */
+//  public WriterToUTF8Buffered(final OutputStream out, final int size)
+//  {
+//
+//    m_os = out;
+//
+//    if (size <= 0)
+//    {
+//      throw new IllegalArgumentException(
+//        SerializerMessages.createMessage(SerializerErrorResources.ER_BUFFER_SIZE_LESSTHAN_ZERO, null)); //"Buffer size <= 0");
+//    }
+//
+//    m_outputBytes = new byte[size];
+//    count = 0;
+//  }
+
+  /**
+   * Write a single character.  The character to be written is contained in
+   * the 16 low-order bits of the given integer value; the 16 high-order bits
+   * are ignored.
+   *
+   * <p> Subclasses that intend to support efficient single-character output
+   * should override this method.
+   *
+   * @param c  int specifying a character to be written.
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void write(final int c) throws IOException
+  {
+    
+    /* If we are close to the end of the buffer then flush it.
+     * Remember the buffer can hold a few more bytes than BYTES_MAX
+     */ 
+    if (count >= BYTES_MAX)
+        flushBuffer();
+
+    if (c < 0x80)
+    {
+       m_outputBytes[count++] = (byte) (c);
+    }
+    else if (c < 0x800)
+    {
+      m_outputBytes[count++] = (byte) (0xc0 + (c >> 6));
+      m_outputBytes[count++] = (byte) (0x80 + (c & 0x3f));
+    }
+    else if (c < 0x10000)
+    {
+      m_outputBytes[count++] = (byte) (0xe0 + (c >> 12));
+      m_outputBytes[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+      m_outputBytes[count++] = (byte) (0x80 + (c & 0x3f));
+    }
+	else
+	{
+	  m_outputBytes[count++] = (byte) (0xf0 + (c >> 18));
+	  m_outputBytes[count++] = (byte) (0x80 + ((c >> 12) & 0x3f));
+	  m_outputBytes[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+	  m_outputBytes[count++] = (byte) (0x80 + (c & 0x3f));
+	}
+
+  }
+
+
+  /**
+   * Write a portion of an array of characters.
+   *
+   * @param  chars  Array of characters
+   * @param  start   Offset from which to start writing characters
+   * @param  length   Number of characters to write
+   *
+   * @exception  IOException  If an I/O error occurs
+   *
+   * @throws java.io.IOException
+   */
+  public void write(final char chars[], final int start, final int length)
+          throws java.io.IOException
+  {
+
+    // We multiply the length by three since this is the maximum length
+    // of the characters that we can put into the buffer.  It is possible
+    // for each Unicode character to expand to three bytes.
+
+    int lengthx3 = 3*length;
+
+    if (lengthx3 >= BYTES_MAX - count)
+    {
+      // The requested length is greater than the unused part of the buffer
+      flushBuffer();
+
+      if (lengthx3 > BYTES_MAX)
+      {
+        /*
+         * The requested length exceeds the size of the buffer.
+         * Cut the buffer up into chunks, each of which will
+         * not cause an overflow to the output buffer m_outputBytes,
+         * and make multiple recursive calls.
+         * Be careful about integer overflows in multiplication.
+         */
+        int split = length/CHARS_MAX; 
+        final int chunks;
+        if (length % CHARS_MAX > 0) 
+            chunks = split + 1;
+        else
+            chunks = split;
+        int end_chunk = start;
+        for (int chunk = 1; chunk <= chunks; chunk++)
+        {
+            int start_chunk = end_chunk;
+            end_chunk = start + (int) ((((long) length) * chunk) / chunks);
+            
+            // Adjust the end of the chunk if it ends on a high char 
+            // of a Unicode surrogate pair and low char of the pair
+            // is not going to be in the same chunk
+            final char c = chars[end_chunk - 1]; 
+            int ic = chars[end_chunk - 1];
+            if (c >= 0xD800 && c <= 0xDBFF) {
+                // The last Java char that we were going
+                // to process is the first of a
+                // Java surrogate char pair that
+                // represent a Unicode character.
+
+                if (end_chunk < start + length) {
+                    // Avoid spanning by including the low
+                    // char in the current chunk of chars.
+                    end_chunk++;
+                } else {
+                    /* This is the last char of the last chunk,
+                     * and it is the high char of a high/low pair with
+                     * no low char provided.
+                     * TODO: error message needed.
+                     * The char array incorrectly ends in a high char
+                     * of a high/low surrogate pair, but there is
+                     * no corresponding low as the high is the last char 
+                     */
+                    end_chunk--;
+                }
+            }
+
+
+            int len_chunk = (end_chunk - start_chunk);
+            this.write(chars,start_chunk, len_chunk);
+        }
+        return;
+      }
+    }
+
+
+
+    final int n = length+start;
+    final byte[] buf_loc = m_outputBytes; // local reference for faster access
+    int count_loc = count;      // local integer for faster access
+    int i = start;
+    {
+        /* This block could be omitted and the code would produce
+         * the same result. But this block exists to give the JIT
+         * a better chance of optimizing a tight and common loop which
+         * occurs when writing out ASCII characters. 
+         */ 
+        char c;
+        for(; i < n && (c = chars[i])< 0x80 ; i++ )
+            buf_loc[count_loc++] = (byte)c;
+    }
+    for (; i < n; i++)
+    {
+
+      final char c = chars[i];
+
+      if (c < 0x80)
+        buf_loc[count_loc++] = (byte) (c);
+      else if (c < 0x800)
+      {
+        buf_loc[count_loc++] = (byte) (0xc0 + (c >> 6));
+        buf_loc[count_loc++] = (byte) (0x80 + (c & 0x3f));
+      }
+      /**
+        * The following else if condition is added to support XML 1.1 Characters for 
+        * UTF-8:   [1111 0uuu] [10uu zzzz] [10yy yyyy] [10xx xxxx]*
+        * Unicode: [1101 10ww] [wwzz zzyy] (high surrogate)
+        *          [1101 11yy] [yyxx xxxx] (low surrogate)
+        *          * uuuuu = wwww + 1
+        */
+      else if (c >= 0xD800 && c <= 0xDBFF) 
+      {
+          char high, low;
+          high = c;
+          i++;
+          low = chars[i];
+
+          buf_loc[count_loc++] = (byte) (0xF0 | (((high + 0x40) >> 8) & 0xf0));
+          buf_loc[count_loc++] = (byte) (0x80 | (((high + 0x40) >> 2) & 0x3f));
+          buf_loc[count_loc++] = (byte) (0x80 | ((low >> 6) & 0x0f) + ((high << 4) & 0x30));
+          buf_loc[count_loc++] = (byte) (0x80 | (low & 0x3f));
+      }
+      else
+      {
+        buf_loc[count_loc++] = (byte) (0xe0 + (c >> 12));
+        buf_loc[count_loc++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+        buf_loc[count_loc++] = (byte) (0x80 + (c & 0x3f));
+      }
+    }
+    // Store the local integer back into the instance variable
+    count = count_loc;
+
+  }
+
+  /**
+   * Write a string.
+   *
+   * @param  s  String to be written
+   *
+   * @exception  IOException  If an I/O error occurs
+   */
+  public void write(final String s) throws IOException
+  {
+
+    // We multiply the length by three since this is the maximum length
+    // of the characters that we can put into the buffer.  It is possible
+    // for each Unicode character to expand to three bytes.
+    final int length = s.length();
+    int lengthx3 = 3*length;
+
+    if (lengthx3 >= BYTES_MAX - count)
+    {
+      // The requested length is greater than the unused part of the buffer
+      flushBuffer();
+
+      if (lengthx3 > BYTES_MAX)
+      {
+        /*
+         * The requested length exceeds the size of the buffer,
+         * so break it up in chunks that don't exceed the buffer size.
+         */
+         final int start = 0;
+         int split = length/CHARS_MAX; 
+         final int chunks;
+         if (length % CHARS_MAX > 0) 
+             chunks = split + 1;
+         else
+             chunks = split;
+         int end_chunk = 0;
+         for (int chunk = 1; chunk <= chunks; chunk++)
+         {
+             int start_chunk = end_chunk;
+             end_chunk = start + (int) ((((long) length) * chunk) / chunks);
+             s.getChars(start_chunk,end_chunk, m_inputChars,0);
+             int len_chunk = (end_chunk - start_chunk);
+
+             // Adjust the end of the chunk if it ends on a high char 
+             // of a Unicode surrogate pair and low char of the pair
+             // is not going to be in the same chunk
+             final char c = m_inputChars[len_chunk - 1];
+             if (c >= 0xD800 && c <= 0xDBFF) {
+                 // Exclude char in this chunk, 
+                 // to avoid spanning a Unicode character 
+                 // that is in two Java chars as a high/low surrogate
+                 end_chunk--;
+                 len_chunk--;
+                 if (chunk == chunks) {
+                     /* TODO: error message needed.
+                      * The String incorrectly ends in a high char
+                      * of a high/low surrogate pair, but there is
+                      * no corresponding low as the high is the last char
+                      * Recover by ignoring this last char.
+                      */
+                 }
+             }
+
+             this.write(m_inputChars,0, len_chunk);
+         }
+         return;
+      }
+    }
+
+
+    s.getChars(0, length , m_inputChars, 0);
+    final char[] chars = m_inputChars;
+    final int n = length;
+    final byte[] buf_loc = m_outputBytes; // local reference for faster access
+    int count_loc = count;      // local integer for faster access
+    int i = 0;
+    {
+        /* This block could be omitted and the code would produce
+         * the same result. But this block exists to give the JIT
+         * a better chance of optimizing a tight and common loop which
+         * occurs when writing out ASCII characters. 
+         */ 
+        char c;
+        for(; i < n && (c = chars[i])< 0x80 ; i++ )
+            buf_loc[count_loc++] = (byte)c;
+    }
+    for (; i < n; i++)
+    {
+
+      final char c = chars[i];
+
+      if (c < 0x80)
+        buf_loc[count_loc++] = (byte) (c);
+      else if (c < 0x800)
+      {
+        buf_loc[count_loc++] = (byte) (0xc0 + (c >> 6));
+        buf_loc[count_loc++] = (byte) (0x80 + (c & 0x3f));
+      }
+    /**
+      * The following else if condition is added to support XML 1.1 Characters for 
+      * UTF-8:   [1111 0uuu] [10uu zzzz] [10yy yyyy] [10xx xxxx]*
+      * Unicode: [1101 10ww] [wwzz zzyy] (high surrogate)
+      *          [1101 11yy] [yyxx xxxx] (low surrogate)
+      *          * uuuuu = wwww + 1
+      */
+    else if (c >= 0xD800 && c <= 0xDBFF) 
+    {
+        char high, low;
+        high = c;
+        i++;
+        low = chars[i];
+
+        buf_loc[count_loc++] = (byte) (0xF0 | (((high + 0x40) >> 8) & 0xf0));
+        buf_loc[count_loc++] = (byte) (0x80 | (((high + 0x40) >> 2) & 0x3f));
+        buf_loc[count_loc++] = (byte) (0x80 | ((low >> 6) & 0x0f) + ((high << 4) & 0x30));
+        buf_loc[count_loc++] = (byte) (0x80 | (low & 0x3f));
+    }
+      else
+      {
+        buf_loc[count_loc++] = (byte) (0xe0 + (c >> 12));
+        buf_loc[count_loc++] = (byte) (0x80 + ((c >> 6) & 0x3f));
+        buf_loc[count_loc++] = (byte) (0x80 + (c & 0x3f));
+      }
+    }
+    // Store the local integer back into the instance variable
+    count = count_loc;
+
+  }
+
+  /**
+   * Flush the internal buffer
+   *
+   * @throws IOException
+   */
+  public void flushBuffer() throws IOException
+  {
+
+    if (count > 0)
+    {
+      m_os.write(m_outputBytes, 0, count);
+
+      count = 0;
+    }
+  }
+
+  /**
+   * Flush the stream.  If the stream has saved any characters from the
+   * various write() methods in a buffer, write them immediately to their
+   * intended destination.  Then, if that destination is another character or
+   * byte stream, flush it.  Thus one flush() invocation will flush all the
+   * buffers in a chain of Writers and OutputStreams.
+   *
+   * @exception  IOException  If an I/O error occurs
+   *
+   * @throws java.io.IOException
+   */
+  public void flush() throws java.io.IOException
+  {
+    flushBuffer();
+    m_os.flush();
+  }
+
+  /**
+   * Close the stream, flushing it first.  Once a stream has been closed,
+   * further write() or flush() invocations will cause an IOException to be
+   * thrown.  Closing a previously-closed stream, however, has no effect.
+   *
+   * @exception  IOException  If an I/O error occurs
+   *
+   * @throws java.io.IOException
+   */
+  public void close() throws java.io.IOException
+  {
+    flushBuffer();
+    m_os.close();
+  }
+
+  /**
+   * Get the output stream where the events will be serialized to.
+   *
+   * @return reference to the result stream, or null of only a writer was
+   * set.
+   */
+  public OutputStream getOutputStream()
+  {
+    return m_os;
+  }
+
+  public Writer getWriter()
+  {
+    // Only one of getWriter() or getOutputStream() can return null
+    // This type of writer wraps an OutputStream, not a Writer.
+    return null;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/XMLEntities.properties b/src/main/java/org/apache/xml/serializer/XMLEntities.properties
new file mode 100644
index 0000000..c30bed3
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/XMLEntities.properties
@@ -0,0 +1,30 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: XMLEntities.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# @version $Revision: 468654 $ $Date: 2006-10-28 00:09:23 -0700 (Sat, 28 Oct 2006) $
+# This file must be encoded in UTF-8; see CharInfo.java
+#
+# Character entity references for markup-significant
+#
+quot=34
+amp=38
+lt=60
+gt=62
+
diff --git a/src/main/java/org/apache/xml/serializer/XSLOutputAttributes.java b/src/main/java/org/apache/xml/serializer/XSLOutputAttributes.java
new file mode 100644
index 0000000..a6fa0f8
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/XSLOutputAttributes.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XSLOutputAttributes.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer;
+
+import java.util.Vector;
+
+/**
+ * This interface has methods associated with the XSLT xsl:output attribues
+ * specified in the stylesheet that effect the format of the document output.
+ * 
+ * In an XSLT stylesheet these attributes appear for example as:
+ * <pre>
+ * <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
+ * </pre>
+ * The xsl:output attributes covered in this interface are:
+ * <pre>
+ * version
+ * encoding
+ * omit-xml-declarations
+ * standalone
+ * doctype-public
+ * doctype-system
+ * cdata-section-elements
+ * indent
+ * media-type
+ * </pre>
+ * 
+ * The one attribute not covered in this interface is <code>method</code> as
+ * this value is implicitly chosen by the serializer that is created, for
+ * example ToXMLStream vs. ToHTMLStream or another one.
+ * 
+ * This interface is only used internally within Xalan.
+ * 
+ * @xsl.usage internal
+ */
+interface XSLOutputAttributes
+{
+    /**
+     * Returns the previously set value of the value to be used as the public
+     * identifier in the document type declaration (DTD).
+     *
+     *@return the public identifier to be used in the DOCTYPE declaration in the
+     * output document.
+     */
+    public String getDoctypePublic();
+    /**
+     * Returns the previously set value of the value to be used
+     * as the system identifier in the document type declaration (DTD).
+     * @return the system identifier to be used in the DOCTYPE declaration in
+     * the output document.
+     *
+     */ 
+    public String getDoctypeSystem();
+    /**
+     * @return the character encoding to be used in the output document.
+     */    
+    public String getEncoding();
+    /**
+	 * @return true if the output document should be indented to visually
+	 * indicate its structure.
+     */    
+    public boolean getIndent();
+    
+    /**
+     * @return the number of spaces to indent for each indentation level.
+     */
+    public int getIndentAmount();
+    /**
+     * @return the mediatype the media-type or MIME type associated with the
+     * output document.
+     */    
+    public String getMediaType();
+    /**
+     * @return true if the XML declaration is to be omitted from the output
+     * document.
+     */    
+    public boolean getOmitXMLDeclaration();
+    /**
+      * @return a value of "yes" if the <code>standalone</code> delaration is to
+      * be included in the output document.
+      */    
+    public String getStandalone();
+    /**
+     * @return the version of the output format.
+     */    
+    public String getVersion();
+
+
+
+
+
+
+    /**
+     * Sets the value coming from the xsl:output cdata-section-elements
+     * stylesheet property.
+     * 
+     * This sets the elements whose text elements are to be output as CDATA
+     * sections.
+     * @param URI_and_localNames pairs of namespace URI and local names that
+     * identify elements whose text elements are to be output as CDATA sections.
+     * The namespace of the local element must be the given URI to match. The
+     * qName is not given because the prefix does not matter, only the namespace
+     * URI to which that prefix would map matters, so the prefix itself is not
+     * relevant in specifying which elements have their text to be output as
+     * CDATA sections.
+     */
+    public void setCdataSectionElements(Vector URI_and_localNames);
+
+    /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
+     * @param system the system identifier to be used in the DOCTYPE declaration
+     * in the output document.
+     * @param pub the public identifier to be used in the DOCTYPE declaration in
+     * the output document.
+     */
+    public void setDoctype(String system, String pub);
+
+    /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
+      * @param doctype the public identifier to be used in the DOCTYPE
+      * declaration in the output document.
+      */
+    public void setDoctypePublic(String doctype);
+    /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
+      * @param doctype the system identifier to be used in the DOCTYPE
+      * declaration in the output document.
+      */
+    public void setDoctypeSystem(String doctype);
+    /**
+     * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
+     * @param encoding the character encoding
+     */
+    public void setEncoding(String encoding);
+    /**
+     * Sets the value coming from the xsl:output indent stylesheet
+     * attribute.
+     * @param indent true if the output document should be indented to visually
+     * indicate its structure.
+     */
+    public void setIndent(boolean indent);
+    /**
+     * Sets the value coming from the xsl:output media-type stylesheet attribute.
+     * @param mediatype the media-type or MIME type associated with the output
+     * document.
+     */
+    public void setMediaType(String mediatype);
+    /**
+     * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
+     * @param b true if the XML declaration is to be omitted from the output
+     * document.
+     */
+    public void setOmitXMLDeclaration(boolean b);
+    /**
+     * Sets the value coming from the xsl:output standalone stylesheet attribute.
+     * @param standalone a value of "yes" indicates that the
+     * <code>standalone</code> delaration is to be included in the output
+     * document.
+     */
+    public void setStandalone(String standalone);
+    /**
+     * Sets the value coming from the xsl:output version attribute.
+     * @param version the version of the output format.
+     */
+    public void setVersion(String version);
+
+    /**
+     * Get the value for a property that affects seraialization,
+     * if a property was set return that value, otherwise return
+     * the default value, otherwise return null.
+     * @param name The name of the property, which is just the local name
+     * if it is in no namespace, but is the URI in curly braces followed by
+     * the local name if it is in a namespace, for example:
+     * <ul>
+     * <li> "encoding"
+     * <li> "method"
+     * <li> "{http://xml.apache.org/xalan}indent-amount"
+     * <li> "{http://xml.apache.org/xalan}line-separator"
+     * </ul>
+     * @return The value of the parameter
+     */
+    public String getOutputProperty(String name);
+    /**
+     * Get the default value for a property that affects seraialization,
+     * or null if there is none. It is possible that a non-default value
+     * was set for the property, however the value returned by this method
+     * is unaffected by any non-default settings.
+     * @param name The name of the property.
+     * @return The default value of the parameter, or null if there is no default value.
+     */    
+    public String getOutputPropertyDefault(String name);
+    /**
+     * Set the non-default value for a property that affects seraialization.
+     * @param name The name of the property, which is just the local name
+     * if it is in no namespace, but is the URI in curly braces followed by
+     * the local name if it is in a namespace, for example:
+     * <ul>
+     * <li> "encoding"
+     * <li> "method"
+     * <li> "{http://xml.apache.org/xalan}indent-amount"
+     * <li> "{http://xml.apache.org/xalan}line-separator"
+     * </ul>
+     * @val The non-default value of the parameter
+     */    
+    public void   setOutputProperty(String name, String val);
+    
+    /**
+     * Set the default value for a property that affects seraialization.
+     * @param name The name of the property, which is just the local name
+     * if it is in no namespace, but is the URI in curly braces followed by
+     * the local name if it is in a namespace, for example:
+     * <ul>
+     * <li> "encoding"
+     * <li> "method"
+     * <li> "{http://xml.apache.org/xalan}indent-amount"
+     * <li> "{http://xml.apache.org/xalan}line-separator"
+     * </ul>
+     * @val The default value of the parameter
+     */ 
+    public void   setOutputPropertyDefault(String name, String val);
+}
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java
new file mode 100644
index 0000000..fcc9882
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import java.io.IOException;
+
+import org.apache.xml.serializer.DOM3Serializer;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.serializer.utils.WrappedRuntimeException;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.LSSerializerFilter;
+
+/**
+ * This class implements the DOM3Serializer interface.
+ * 
+ * @xsl.usage internal
+ */
+public final class DOM3SerializerImpl implements DOM3Serializer {
+
+    /**
+     * Private class members
+     */
+    // The DOMErrorHandler
+    private DOMErrorHandler fErrorHandler;
+
+    // A LSSerializerFilter
+    private LSSerializerFilter fSerializerFilter;
+
+    // A LSSerializerFilter
+    private String fNewLine;
+
+    // A SerializationHandler ex. an instance of ToXMLStream
+    private SerializationHandler fSerializationHandler;
+
+    /**
+     * Constructor
+     * 
+     * @param handler An instance of the SerializationHandler interface. 
+     */
+    public DOM3SerializerImpl(SerializationHandler handler) {
+        fSerializationHandler = handler;
+    }
+
+    // Public memebers
+
+    /**
+     * Returns a DOMErrorHandler set on the DOM Level 3 Serializer.
+     * 
+     * This interface is a public API.
+     *
+     * @return A Level 3 DOMErrorHandler
+     */
+    public DOMErrorHandler getErrorHandler() {
+        return fErrorHandler;
+    }
+
+    /**
+     * Returns a LSSerializerFilter set on the DOM Level 3 Serializer to filter nodes
+     * during serialization.
+     * 
+     * This interface is a public API.
+     *
+     * @return The Level 3 LSSerializerFilter
+     */
+    public LSSerializerFilter getNodeFilter() {
+        return fSerializerFilter;
+    }
+    
+    /**
+     * Gets the end-of-line sequence of characters to be used during serialization.
+     */
+    public char[] getNewLine() {
+        return (fNewLine != null) ? fNewLine.toCharArray() : null;
+    }
+
+    /**
+     * Serializes the Level 3 DOM node by creating an instance of DOM3TreeWalker
+     * which traverses the DOM tree and invokes handler events to serialize
+     * the DOM NOde. Throws an exception only if an I/O exception occured
+     * while serializing.
+     * This interface is a public API.
+     *
+     * @param node the Level 3 DOM node to serialize
+     * @throws IOException if an I/O exception occured while serializing
+     */
+    public void serializeDOM3(Node node) throws IOException {
+        try {
+            DOM3TreeWalker walker = new DOM3TreeWalker(fSerializationHandler,
+                    fErrorHandler, fSerializerFilter, fNewLine);
+
+            walker.traverse(node);
+        } catch (org.xml.sax.SAXException se) {
+            throw new WrappedRuntimeException(se);
+        }
+    }
+
+    /**
+     * Sets a DOMErrorHandler on the DOM Level 3 Serializer.
+     * 
+     * This interface is a public API.
+     *
+     * @param handler the Level 3 DOMErrorHandler
+     */
+    public void setErrorHandler(DOMErrorHandler handler) {
+        fErrorHandler = handler;
+    }
+
+    /**
+     * Sets a LSSerializerFilter on the DOM Level 3 Serializer to filter nodes
+     * during serialization.
+     * 
+     * This interface is a public API.
+     *
+     * @param filter the Level 3 LSSerializerFilter
+     */
+    public void setNodeFilter(LSSerializerFilter filter) {
+        fSerializerFilter = filter;
+    }
+
+    /**
+     * Sets a SerializationHandler on the DOM Serializer.
+     * 
+     * This interface is a public API.
+     *
+     * @param handler An instance of SerializationHandler
+     */
+    public void setSerializationHandler(SerializationHandler handler) {
+        fSerializationHandler = handler;
+    }
+
+    /**
+     * Sets the end-of-line sequence of characters to be used during serialization.
+     * @param newLine The end-of-line sequence of characters to be used during serialization.
+     */
+    public void setNewLine(char[] newLine) {
+        fNewLine = (newLine != null) ? new String(newLine) : null;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOM3TreeWalker.java b/src/main/java/org/apache/xml/serializer/dom3/DOM3TreeWalker.java
new file mode 100644
index 0000000..0b62423
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOM3TreeWalker.java
@@ -0,0 +1,2149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import org.apache.xml.serializer.dom3.NamespaceSupport;
+import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.apache.xml.serializer.utils.XML11Char;
+import org.apache.xml.serializer.utils.XMLChar;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Entity;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.ls.LSSerializerFilter;
+import org.w3c.dom.traversal.NodeFilter;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * Built on org.apache.xml.serializer.TreeWalker and adds functionality to
+ * traverse and serialize a DOM Node (Level 2 or Level 3) as specified in 
+ * the DOM Level 3 LS Recommedation by evaluating and applying DOMConfiguration 
+ * parameters and filters if any during serialization.
+ *   
+ * @xsl.usage internal
+ */
+final class DOM3TreeWalker {
+
+    /**
+     * The SerializationHandler, it extends ContentHandler and when
+     * this class is instantiated via the constructor provided, a
+     * SerializationHandler object is passed to it.
+     */
+    private SerializationHandler fSerializer = null;
+
+    /** We do not need DOM2Helper since DOM Level 3 LS applies to DOM Level 2 or newer */
+
+    /** Locator object for this TreeWalker          */
+    private LocatorImpl fLocator = new LocatorImpl();
+
+    /** ErrorHandler */
+    private DOMErrorHandler fErrorHandler = null;
+
+    /** LSSerializerFilter */
+    private LSSerializerFilter fFilter = null;
+
+    /** If the serializer is an instance of a LexicalHandler */
+    private LexicalHandler fLexicalHandler = null;
+
+    private int fWhatToShowFilter;
+
+    /** New Line character to use in serialization */
+    private String fNewLine = null;
+
+    /** DOMConfiguration Properties */
+    private Properties fDOMConfigProperties = null;
+
+    /** Keeps track if we are in an entity reference when entities=true */
+    private boolean fInEntityRef = false;
+
+    /** Stores the version of the XML document to be serialize */
+    private String fXMLVersion = null;
+
+    /** XML Version, default 1.0 */
+    private boolean fIsXMLVersion11 = false;
+
+    /** Is the Node a Level 3 DOM node */
+    private boolean fIsLevel3DOM = false;
+
+    /** DOM Configuration Parameters */
+    private int fFeatures = 0;
+
+    /** Flag indicating whether following text to be processed is raw text          */
+    boolean fNextIsRaw = false;
+
+    // 
+    private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+
+    //
+    private static final String XMLNS_PREFIX = "xmlns";
+
+    // 
+    private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
+
+    // 
+    private static final String XML_PREFIX = "xml";
+
+    /** stores namespaces in scope */
+    protected NamespaceSupport fNSBinder;
+
+    /** stores all namespace bindings on the current element */
+    protected NamespaceSupport fLocalNSBinder;
+    
+    /** stores the current element depth */
+    private int fElementDepth = 0;
+
+    // ***********************************************************************
+    // DOMConfiguration paramter settings 
+    // ***********************************************************************
+    // Parameter canonical-form, true [optional] - NOT SUPPORTED 
+    private final static int CANONICAL = 0x1 << 0;
+
+    // Parameter cdata-sections, true [required] (default)
+    private final static int CDATA = 0x1 << 1;
+
+    // Parameter check-character-normalization, true [optional] - NOT SUPPORTED 
+    private final static int CHARNORMALIZE = 0x1 << 2;
+
+    // Parameter comments, true [required] (default)
+    private final static int COMMENTS = 0x1 << 3;
+
+    // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
+    private final static int DTNORMALIZE = 0x1 << 4;
+
+    // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
+    private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;
+
+    // Parameter entities, true [required] (default)
+    private final static int ENTITIES = 0x1 << 6;
+
+    // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
+    private final static int INFOSET = 0x1 << 7;
+
+    // Parameter namespaces, true [required] (default)
+    private final static int NAMESPACES = 0x1 << 8;
+
+    // Parameter namespace-declarations, true [required] (default)
+    private final static int NAMESPACEDECLS = 0x1 << 9;
+
+    // Parameter normalize-characters, true [optional] - NOT SUPPORTED
+    private final static int NORMALIZECHARS = 0x1 << 10;
+
+    // Parameter split-cdata-sections, true [required] (default)
+    private final static int SPLITCDATA = 0x1 << 11;
+
+    // Parameter validate, true [optional] - NOT SUPPORTED
+    private final static int VALIDATE = 0x1 << 12;
+
+    // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
+    private final static int SCHEMAVALIDATE = 0x1 << 13;
+
+    // Parameter split-cdata-sections, true [required] (default)
+    private final static int WELLFORMED = 0x1 << 14;
+
+    // Parameter discard-default-content, true [required] (default)
+    // Not sure how this will be used in level 2 Documents
+    private final static int DISCARDDEFAULT = 0x1 << 15;
+
+    // Parameter format-pretty-print, true [optional] 
+    private final static int PRETTY_PRINT = 0x1 << 16;
+
+    // Parameter ignore-unknown-character-denormalizations, true [required] (default)
+    // We currently do not support XML 1.1 character normalization
+    private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;
+
+    // Parameter discard-default-content, true [required] (default)
+    private final static int XMLDECL = 0x1 << 18;
+
+    /**
+     * Constructor.
+     * @param   contentHandler serialHandler The implemention of the SerializationHandler interface
+     */
+    DOM3TreeWalker(
+        SerializationHandler serialHandler,
+        DOMErrorHandler errHandler,
+        LSSerializerFilter filter,
+        String newLine) {
+        fSerializer = serialHandler;
+        //fErrorHandler = errHandler == null ? new DOMErrorHandlerImpl() : errHandler; // Should we be using the default?
+        fErrorHandler = errHandler;
+        fFilter = filter;
+        fLexicalHandler = null;
+        fNewLine = newLine;
+
+        fNSBinder = new NamespaceSupport();
+        fLocalNSBinder = new NamespaceSupport();
+        
+        fDOMConfigProperties = fSerializer.getOutputFormat();
+        fSerializer.setDocumentLocator(fLocator);
+        initProperties(fDOMConfigProperties);
+        
+        try {
+            // Bug see Bugzilla  26741
+            fLocator.setSystemId(
+                System.getProperty("user.dir") + File.separator + "dummy.xsl");
+        } catch (SecurityException se) { // user.dir not accessible from applet
+
+        }
+    }
+
+    /**
+     * Perform a pre-order traversal non-recursive style.  
+     *
+     * Note that TreeWalker assumes that the subtree is intended to represent 
+     * a complete (though not necessarily well-formed) document and, during a 
+     * traversal, startDocument and endDocument will always be issued to the 
+     * SAX listener.
+     *  
+     * @param pos Node in the tree where to start traversal
+     *
+     * @throws TransformerException
+     */
+    public void traverse(Node pos) throws org.xml.sax.SAXException {
+        this.fSerializer.startDocument();
+
+        // Determine if the Node is a DOM Level 3 Core Node.
+        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
+            Document ownerDoc = pos.getOwnerDocument();
+            if (ownerDoc != null
+                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
+                fIsLevel3DOM = true;
+            }
+        } else {
+            if (((Document) pos)
+                .getImplementation()
+                .hasFeature("Core", "3.0")) {
+                fIsLevel3DOM = true;
+            }
+        }
+
+        if (fSerializer instanceof LexicalHandler) {
+            fLexicalHandler = ((LexicalHandler) this.fSerializer);
+        }
+
+        if (fFilter != null)
+            fWhatToShowFilter = fFilter.getWhatToShow();
+
+        Node top = pos;
+
+        while (null != pos) {
+            startNode(pos);
+
+            Node nextNode = null;
+
+            nextNode = pos.getFirstChild();
+
+            while (null == nextNode) {
+                endNode(pos);
+
+                if (top.equals(pos))
+                    break;
+
+                nextNode = pos.getNextSibling();
+
+                if (null == nextNode) {
+                    pos = pos.getParentNode();
+
+                    if ((null == pos) || (top.equals(pos))) {
+                        if (null != pos)
+                            endNode(pos);
+
+                        nextNode = null;
+
+                        break;
+                    }
+                }
+            }
+
+            pos = nextNode;
+        }
+        this.fSerializer.endDocument();
+    }
+
+    /**
+     * Perform a pre-order traversal non-recursive style.
+     
+     * Note that TreeWalker assumes that the subtree is intended to represent 
+     * a complete (though not necessarily well-formed) document and, during a 
+     * traversal, startDocument and endDocument will always be issued to the 
+     * SAX listener.
+     *
+     * @param pos Node in the tree where to start traversal
+     * @param top Node in the tree where to end traversal
+     *
+     * @throws TransformerException
+     */
+    public void traverse(Node pos, Node top) throws org.xml.sax.SAXException {
+
+        this.fSerializer.startDocument();
+
+        // Determine if the Node is a DOM Level 3 Core Node.
+        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
+            Document ownerDoc = pos.getOwnerDocument();
+            if (ownerDoc != null
+                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
+                fIsLevel3DOM = true;
+            }
+        } else {
+            if (((Document) pos)
+                .getImplementation()
+                .hasFeature("Core", "3.0")) {
+                fIsLevel3DOM = true;
+            }
+        }
+
+        if (fSerializer instanceof LexicalHandler) {
+            fLexicalHandler = ((LexicalHandler) this.fSerializer);
+        }
+
+        if (fFilter != null)
+            fWhatToShowFilter = fFilter.getWhatToShow();
+
+        while (null != pos) {
+            startNode(pos);
+
+            Node nextNode = null;
+
+            nextNode = pos.getFirstChild();
+
+            while (null == nextNode) {
+                endNode(pos);
+
+                if ((null != top) && top.equals(pos))
+                    break;
+
+                nextNode = pos.getNextSibling();
+
+                if (null == nextNode) {
+                    pos = pos.getParentNode();
+
+                    if ((null == pos) || ((null != top) && top.equals(pos))) {
+                        nextNode = null;
+
+                        break;
+                    }
+                }
+            }
+
+            pos = nextNode;
+        }
+        this.fSerializer.endDocument();
+    }
+
+    /**
+     * Optimized dispatch of characters.
+     */
+    private final void dispatachChars(Node node)
+        throws org.xml.sax.SAXException {
+        if (fSerializer != null) {
+            this.fSerializer.characters(node);
+        } else {
+            String data = ((Text) node).getData();
+            this.fSerializer.characters(data.toCharArray(), 0, data.length());
+        }
+    }
+
+    /**
+     * Start processing given node
+     *
+     * @param node Node to process
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void startNode(Node node) throws org.xml.sax.SAXException {
+        if (node instanceof Locator) {
+            Locator loc = (Locator) node;
+            fLocator.setColumnNumber(loc.getColumnNumber());
+            fLocator.setLineNumber(loc.getLineNumber());
+            fLocator.setPublicId(loc.getPublicId());
+            fLocator.setSystemId(loc.getSystemId());
+        } else {
+            fLocator.setColumnNumber(0);
+            fLocator.setLineNumber(0);
+        }
+
+        switch (node.getNodeType()) {
+            case Node.DOCUMENT_TYPE_NODE :
+                serializeDocType((DocumentType) node, true);
+                break;
+            case Node.COMMENT_NODE :
+                serializeComment((Comment) node);
+                break;
+            case Node.DOCUMENT_FRAGMENT_NODE :
+                // Children are traversed
+                break;
+            case Node.DOCUMENT_NODE :
+                break;
+            case Node.ELEMENT_NODE :
+                serializeElement((Element) node, true);
+                break;
+            case Node.PROCESSING_INSTRUCTION_NODE :
+                serializePI((ProcessingInstruction) node);
+                break;
+            case Node.CDATA_SECTION_NODE :
+                serializeCDATASection((CDATASection) node);
+                break;
+            case Node.TEXT_NODE :
+                serializeText((Text) node);
+                break;
+            case Node.ENTITY_REFERENCE_NODE :
+                serializeEntityReference((EntityReference) node, true);
+                break;
+            default :
+                }
+    }
+
+    /**
+     * End processing of given node 
+     *
+     *
+     * @param node Node we just finished processing
+     *
+     * @throws org.xml.sax.SAXException
+     */
+    protected void endNode(Node node) throws org.xml.sax.SAXException {
+
+        switch (node.getNodeType()) {
+            case Node.DOCUMENT_NODE :
+                break;
+            case Node.DOCUMENT_TYPE_NODE :
+                serializeDocType((DocumentType) node, false);
+                break;
+            case Node.ELEMENT_NODE :
+                serializeElement((Element) node, false);
+                break;
+            case Node.CDATA_SECTION_NODE :
+                break;
+            case Node.ENTITY_REFERENCE_NODE :
+                serializeEntityReference((EntityReference) node, false);
+                break;
+            default :
+                }
+    }
+
+    // ***********************************************************************
+    // Node serialization methods
+    // ***********************************************************************
+    /**
+     * Applies a filter on the node to serialize
+     * 
+     * @param node The Node to serialize
+     * @return True if the node is to be serialized else false if the node 
+     *         is to be rejected or skipped. 
+     */
+    protected boolean applyFilter(Node node, int nodeType) {
+        if (fFilter != null && (fWhatToShowFilter & nodeType) != 0) {
+
+            short code = fFilter.acceptNode(node);
+            switch (code) {
+                case NodeFilter.FILTER_REJECT :
+                case NodeFilter.FILTER_SKIP :
+                    return false; // skip the node
+                default : // fall through..
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Serializes a Document Type Node.
+     * 
+     * @param node The Docuemnt Type Node to serialize
+     * @param bStart Invoked at the start or end of node.  Default true. 
+     */
+    protected void serializeDocType(DocumentType node, boolean bStart)
+        throws SAXException {
+        // The DocType and internalSubset can not be modified in DOM and is
+        // considered to be well-formed as the outcome of successful parsing.
+        String docTypeName = node.getNodeName();
+        String publicId = node.getPublicId();
+        String systemId = node.getSystemId();
+        String internalSubset = node.getInternalSubset();
+
+        //DocumentType nodes are never passed to the filter
+        
+        if (internalSubset != null && !"".equals(internalSubset)) {
+
+            if (bStart) {
+                try {
+                    // The Serializer does not provide a way to write out the
+                    // DOCTYPE internal subset via an event call, so we write it
+                    // out here.
+                    Writer writer = fSerializer.getWriter();
+                    StringBuffer dtd = new StringBuffer();
+
+                    dtd.append("<!DOCTYPE ");
+                    dtd.append(docTypeName);
+                    if (null != publicId) {
+                        dtd.append(" PUBLIC \"");
+                        dtd.append(publicId);
+                        dtd.append('\"');
+                    }
+
+                    if (null != systemId) {
+                        if (null == publicId) {
+                            dtd.append(" SYSTEM \"");
+                        } else {
+                            dtd.append(" \"");
+                        }    
+                        dtd.append(systemId);
+                        dtd.append('\"');
+                    }
+                    
+                    dtd.append(" [ ");
+                    
+                    dtd.append(fNewLine);
+                    dtd.append(internalSubset);
+                    dtd.append("]>");
+                    dtd.append(new String(fNewLine));
+                    
+                    writer.write(dtd.toString());
+                    writer.flush();
+                    
+                } catch (IOException e) {
+                    throw new SAXException(Utils.messages.createMessage(
+                            MsgKey.ER_WRITING_INTERNAL_SUBSET, null), e);
+                }
+            } // else if !bStart do nothing
+            
+        } else {
+            
+            if (bStart) {
+                if (fLexicalHandler != null) {
+                    fLexicalHandler.startDTD(docTypeName, publicId, systemId);
+                }
+            } else {
+                if (fLexicalHandler != null) {
+                    fLexicalHandler.endDTD();
+                }
+            }
+        }
+    }
+
+    /**
+     * Serializes a Comment Node.
+     * 
+     * @param node The Comment Node to serialize
+     */
+    protected void serializeComment(Comment node) throws SAXException {
+        // comments=true
+        if ((fFeatures & COMMENTS) != 0) {
+            String data = node.getData();
+
+            // well-formed=true
+            if ((fFeatures & WELLFORMED) != 0) {
+                isCommentWellFormed(data);
+            }
+
+            if (fLexicalHandler != null) {
+                // apply the LSSerializer filter after the operations requested by the 
+                // DOMConfiguration parameters have been applied 
+                if (!applyFilter(node, NodeFilter.SHOW_COMMENT)) {
+                    return;
+                }
+
+                fLexicalHandler.comment(data.toCharArray(), 0, data.length());
+            }
+        }
+    }
+
+    /**
+     * Serializes an Element Node.
+     * 
+     * @param node The Element Node to serialize
+     * @param bStart Invoked at the start or end of node.   
+     */
+    protected void serializeElement(Element node, boolean bStart)
+        throws SAXException {
+        if (bStart) {
+            fElementDepth++;
+
+            // We use the Xalan specific startElement and starPrefixMapping calls 
+            // (and addAttribute and namespaceAfterStartElement) as opposed to
+            // SAX specific, for performance reasons as they reduce the overhead
+            // of creating an AttList object upfront.
+
+            // well-formed=true
+            if ((fFeatures & WELLFORMED) != 0) {
+                isElementWellFormed(node);
+            }
+
+            // REVISIT: We apply the LSSerializer filter for elements before
+            // namesapce fixup
+            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
+                return;
+            }
+
+            // namespaces=true, record and fixup namspaced element
+            if ((fFeatures & NAMESPACES) != 0) {
+            	fNSBinder.pushContext();
+            	fLocalNSBinder.reset();
+            	
+                recordLocalNSDecl(node);
+                fixupElementNS(node);
+            }
+
+            // Namespace normalization
+            fSerializer.startElement(
+            		node.getNamespaceURI(),
+                    node.getLocalName(),
+                    node.getNodeName());
+
+            serializeAttList(node);
+            
+        } else {
+        	fElementDepth--;
+
+            // apply the LSSerializer filter
+            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
+                return;
+            }
+
+            this.fSerializer.endElement(
+            	node.getNamespaceURI(),
+                node.getLocalName(),
+                node.getNodeName());
+            // since endPrefixMapping was not used by SerializationHandler it was removed
+            // for performance reasons.
+
+            if ((fFeatures & NAMESPACES) != 0 ) {
+                    fNSBinder.popContext();
+            }
+            
+        }
+    }
+
+    /**
+     * Serializes the Attr Nodes of an Element.
+     * 
+     * @param node The OwnerElement whose Attr Nodes are to be serialized.
+     */
+    protected void serializeAttList(Element node) throws SAXException {
+        NamedNodeMap atts = node.getAttributes();
+        int nAttrs = atts.getLength();
+
+        for (int i = 0; i < nAttrs; i++) {
+            Node attr = atts.item(i);
+
+            String localName = attr.getLocalName();
+            String attrName = attr.getNodeName();
+            String attrPrefix = attr.getPrefix() == null ? "" : attr.getPrefix();
+            String attrValue = attr.getNodeValue();
+
+            // Determine the Attr's type.
+            String type = null;
+            if (fIsLevel3DOM) {
+                type = ((Attr) attr).getSchemaTypeInfo().getTypeName();
+            }
+            type = type == null ? "CDATA" : type;
+
+            String attrNS = attr.getNamespaceURI();
+            if (attrNS !=null && attrNS.length() == 0) {
+            	attrNS=null;
+                // we must remove prefix for this attribute
+            	attrName=attr.getLocalName();
+            }
+
+            boolean isSpecified = ((Attr) attr).getSpecified();
+            boolean addAttr = true;
+            boolean applyFilter = false;
+            boolean xmlnsAttr =
+                attrName.equals("xmlns") || attrName.startsWith("xmlns:");
+
+            // well-formed=true
+            if ((fFeatures & WELLFORMED) != 0) {
+                isAttributeWellFormed(attr);
+            }
+            
+            //-----------------------------------------------------------------
+            // start Attribute namespace fixup
+            //-----------------------------------------------------------------
+            // namespaces=true, normalize all non-namespace attributes
+            // Step 3. Attribute
+            if ((fFeatures & NAMESPACES) != 0 && !xmlnsAttr) {
+           	
+        		// If the Attr has a namespace URI
+        		if (attrNS != null) {
+        			attrPrefix = attrPrefix == null ? "" : attrPrefix;
+
+        			String declAttrPrefix = fNSBinder.getPrefix(attrNS);
+        			String declAttrNS = fNSBinder.getURI(attrPrefix);
+        			
+        			// attribute has no prefix (default namespace decl does not apply to
+        			// attributes)
+        			// OR
+        			// attribute prefix is not declared
+        			// OR
+        			// conflict: attribute has a prefix that conflicts with a binding
+        			if ("".equals(attrPrefix) || "".equals(declAttrPrefix)
+        					|| !attrPrefix.equals(declAttrPrefix)) {
+
+        				// namespaceURI matches an in scope declaration of one or
+        				// more prefixes
+        				if (declAttrPrefix != null && !"".equals(declAttrPrefix)) {
+        					// pick the prefix that was found and change attribute's
+        					// prefix and nodeName.
+        					attrPrefix = declAttrPrefix;
+        					
+        					if (declAttrPrefix.length() > 0 ) { 
+        						attrName = declAttrPrefix + ":" + localName;
+        					} else {
+        						attrName = localName;
+        					}	
+        				} else {
+        					// The current prefix is not null and it has no in scope
+        					// declaration
+        					if (attrPrefix != null && !"".equals(attrPrefix)
+        							&& declAttrNS == null) {
+        						// declare this prefix
+        						if ((fFeatures & NAMESPACEDECLS) != 0) {
+        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
+        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
+        									attrNS);
+        							fNSBinder.declarePrefix(attrPrefix, attrNS);
+        							fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
+        						}
+        					} else {
+        						// find a prefix following the pattern "NS" +index
+        						// (starting at 1)
+        						// make sure this prefix is not declared in the current
+        						// scope.
+        						int counter = 1;
+        						attrPrefix = "NS" + counter++;
+
+        						while (fLocalNSBinder.getURI(attrPrefix) != null) {
+        							attrPrefix = "NS" + counter++;
+        						}
+        						// change attribute's prefix and Name
+        						attrName = attrPrefix + ":" + localName;
+        						
+        						// create a local namespace declaration attribute
+        						// Add the xmlns declaration attribute
+        						if ((fFeatures & NAMESPACEDECLS) != 0) {
+                                       							
+        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
+        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
+        									attrNS);
+            						fNSBinder.declarePrefix(attrPrefix, attrNS);
+            						fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
+        						}
+        					}
+        				}
+        			}
+
+        		} else { // if the Attr has no namespace URI
+        			// Attr has no localName
+        			if (localName == null) {
+        				// DOM Level 1 node!
+        				String msg = Utils.messages.createMessage(
+        						MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+        						new Object[] { attrName });
+
+        				if (fErrorHandler != null) {
+        					fErrorHandler
+        							.handleError(new DOMErrorImpl(
+        									DOMError.SEVERITY_ERROR, msg,
+        									MsgKey.ER_NULL_LOCAL_ELEMENT_NAME, null,
+        									null, null));
+        				}
+
+        			} else { // uri=null and no colon
+        				// attr has no namespace URI and no prefix
+        				// no action is required, since attrs don't use default
+        			}
+        		}
+
+            }
+
+            
+            // discard-default-content=true
+            // Default attr's are not passed to the filter and this contraint
+            // is applied only when discard-default-content=true 
+            // What about default xmlns attributes???? check for xmlnsAttr
+            if ((((fFeatures & DISCARDDEFAULT) != 0) && isSpecified)
+                || ((fFeatures & DISCARDDEFAULT) == 0)) {
+                applyFilter = true;
+            } else {
+            	addAttr = false;
+            }
+
+            if (applyFilter) {
+                // apply the filter for Attributes that are not default attributes
+                // or namespace decl attributes
+                if (fFilter != null
+                    && (fFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)
+                        != 0) {
+
+                    if (!xmlnsAttr) {
+                        short code = fFilter.acceptNode(attr);
+                        switch (code) {
+                            case NodeFilter.FILTER_REJECT :
+                            case NodeFilter.FILTER_SKIP :
+                                addAttr = false;
+                                break;
+                            default : //fall through..
+                        }
+                    }
+                }
+            }
+
+            // if the node is a namespace node
+            if (addAttr && xmlnsAttr) {
+                // If namespace-declarations=true, add the node , else don't add it
+                if ((fFeatures & NAMESPACEDECLS) != 0) {
+               		// The namespace may have been fixed up, in that case don't add it.
+                	if (localName != null && !"".equals(localName)) {
+                		fSerializer.addAttribute(attrNS, localName, attrName, type, attrValue);
+                	} 
+                }
+            } else if (
+                addAttr && !xmlnsAttr) { // if the node is not a namespace node
+                // If namespace-declarations=true, add the node with the Attr nodes namespaceURI
+                // else add the node setting it's namespace to null or else the serializer will later
+                // attempt to add a xmlns attr for the prefixed attribute
+                if (((fFeatures & NAMESPACEDECLS) != 0) && (attrNS != null)) {
+                    fSerializer.addAttribute(
+                        attrNS,
+                        localName,
+                        attrName,
+                        type,
+                        attrValue);
+                } else {
+                    fSerializer.addAttribute(
+                        "",
+                        localName,
+                        attrName,
+                        type,
+                        attrValue);
+                }
+            }
+
+            // 
+            if (xmlnsAttr && ((fFeatures & NAMESPACEDECLS) != 0)) {
+                int index;
+                // Use "" instead of null, as Xerces likes "" for the 
+                // name of the default namespace.  Fix attributed 
+                // to "Steven Murray" <smurray@ebt.com>.
+                String prefix =
+                    (index = attrName.indexOf(":")) < 0
+                        ? ""
+                        : attrName.substring(index + 1);
+
+                if (!"".equals(prefix)) {
+                    fSerializer.namespaceAfterStartElement(prefix, attrValue);
+                }
+            }
+        }
+        
+    }
+   
+    /**
+     * Serializes an ProcessingInstruction Node.
+     * 
+     * @param node The ProcessingInstruction Node to serialize
+     */
+    protected void serializePI(ProcessingInstruction node)
+        throws SAXException {
+        ProcessingInstruction pi = node;
+        String name = pi.getNodeName();
+
+        // well-formed=true
+        if ((fFeatures & WELLFORMED) != 0) {
+            isPIWellFormed(node);
+        }
+
+        // apply the LSSerializer filter
+        if (!applyFilter(node, NodeFilter.SHOW_PROCESSING_INSTRUCTION)) {
+            return;
+        }
+
+        // String data = pi.getData();
+        if (name.equals("xslt-next-is-raw")) {
+            fNextIsRaw = true;
+        } else {
+            this.fSerializer.processingInstruction(name, pi.getData());
+        }
+    }
+
+    /**
+     * Serializes an CDATASection Node.
+     * 
+     * @param node The CDATASection Node to serialize
+     */
+    protected void serializeCDATASection(CDATASection node)
+        throws SAXException {
+        // well-formed=true
+        if ((fFeatures & WELLFORMED) != 0) {
+            isCDATASectionWellFormed(node);
+        }
+
+        // cdata-sections = true
+        if ((fFeatures & CDATA) != 0) {
+
+            // split-cdata-sections = true
+            // Assumption: This parameter has an effect only when
+			// cdata-sections=true
+            // ToStream, by default splits cdata-sections. Hence the check
+			// below.
+            String nodeValue = node.getNodeValue();
+            int endIndex = nodeValue.indexOf("]]>");
+            if ((fFeatures & SPLITCDATA) != 0) {
+                if (endIndex >= 0) {
+                    // The first node split will contain the ]] markers
+                    String relatedData = nodeValue.substring(0, endIndex + 2);
+
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
+                            null);
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_WARNING,
+                                msg,
+                                MsgKey.ER_CDATA_SECTIONS_SPLIT,
+                                null,
+                                relatedData,
+                                null));
+                    }
+                }
+            } else {
+                if (endIndex >= 0) {
+                    // The first node split will contain the ]] markers 
+                    String relatedData = nodeValue.substring(0, endIndex + 2);
+
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
+                            null);
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_ERROR,
+                                msg,
+                                MsgKey.ER_CDATA_SECTIONS_SPLIT));
+                    }
+                    // Report an error and return.  What error???
+                    return;
+                }
+            }
+
+            // apply the LSSerializer filter
+            if (!applyFilter(node, NodeFilter.SHOW_CDATA_SECTION)) {
+                return;
+            }
+
+            // splits the cdata-section
+            if (fLexicalHandler != null) {
+                fLexicalHandler.startCDATA();
+            }
+            dispatachChars(node);
+            if (fLexicalHandler != null) {
+                fLexicalHandler.endCDATA();
+            }
+        } else {
+            dispatachChars(node);
+        }
+    }
+
+    /**
+     * Serializes an Text Node.
+     * 
+     * @param node The Text Node to serialize
+     */
+    protected void serializeText(Text node) throws SAXException {
+        if (fNextIsRaw) {
+            fNextIsRaw = false;
+            fSerializer.processingInstruction(
+                javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING,
+                "");
+            dispatachChars(node);
+            fSerializer.processingInstruction(
+                javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING,
+                "");
+        } else {
+            // keep track of dispatch or not to avoid duplicaiton of filter code
+            boolean bDispatch = false;
+
+            // well-formed=true
+            if ((fFeatures & WELLFORMED) != 0) {
+                isTextWellFormed(node);
+            }
+
+            // if the node is whitespace
+            // Determine the Attr's type.
+            boolean isElementContentWhitespace = false;
+            if (fIsLevel3DOM) {
+                isElementContentWhitespace =
+                       node.isElementContentWhitespace();
+            }
+
+            if (isElementContentWhitespace) {
+                // element-content-whitespace=true
+                if ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) {
+                    bDispatch = true;
+                }
+            } else {
+                bDispatch = true;
+            }
+
+            // apply the LSSerializer filter
+            if (!applyFilter(node, NodeFilter.SHOW_TEXT)) {
+                return;
+            }
+
+            if (bDispatch) {
+                dispatachChars(node);
+            }
+        }
+    }
+
+    /**
+     * Serializes an EntityReference Node.
+     * 
+     * @param node The EntityReference Node to serialize
+     * @param bStart Inicates if called from start or endNode 
+     */
+    protected void serializeEntityReference(
+        EntityReference node,
+        boolean bStart)
+        throws SAXException {
+        if (bStart) {
+            EntityReference eref = node;
+            // entities=true
+            if ((fFeatures & ENTITIES) != 0) {
+                
+                // perform well-formedness and other checking only if 
+                // entities = true
+
+                // well-formed=true
+                if ((fFeatures & WELLFORMED) != 0) {
+                    isEntityReferneceWellFormed(node);
+                }
+
+                // check "unbound-prefix-in-entity-reference" [fatal] 
+                // Raised if the configuration parameter "namespaces" is set to true
+                if ((fFeatures & NAMESPACES) != 0) {
+                    checkUnboundPrefixInEntRef(node);
+                }
+
+                // The filter should not apply in this case, since the
+                // EntityReference is not being expanded.
+                // should we pass entity reference nodes to the filter???
+            } 
+            
+            if (fLexicalHandler != null) {
+
+                // startEntity outputs only Text but not Element, Attr, Comment 
+                // and PI child nodes.  It does so by setting the m_inEntityRef 
+                // in ToStream and using this to decide if a node is to be 
+                // serialized or not.
+                fLexicalHandler.startEntity(eref.getNodeName());
+            } 
+
+        } else {
+            EntityReference eref = node;
+            // entities=true or false, 
+            if (fLexicalHandler != null) {
+                fLexicalHandler.endEntity(eref.getNodeName());
+            }
+        }
+    }
+
+    
+    // ***********************************************************************
+    // Methods to check well-formedness
+    // ***********************************************************************
+    /**
+     * Taken from org.apache.xerces.dom.CoreDocumentImpl
+     * 
+     * Check the string against XML's definition of acceptable names for
+     * elements and attributes and so on using the XMLCharacterProperties
+     * utility class
+     */
+    protected boolean isXMLName(String s, boolean xml11Version) {
+
+        if (s == null) {
+            return false;
+        }
+        if (!xml11Version)
+            return XMLChar.isValidName(s);
+        else
+            return XML11Char.isXML11ValidName(s);
+    }
+
+    /**
+     * Taken from org.apache.xerces.dom.CoreDocumentImpl
+     *  
+     * Checks if the given qualified name is legal with respect
+     * to the version of XML to which this document must conform.
+     *
+     * @param prefix prefix of qualified name
+     * @param local local part of qualified name
+     */
+    protected boolean isValidQName(
+        String prefix,
+        String local,
+        boolean xml11Version) {
+
+        // check that both prefix and local part match NCName
+        if (local == null)
+            return false;
+        boolean validNCName = false;
+
+        if (!xml11Version) {
+            validNCName =
+                (prefix == null || XMLChar.isValidNCName(prefix))
+                    && XMLChar.isValidNCName(local);
+        } else {
+            validNCName =
+                (prefix == null || XML11Char.isXML11ValidNCName(prefix))
+                    && XML11Char.isXML11ValidNCName(local);
+        }
+
+        return validNCName;
+    }
+
+    /**
+     * Checks if a XML character is well-formed
+     * 
+     * @param characters A String of characters to be checked for Well-Formedness
+     * @param refInvalidChar A reference to the character to be returned that was determined invalid. 
+     */
+    protected boolean isWFXMLChar(String chardata, Character refInvalidChar) {
+        if (chardata == null || (chardata.length() == 0)) {
+            return true;
+        }
+
+        char[] dataarray = chardata.toCharArray();
+        int datalength = dataarray.length;
+
+        // version of the document is XML 1.1
+        if (fIsXMLVersion11) {
+            //we need to check all characters as per production rules of XML11
+            int i = 0;
+            while (i < datalength) {
+                if (XML11Char.isXML11Invalid(dataarray[i++])) {
+                    // check if this is a supplemental character
+                    char ch = dataarray[i - 1];
+                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
+                        char ch2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(ch2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(ch, ch2))) {
+                            continue;
+                        }
+                    }
+                    // Reference to invalid character which is returned
+                    refInvalidChar = new Character(ch);
+                    return false;
+                }
+            }
+        } // version of the document is XML 1.0
+        else {
+            // we need to check all characters as per production rules of XML 1.0
+            int i = 0;
+            while (i < datalength) {
+                if (XMLChar.isInvalid(dataarray[i++])) {
+                    // check if this is a supplemental character
+                    char ch = dataarray[i - 1];
+                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
+                        char ch2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(ch2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(ch, ch2))) {
+                            continue;
+                        }
+                    }
+                    // Reference to invalid character which is returned                    
+                    refInvalidChar = new Character(ch);
+                    return false;
+                }
+            }
+        } // end-else fDocument.isXMLVersion()
+
+        return true;
+    } // isXMLCharWF
+
+    /**
+     * Checks if a XML character is well-formed.  If there is a problem with
+     * the character a non-null Character is returned else null is returned.
+     * 
+     * @param characters A String of characters to be checked for Well-Formedness
+     * @return Character A reference to the character to be returned that was determined invalid. 
+     */
+    protected Character isWFXMLChar(String chardata) {
+    	Character refInvalidChar;
+        if (chardata == null || (chardata.length() == 0)) {
+            return null;
+        }
+
+        char[] dataarray = chardata.toCharArray();
+        int datalength = dataarray.length;
+
+        // version of the document is XML 1.1
+        if (fIsXMLVersion11) {
+            //we need to check all characters as per production rules of XML11
+            int i = 0;
+            while (i < datalength) {
+                if (XML11Char.isXML11Invalid(dataarray[i++])) {
+                    // check if this is a supplemental character
+                    char ch = dataarray[i - 1];
+                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
+                        char ch2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(ch2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(ch, ch2))) {
+                            continue;
+                        }
+                    }
+                    // Reference to invalid character which is returned
+                    refInvalidChar = new Character(ch);
+                    return refInvalidChar;
+                }
+            }
+        } // version of the document is XML 1.0
+        else {
+            // we need to check all characters as per production rules of XML 1.0
+            int i = 0;
+            while (i < datalength) {
+                if (XMLChar.isInvalid(dataarray[i++])) {
+                    // check if this is a supplemental character
+                    char ch = dataarray[i - 1];
+                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
+                        char ch2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(ch2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(ch, ch2))) {
+                            continue;
+                        }
+                    }
+                    // Reference to invalid character which is returned                    
+                    refInvalidChar = new Character(ch);
+                    return refInvalidChar;
+                }
+            }
+        } // end-else fDocument.isXMLVersion()
+
+        return null;
+    } // isXMLCharWF
+
+    /**
+     * Checks if a comment node is well-formed
+     * 
+     * @param data The contents of the comment node
+     * @return a boolean indiacating if the comment is well-formed or not.
+     */
+    protected void isCommentWellFormed(String data) {
+        if (data == null || (data.length() == 0)) {
+            return;
+        }
+
+        char[] dataarray = data.toCharArray();
+        int datalength = dataarray.length;
+
+        // version of the document is XML 1.1
+        if (fIsXMLVersion11) {
+            // we need to check all chracters as per production rules of XML11
+            int i = 0;
+            while (i < datalength) {
+                char c = dataarray[i++];
+                if (XML11Char.isXML11Invalid(c)) {
+                    // check if this is a supplemental character
+                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
+                        char c2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(c2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(c, c2))) {
+                            continue;
+                        }
+                    }
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                            new Object[] { new Character(c)});
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                msg,
+                                MsgKey.ER_WF_INVALID_CHARACTER,
+                                null,
+                                null,
+                                null));
+                    }
+                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_WF_DASH_IN_COMMENT,
+                            null);
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                msg,
+                                MsgKey.ER_WF_INVALID_CHARACTER,
+                                null,
+                                null,
+                                null));
+                    }
+                }
+            }
+        } // version of the document is XML 1.0
+        else {
+            // we need to check all chracters as per production rules of XML 1.0
+            int i = 0;
+            while (i < datalength) {
+                char c = dataarray[i++];
+                if (XMLChar.isInvalid(c)) {
+                    // check if this is a supplemental character
+                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
+                        char c2 = dataarray[i++];
+                        if (XMLChar.isLowSurrogate(c2)
+                            && XMLChar.isSupplemental(
+                                XMLChar.supplemental(c, c2))) {
+                            continue;
+                        }
+                    }
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                            new Object[] { new Character(c)});
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                msg,
+                                MsgKey.ER_WF_INVALID_CHARACTER,
+                                null,
+                                null,
+                                null));
+                    }
+                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_WF_DASH_IN_COMMENT,
+                            null);
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                msg,
+                                MsgKey.ER_WF_INVALID_CHARACTER,
+                                null,
+                                null,
+                                null));
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    /**
+     * Checks if an element node is well-formed, by checking its Name for well-formedness.
+     * 
+     * @param data The contents of the comment node
+     * @return a boolean indiacating if the comment is well-formed or not.
+     */
+    protected void isElementWellFormed(Node node) {
+        boolean isNameWF = false;
+        if ((fFeatures & NAMESPACES) != 0) {
+            isNameWF =
+                isValidQName(
+                    node.getPrefix(),
+                    node.getLocalName(),
+                    fIsXMLVersion11);
+        } else {
+            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
+        }
+
+        if (!isNameWF) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                    new Object[] { "Element", node.getNodeName()});
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                        null,
+                        null,
+                        null));
+            }
+        }
+    }
+
+    /**
+     * Checks if an attr node is well-formed, by checking it's Name and value
+     * for well-formedness.
+     * 
+     * @param data The contents of the comment node
+     * @return a boolean indiacating if the comment is well-formed or not.
+     */
+    protected void isAttributeWellFormed(Node node) {
+        boolean isNameWF = false;
+        if ((fFeatures & NAMESPACES) != 0) {
+            isNameWF =
+                isValidQName(
+                    node.getPrefix(),
+                    node.getLocalName(),
+                    fIsXMLVersion11);
+        } else {
+            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
+        }
+
+        if (!isNameWF) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                    new Object[] { "Attr", node.getNodeName()});
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                        null,
+                        null,
+                        null));
+            }
+        }
+
+        // Check the Attr's node value
+        // WFC: No < in Attribute Values
+        String value = node.getNodeValue();
+        if (value.indexOf('<') >= 0) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_LT_IN_ATTVAL,
+                    new Object[] {
+                        ((Attr) node).getOwnerElement().getNodeName(),
+                        node.getNodeName()});
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_LT_IN_ATTVAL,
+                        null,
+                        null,
+                        null));
+            }
+        }
+
+        // we need to loop through the children of attr nodes and check their values for
+        // well-formedness  
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            // An attribute node with no text or entity ref child for example
+            // doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns");
+            // followes by
+            // element.setAttributeNodeNS(attribute);
+            // can potentially lead to this situation.  If the attribute
+            // was a prefix Namespace attribute declaration then then DOM Core 
+            // should have some exception defined for this.
+            if (child == null) {
+                // we should probably report an error
+                continue;
+            }
+            switch (child.getNodeType()) {
+                case Node.TEXT_NODE :
+                    isTextWellFormed((Text) child);
+                    break;
+                case Node.ENTITY_REFERENCE_NODE :
+                    isEntityReferneceWellFormed((EntityReference) child);
+                    break;
+                default :
+            }
+        }
+
+        // TODO:
+        // WFC: Check if the attribute prefix is bound to 
+        // http://www.w3.org/2000/xmlns/  
+
+        // WFC: Unique Att Spec
+        // Perhaps pass a seen boolean value to this method.  serializeAttList will determine
+        // if the attr was seen before.
+    }
+
+    /**
+     * Checks if a PI node is well-formed, by checking it's Name and data
+     * for well-formedness.
+     * 
+     * @param data The contents of the comment node
+     */
+    protected void isPIWellFormed(ProcessingInstruction node) {
+        // Is the PI Target a valid XML name
+        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                    new Object[] { "ProcessingInstruction", node.getTarget()});
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                        null,
+                        null,
+                        null));
+            }
+        }
+
+        // Does the PI Data carry valid XML characters
+
+        // REVISIT: Should we check if the PI DATA contains a ?> ???
+        Character invalidChar = isWFXMLChar(node.getData());
+        if (invalidChar != null) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER,
+                        null,
+                        null,
+                        null));
+            }
+        }
+    }
+
+    /**
+     * Checks if an CDATASection node is well-formed, by checking it's data
+     * for well-formedness.  Note that the presence of a CDATA termination mark
+     * in the contents of a CDATASection is handled by the parameter 
+     * spli-cdata-sections
+     * 
+     * @param data The contents of the comment node
+     */
+    protected void isCDATASectionWellFormed(CDATASection node) {
+        // Does the data valid XML character data        
+        Character invalidChar = isWFXMLChar(node.getData());
+        //if (!isWFXMLChar(node.getData(), invalidChar)) {
+        if (invalidChar != null) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER,
+                        null,
+                        null,
+                        null));
+            }
+        }
+    }
+
+    /**
+     * Checks if an Text node is well-formed, by checking if it contains invalid
+     * XML characters.
+     * 
+     * @param data The contents of the comment node
+     */
+    protected void isTextWellFormed(Text node) {
+        // Does the data valid XML character data        
+    	Character invalidChar = isWFXMLChar(node.getData());
+    	if (invalidChar != null) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER,
+                        null,
+                        null,
+                        null));
+            }
+        }
+    }
+
+    /**
+     * Checks if an EntityRefernece node is well-formed, by checking it's node name.  Then depending
+     * on whether it is referenced in Element content or in an Attr Node, checks if the EntityReference
+     * references an unparsed entity or a external entity and if so throws raises the 
+     * appropriate well-formedness error.  
+     * 
+     * @param data The contents of the comment node
+     * @parent The parent of the EntityReference Node
+     */
+    protected void isEntityReferneceWellFormed(EntityReference node) {
+        // Is the EntityReference name a valid XML name
+        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
+            String msg =
+                Utils.messages.createMessage(
+                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                    new Object[] { "EntityReference", node.getNodeName()});
+
+            if (fErrorHandler != null) {
+                fErrorHandler.handleError(
+                    new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR,
+                        msg,
+                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                        null,
+                        null,
+                        null));
+            }
+        }
+
+        // determine the parent node
+        Node parent = node.getParentNode();
+
+        // Traverse the declared entities and check if the nodeName and namespaceURI
+        // of the EntityReference matches an Entity.  If so, check the if the notationName
+        // is not null, if so, report an error.
+        DocumentType docType = node.getOwnerDocument().getDoctype();
+        if (docType != null) {
+            NamedNodeMap entities = docType.getEntities();
+            for (int i = 0; i < entities.getLength(); i++) {
+                Entity ent = (Entity) entities.item(i);
+
+                String nodeName =
+                    node.getNodeName() == null ? "" : node.getNodeName();
+                String nodeNamespaceURI =
+                    node.getNamespaceURI() == null
+                        ? ""
+                        : node.getNamespaceURI();
+                String entName =
+                    ent.getNodeName() == null ? "" : ent.getNodeName();
+                String entNamespaceURI =
+                    ent.getNamespaceURI() == null ? "" : ent.getNamespaceURI();
+                // If referenced in Element content
+                // WFC: Parsed Entity
+                if (parent.getNodeType() == Node.ELEMENT_NODE) {
+                    if (entNamespaceURI.equals(nodeNamespaceURI)
+                        && entName.equals(nodeName)) {
+
+                        if (ent.getNotationName() != null) {
+                            String msg =
+                                Utils.messages.createMessage(
+                                    MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                                    new Object[] { node.getNodeName()});
+
+                            if (fErrorHandler != null) {
+                                fErrorHandler.handleError(
+                                    new DOMErrorImpl(
+                                        DOMError.SEVERITY_FATAL_ERROR,
+                                        msg,
+                                        MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                                        null,
+                                        null,
+                                        null));
+                            }
+                        }
+                    }
+                } // end if WFC: Parsed Entity
+
+                // If referenced in an Attr value
+                // WFC: No External Entity References
+                if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
+                    if (entNamespaceURI.equals(nodeNamespaceURI)
+                        && entName.equals(nodeName)) {
+
+                        if (ent.getPublicId() != null
+                            || ent.getSystemId() != null
+                            || ent.getNotationName() != null) {
+                            String msg =
+                                Utils.messages.createMessage(
+                                    MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                                    new Object[] { node.getNodeName()});
+
+                            if (fErrorHandler != null) {
+                                fErrorHandler.handleError(
+                                    new DOMErrorImpl(
+                                        DOMError.SEVERITY_FATAL_ERROR,
+                                        msg,
+                                        MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                                        null,
+                                        null,
+                                        null));
+                            }
+                        }
+                    }
+                } //end if WFC: No External Entity References
+            }
+        }
+    } // isEntityReferneceWellFormed    
+
+    /**
+     * If the configuration parameter "namespaces" is set to true, this methods
+     * checks if an entity whose replacement text contains unbound namespace 
+     * prefixes is referenced in a location where there are no bindings for 
+     * the namespace prefixes and if so raises a LSException with the error-type
+     * "unbound-prefix-in-entity-reference"   
+     * 
+     * @param Node, The EntityReference nodes whose children are to be checked
+     */
+    protected void checkUnboundPrefixInEntRef(Node node) {
+        Node child, next;
+        for (child = node.getFirstChild(); child != null; child = next) {
+            next = child.getNextSibling();
+
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+
+                //If a NamespaceURI is not declared for the current
+                //node's prefix, raise a fatal error.
+                String prefix = child.getPrefix();
+                if (prefix != null
+                		&& fNSBinder.getURI(prefix) == null) {
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                            new Object[] {
+                                node.getNodeName(),
+                                child.getNodeName(),
+                                prefix });
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                msg,
+                                MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                                null,
+                                null,
+                                null));
+                    }
+                }
+
+                NamedNodeMap attrs = child.getAttributes();
+
+                for (int i = 0; i < attrs.getLength(); i++) {
+                    String attrPrefix = attrs.item(i).getPrefix();
+                    if (attrPrefix != null
+                    		&& fNSBinder.getURI(attrPrefix) == null) {
+                        String msg =
+                            Utils.messages.createMessage(
+                                MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                                new Object[] {
+                                    node.getNodeName(),
+                                    child.getNodeName(),
+                                    attrs.item(i)});
+
+                        if (fErrorHandler != null) {
+                            fErrorHandler.handleError(
+                                new DOMErrorImpl(
+                                    DOMError.SEVERITY_FATAL_ERROR,
+                                    msg,
+                                    MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                                    null,
+                                    null,
+                                    null));
+                        }
+                    }
+                }
+            }
+
+            if (child.hasChildNodes()) {
+                checkUnboundPrefixInEntRef(child);
+            }
+        }
+    }
+
+    // ***********************************************************************
+    // Namespace normalization
+    // ***********************************************************************
+    /**
+     * Records local namespace declarations, to be used for normalization later
+     * 
+     * @param Node, The element node, whose namespace declarations are to be recorded
+     */
+    protected void recordLocalNSDecl(Node node) {
+        NamedNodeMap atts = ((Element) node).getAttributes();
+        int length = atts.getLength();
+
+        for (int i = 0; i < length; i++) {
+            Node attr = atts.item(i);
+
+            String localName = attr.getLocalName();
+            String attrPrefix = attr.getPrefix();
+            String attrValue = attr.getNodeValue();
+            String attrNS = attr.getNamespaceURI();
+
+            localName =
+                localName == null
+                    || XMLNS_PREFIX.equals(localName) ? "" : localName;
+            attrPrefix = attrPrefix == null ? "" : attrPrefix;
+            attrValue = attrValue == null ? "" : attrValue;
+            attrNS = attrNS == null ? "" : attrNS;
+
+            // check if attribute is a namespace decl
+            if (XMLNS_URI.equals(attrNS)) {
+
+                // No prefix may be bound to http://www.w3.org/2000/xmlns/.
+                if (XMLNS_URI.equals(attrValue)) {
+                    String msg =
+                        Utils.messages.createMessage(
+                            MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                            new Object[] { attrPrefix, XMLNS_URI });
+
+                    if (fErrorHandler != null) {
+                        fErrorHandler.handleError(
+                            new DOMErrorImpl(
+                                DOMError.SEVERITY_ERROR,
+                                msg,
+                                MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                                null,
+                                null,
+                                null));
+                    }
+                } else {
+                    // store the namespace-declaration
+                	if (XMLNS_PREFIX.equals(attrPrefix) ) {
+                        // record valid decl
+                        if (attrValue.length() != 0) {
+                            fNSBinder.declarePrefix(localName, attrValue);
+                        } else {
+                            // Error; xmlns:prefix=""
+                        }
+                    } else { // xmlns
+                        // empty prefix is always bound ("" or some string)
+                        fNSBinder.declarePrefix("", attrValue);
+                    }
+                }
+                
+            }
+        }
+    }
+
+    /**
+     * Fixes an element's namespace
+     * 
+     * @param Node, The element node, whose namespace is to be fixed
+     */
+    protected void fixupElementNS(Node node) throws SAXException {
+        String namespaceURI = ((Element) node).getNamespaceURI();
+        String prefix = ((Element) node).getPrefix();
+        String localName = ((Element) node).getLocalName();
+
+        if (namespaceURI != null) {
+            //if ( Element's prefix/namespace pair (or default namespace,
+            // if no prefix) are within the scope of a binding )
+            prefix = prefix == null ? "" : prefix;
+            String inScopeNamespaceURI = fNSBinder.getURI(prefix);
+
+            if ((inScopeNamespaceURI != null
+                && inScopeNamespaceURI.equals(namespaceURI))) {
+                // do nothing, declaration in scope is inherited
+                
+            } else {
+                // Create a local namespace declaration attr for this namespace,
+                // with Element's current prefix (or a default namespace, if
+                // no prefix). If there's a conflicting local declaration
+                // already present, change its value to use this namespace.
+                
+                // Add the xmlns declaration attribute
+            	//fNSBinder.pushNamespace(prefix, namespaceURI, fElementDepth);
+                if ((fFeatures & NAMESPACEDECLS) != 0) {
+                    if ("".equals(prefix) || "".equals(namespaceURI)) {
+                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceURI);
+                    } else {
+                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX + ":" + prefix, namespaceURI);
+                    }
+                }
+                fLocalNSBinder.declarePrefix(prefix, namespaceURI);
+                fNSBinder.declarePrefix(prefix, namespaceURI);
+
+            } 
+        } else {
+            // Element has no namespace
+            // DOM Level 1
+            if (localName == null || "".equals(localName)) {
+                //  DOM Level 1 node!
+                String msg =
+                    Utils.messages.createMessage(
+                        MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                        new Object[] { node.getNodeName()});
+
+                if (fErrorHandler != null) {
+                    fErrorHandler.handleError(
+                        new DOMErrorImpl(
+                            DOMError.SEVERITY_ERROR,
+                            msg,
+                            MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                            null,
+                            null,
+                            null));
+                }
+            } else {
+            	namespaceURI = fNSBinder.getURI("");
+            	if (namespaceURI !=null && namespaceURI.length() > 0) {
+            	    ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, "");
+            		fLocalNSBinder.declarePrefix("", "");
+                    fNSBinder.declarePrefix("", "");
+            	}
+            }
+        }
+    }
+    /** 
+     * This table is a quick lookup of a property key (String) to the integer that
+     * is the bit to flip in the fFeatures field, so the integers should have
+     * values 1,2,4,8,16...
+     * 
+     */
+    private static final Hashtable s_propKeys = new Hashtable();
+    static {
+
+        // Initialize the mappings of property keys to bit values (Integer objects)
+        // or mappings to a String object "", which indicates we are interested
+        // in the property, but it does not have a simple bit value to flip
+
+        // cdata-sections
+        int i = CDATA;
+        Integer val = new Integer(i);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_CDATA_SECTIONS,
+            val);
+
+        // comments
+        int i1 = COMMENTS;
+        val = new Integer(i1);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_COMMENTS,
+            val);
+
+        // element-content-whitespace
+        int i2 = ELEM_CONTENT_WHITESPACE;
+        val = new Integer(i2);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
+            val);
+        int i3 = ENTITIES;
+
+        // entities
+        val = new Integer(i3);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_ENTITIES,
+            val);
+
+        // namespaces
+        int i4 = NAMESPACES;
+        val = new Integer(i4);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_NAMESPACES,
+            val);
+
+        // namespace-declarations
+        int i5 = NAMESPACEDECLS;
+        val = new Integer(i5);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
+            val);
+
+        // split-cdata-sections
+        int i6 = SPLITCDATA;
+        val = new Integer(i6);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_SPLIT_CDATA,
+            val);
+
+        // discard-default-content	
+        int i7 = WELLFORMED;
+        val = new Integer(i7);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_WELLFORMED,
+            val);
+
+        // discard-default-content	
+        int i8 = DISCARDDEFAULT;
+        val = new Integer(i8);
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
+            val);
+
+        // We are interested in these properties, but they don't have a simple
+        // bit value to deal with.
+        s_propKeys.put(
+            DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_FORMAT_PRETTY_PRINT,
+            "");
+        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "");
+        s_propKeys.put(
+            DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION,
+            "");
+        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_ENCODING, "");
+        s_propKeys.put(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.DOM_ENTITIES, "");
+    }
+
+    /**
+     * Initializes fFeatures based on the DOMConfiguration Parameters set.
+     *
+     * @param properties DOMConfiguraiton properties that were set and which are
+     * to be used while serializing the DOM. 
+     */
+    protected void initProperties(Properties properties) {
+
+        for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {
+
+            final String key = (String) keys.nextElement();
+    
+            // caonical-form
+            // Other features will be enabled or disabled when this is set to true or false.
+
+            // error-handler; set via the constructor
+
+            // infoset
+            // Other features will be enabled or disabled when this is set to true
+
+            // A quick lookup for the given set of properties (cdata-sections ...)
+            final Object iobj = s_propKeys.get(key);
+            if (iobj != null) {
+                if (iobj instanceof Integer) {
+                    // Dealing with a property that has a simple bit value that
+                    // we need to set
+
+                    // cdata-sections			
+                    // comments
+                    // element-content-whitespace
+                    // entities
+                    // namespaces
+                    // namespace-declarations
+                    // split-cdata-sections
+                    // well-formed
+                    // discard-default-content
+                    final int BITFLAG = ((Integer) iobj).intValue();
+                    if ((properties.getProperty(key).endsWith("yes"))) {
+                        fFeatures = fFeatures | BITFLAG;
+                    } else {
+                        fFeatures = fFeatures & ~BITFLAG;
+                    }
+                } else {
+                    // We are interested in the property, but it is not
+                    // a simple bit that we need to set.
+
+                    if ((DOMConstants.S_DOM3_PROPERTIES_NS
+                        + DOMConstants.DOM_FORMAT_PRETTY_PRINT)
+                        .equals(key)) {
+                        // format-pretty-print; set internally on the serializers via xsl:output properties in LSSerializer
+                        if ((properties.getProperty(key).endsWith("yes"))) {
+                            fSerializer.setIndent(true);
+                            fSerializer.setIndentAmount(3);
+                        } else {
+                            fSerializer.setIndent(false);
+                        }
+                    } else if (
+                        (DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL).equals(
+                            key)) {
+                        // omit-xml-declaration; set internally on the serializers via xsl:output properties in LSSerializer
+                        if ((properties.getProperty(key).endsWith("yes"))) {
+                            fSerializer.setOmitXMLDeclaration(true);
+                        } else {
+                            fSerializer.setOmitXMLDeclaration(false);
+                        }
+                    } else if (
+                        (
+                            DOMConstants.S_XERCES_PROPERTIES_NS
+                                + DOMConstants.S_XML_VERSION).equals(
+                            key)) {
+                        // Retreive the value of the XML Version attribute via the xml-version
+                        String version = properties.getProperty(key);
+                        if ("1.1".equals(version)) {
+                            fIsXMLVersion11 = true;
+                            fSerializer.setVersion(version);
+                        } else {
+                            fSerializer.setVersion("1.0");
+                        }
+                    } else if (
+                        (DOMConstants.S_XSL_OUTPUT_ENCODING).equals(key)) {
+                        // Retreive the value of the XML Encoding attribute
+                        String encoding = properties.getProperty(key);
+                        if (encoding != null) {
+                            fSerializer.setEncoding(encoding);
+                        }
+                    } else if ((DOMConstants.S_XERCES_PROPERTIES_NS
+                            + DOMConstants.DOM_ENTITIES).equals(key)) {
+                        // Preserve entity references in the document
+                        if ((properties.getProperty(key).endsWith("yes"))) {
+                            fSerializer.setDTDEntityExpansion(false);
+                        }
+                        else {
+                            fSerializer.setDTDEntityExpansion(true);
+                        }
+                    } else {
+                        // We shouldn't get here, ever, now what?
+                    }
+                }
+            }
+        }
+        // Set the newLine character to use
+        if (fNewLine != null) {
+            fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR, fNewLine);
+        }
+    }
+
+} //TreeWalker
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMConstants.java b/src/main/java/org/apache/xml/serializer/dom3/DOMConstants.java
new file mode 100644
index 0000000..dae4f59
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMConstants.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+/**
+ * DOM Constants used by the DOM Level 3 LSSerializer implementation.
+ *
+ * @xsl.usage internal
+ */
+final class DOMConstants {
+    //
+    // Constants: DOM Level 3 feature ids
+    //
+    public static final String DOM3_REC_URL = "http://www.w3.org/TR/DOM-Level-3-LS";
+
+    public static final String XERCES_URL = "http://xml.apache.org/xerces-2j";
+
+    // The namespace used to qualified DOM Level 3 DOMConfiguration parameters
+    public static final String S_DOM3_PROPERTIES_NS = "{"
+            + DOMConstants.DOM3_REC_URL + "}";
+
+    public static final String S_XERCES_PROPERTIES_NS = "{"
+            + DOMConstants.XERCES_URL + "}";
+
+    // xmlns namespaces 
+    private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+
+    // namespace prefix
+    private static final String XMLNS_PREFIX = "xmlns";
+
+    // ************************************************************************
+    // DOM Level 3 DOM Configuration parameter names
+    // ************************************************************************
+    // DOM Level 3 parameters defined in Core
+    public static final String DOM_CANONICAL_FORM = "canonical-form"; // Unsupported, we only appear to support this
+
+    public static final String DOM_CDATA_SECTIONS = "cdata-sections";
+
+    public static final String DOM_CHECK_CHAR_NORMALIZATION = "check-character-normalization"; // Unsupported
+
+    public static final String DOM_COMMENTS = "comments";
+
+    public static final String DOM_DATATYPE_NORMALIZATION = "datatype-normalization"; // Unsupported
+
+    public static final String DOM_ELEMENT_CONTENT_WHITESPACE = "element-content-whitespace";
+
+    public static final String DOM_ENTITIES = "entities";
+
+    public static final String DOM_INFOSET = "infoset";
+
+    public static final String DOM_NAMESPACES = "namespaces";
+
+    public static final String DOM_NAMESPACE_DECLARATIONS = "namespace-declarations";
+
+    public static final String DOM_NORMALIZE_CHARACTERS = "normalize-characters"; // Unsupported
+
+    public static final String DOM_SPLIT_CDATA = "split-cdata-sections";
+
+    public static final String DOM_VALIDATE_IF_SCHEMA = "validate-if-schema"; // Unsopported
+
+    public static final String DOM_VALIDATE = "validate"; // Unsopported
+
+    public static final String DOM_WELLFORMED = "well-formed";
+
+    // DOM Level 3 Save
+    public static final String DOM_DISCARD_DEFAULT_CONTENT = "discard-default-content";
+
+    public static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
+
+    public static final String DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS = "ignore-unknown-character-denormalizations"; // Unsupported
+
+    public static final String DOM_XMLDECL = "xml-declaration";
+
+    // DOM Properties
+    public static final String DOM_ERROR_HANDLER = "error-handler";
+
+    public static final String DOM_SCHEMA_TYPE = "schema-type"; // Unsupported
+
+    public static final String DOM_SCHEMA_LOCATION = "schema-location"; // Unsupported
+
+    // ************************************************************************
+
+    // XSL Output properties
+    // The xsl:output 'indent' property used in LSSerializer 
+    public static final String S_XSL_OUTPUT_INDENT = "indent";
+
+    // The xsl:output 'indent' property used in LSSerializer 
+    public static final String S_XSL_OUTPUT_ENCODING = "encoding";
+
+    // The xsl:output 'omit-xml-declaration' property used in LSSerializer 
+    public static final String S_XSL_OUTPUT_OMIT_XML_DECL = "omit-xml-declaration";
+
+    // The xerces serializer specific 'omit-xml-declaration' property used in LSSerializer 
+    public static final String S_XML_VERSION = "xml-version";
+
+    //     
+    public static final String S_XSL_VALUE_ENTITIES = "org/apache/xml/serializer/XMLEntities";
+    
+    // Parameter values
+    public static final String DOM3_EXPLICIT_TRUE = "explicit:yes";
+
+    public static final String DOM3_DEFAULT_TRUE = "default:yes";
+
+    public static final String DOM3_EXPLICIT_FALSE = "explicit:no";
+
+    public static final String DOM3_DEFAULT_FALSE = "default:no";
+
+    // DOM Exceptions
+    public static final String DOM_EXCEPTION_FEATURE_NOT_FOUND = "FEATURE_NOT_FOUND";
+
+    public static final String DOM_EXCEPTION_FEATURE_NOT_SUPPORTED = "FEATURE_NOT_SUPPORTED";
+
+    public static final String DOM_LSEXCEPTION_SERIALIZER_ERR = "SERIALIZER_ERROR";
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMErrorHandlerImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOMErrorHandlerImpl.java
new file mode 100644
index 0000000..fd88266
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMErrorHandlerImpl.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+
+/**
+ * This is the default implementation of the ErrorHandler interface and is 
+ * used if one is not provided.  The default implementation simply reports
+ * DOMErrors to System.err.
+ * 
+ * @xsl.usage internal
+ */
+final class DOMErrorHandlerImpl implements DOMErrorHandler {
+    
+    /**
+     * Default Constructor 
+     */
+    DOMErrorHandlerImpl() {
+    }
+    
+    /**
+     * Implementation of DOMErrorHandler.handleError that
+     * adds copy of error to list for later retrieval.
+     *
+     */
+    public boolean handleError(DOMError error) {
+        boolean fail = true;
+        String severity = null;
+        if (error.getSeverity() == DOMError.SEVERITY_WARNING) {
+            fail = false;
+            severity = "[Warning]";
+        } else if (error.getSeverity() == DOMError.SEVERITY_ERROR) {
+            severity = "[Error]";
+        } else if (error.getSeverity() == DOMError.SEVERITY_FATAL_ERROR) {
+            severity = "[Fatal Error]";
+        }
+        
+        System.err.println(severity + ": " + error.getMessage() + "\t");
+        System.err.println("Type : " + error.getType() + "\t" + "Related Data: "
+                + error.getRelatedData() + "\t" + "Related Exception: "
+                + error.getRelatedException() );
+        
+        return fail;
+    }
+}
+
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMErrorImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOMErrorImpl.java
new file mode 100644
index 0000000..3895a53
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMErrorImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMLocator;
+
+/**
+ * Implementation of the DOM Level 3 DOMError interface.
+ *
+ * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ERROR-Interfaces-DOMError'>DOMError Interface definition from Document Object Model (DOM) Level 3 Core Specification</a>.
+ * 
+ * @xsl.usage internal 
+ */
+
+public final class DOMErrorImpl implements DOMError {
+    
+    /** private data members */
+    
+    // The DOMError Severity
+    private short fSeverity = DOMError.SEVERITY_WARNING;
+    
+    // The Error message
+    private String fMessage = null;
+    
+    //  A String indicating which related data is expected in relatedData. 
+    private String fType;
+    
+    // The platform related exception
+    private Exception fException = null;
+    
+    //  
+    private Object fRelatedData;
+    
+    // The location of the exception
+    private DOMLocatorImpl fLocation = new DOMLocatorImpl();
+    
+    
+    //
+    // Constructors
+    //
+    
+    /** 
+     * Default constructor. 
+     */    
+    DOMErrorImpl () {
+    }
+    
+    /**
+     * @param severity
+     * @param message
+     * @param type
+     */
+    public DOMErrorImpl(short severity, String message, String type) {
+        fSeverity = severity;
+        fMessage = message;
+        fType = type;
+    }
+    
+    /**
+     * @param severity
+     * @param message
+     * @param type
+     * @param exception
+     */
+    public DOMErrorImpl(short severity, String message, String type,
+            Exception exception) {
+        fSeverity = severity;
+        fMessage = message;
+        fType = type;
+        fException = exception;
+    }
+    
+    /**
+     * @param severity
+     * @param message
+     * @param type
+     * @param exception
+     * @param relatedData
+     * @param location
+     */
+    public DOMErrorImpl(short severity, String message, String type,
+            Exception exception, Object relatedData, DOMLocatorImpl location) {
+        fSeverity = severity;
+        fMessage = message;
+        fType = type;
+        fException = exception;
+        fRelatedData = relatedData;
+        fLocation = location;
+    }
+    
+    
+    /**
+     * The severity of the error, either <code>SEVERITY_WARNING</code>, 
+     * <code>SEVERITY_ERROR</code>, or <code>SEVERITY_FATAL_ERROR</code>.
+     * 
+     * @return A short containing the DOMError severity
+     */
+    public short getSeverity() {
+        return fSeverity;
+    }
+    
+    /**
+     * The DOMError message string.
+     * 
+     * @return String
+     */
+    public String getMessage() {
+        return fMessage;
+    }
+    
+    /**
+     * The location of the DOMError.
+     * 
+     * @return A DOMLocator object containing the DOMError location.
+     */
+    public DOMLocator getLocation() {
+        return fLocation;
+    }
+    
+    /**
+     * The related platform dependent exception if any.
+     * 
+     * @return A java.lang.Exception 
+     */
+    public Object getRelatedException(){
+        return fException;
+    }
+    
+    /**
+     * Returns a String indicating which related data is expected in relatedData.
+     * 
+     * @return A String
+     */
+    public String getType(){
+        return fType;
+    }
+    
+    /**
+     * The related DOMError.type dependent data if any.
+     * 
+     * @return java.lang.Object 
+     */
+    public Object getRelatedData(){
+        return fRelatedData;
+    }
+    
+    public void reset(){
+        fSeverity = DOMError.SEVERITY_WARNING; 
+        fException = null;
+        fMessage = null;
+        fType = null;
+        fRelatedData = null;
+        fLocation = null;        
+    }
+    
+}// class DOMErrorImpl
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMLocatorImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOMLocatorImpl.java
new file mode 100644
index 0000000..8add00c
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMLocatorImpl.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import org.w3c.dom.DOMLocator;
+import org.w3c.dom.Node;
+
+
+/**
+ * <code>DOMLocatorImpl</code> is an implementaion that describes a location (e.g. 
+ * where an error occured).
+ * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>.
+ * This class is a copy of the Xerces-2J class org.apache.xerces.dom.DOMLocatorImpl.java v 1.10 
+ *
+ * @author Gopal Sharma, SUN Microsystems Inc.
+ * @version $Id: 
+ * 
+ * @xsl.usage internal
+ */
+final class DOMLocatorImpl implements DOMLocator {
+    
+    //
+    // Data
+    //
+    
+    /**
+     * The column number where the error occured, 
+     * or -1 if there is no column number available.
+     */
+    private final int fColumnNumber;
+    
+    /**
+     * The line number where the error occured, 
+     * or -1 if there is no line number available.
+     */
+    private final int fLineNumber;
+    
+    /** related data node*/
+    private final Node fRelatedNode;
+    
+    /**
+     * The URI where the error occured, 
+     * or null if there is no URI available.
+     */
+    private final String fUri;
+    
+    /**
+     * The byte offset into the input source this locator is pointing to or -1 
+     * if there is no byte offset available
+     */
+    private final int fByteOffset;
+    
+    /**
+     * The UTF-16, as defined in [Unicode] and Amendment 1 of [ISO/IEC 10646], 
+     * offset into the input source this locator is pointing to or -1 if there 
+     * is no UTF-16 offset available.
+     */
+    private final int fUtf16Offset;
+    
+    //
+    // Constructors
+    //
+    
+    DOMLocatorImpl(){
+        fColumnNumber = -1;
+        fLineNumber = -1;
+        fRelatedNode = null;
+        fUri = null;
+        fByteOffset = -1;
+        fUtf16Offset = -1;
+    }
+    
+    DOMLocatorImpl (int lineNumber, int columnNumber, String uri ){
+        fLineNumber = lineNumber ;
+        fColumnNumber = columnNumber ;
+        fUri = uri;
+        
+        fRelatedNode = null;
+        fByteOffset = -1;
+        fUtf16Offset = -1;
+    } // DOMLocatorImpl (int lineNumber, int columnNumber, String uri )
+    
+    DOMLocatorImpl (int lineNumber, int columnNumber, int utf16Offset, String uri ){
+        fLineNumber = lineNumber ;
+        fColumnNumber = columnNumber ;
+        fUri = uri;
+        fUtf16Offset = utf16Offset;
+        
+
+        fRelatedNode = null;
+        fByteOffset = -1;
+    } // DOMLocatorImpl (int lineNumber, int columnNumber, int utf16Offset, String uri )
+    
+    DOMLocatorImpl (int lineNumber, int columnNumber, int byteoffset, Node relatedData, String uri ){
+        fLineNumber = lineNumber ;
+        fColumnNumber = columnNumber ;
+        fByteOffset = byteoffset ;
+        fRelatedNode = relatedData ;
+        fUri = uri;
+        
+        fUtf16Offset = -1;
+    } // DOMLocatorImpl (int lineNumber, int columnNumber, int offset, Node errorNode, String uri )
+    
+    DOMLocatorImpl (int lineNumber, int columnNumber, int byteoffset, Node relatedData, String uri, int utf16Offset ){
+        fLineNumber = lineNumber ;
+        fColumnNumber = columnNumber ;
+        fByteOffset = byteoffset ;
+        fRelatedNode = relatedData ;
+        fUri = uri;
+        fUtf16Offset = utf16Offset;
+    } // DOMLocatorImpl (int lineNumber, int columnNumber, int offset, Node errorNode, String uri )
+    
+    
+    /**
+     * The line number where the error occured, or -1 if there is no line 
+     * number available.
+     */
+    public int getLineNumber(){
+        return fLineNumber;
+    }
+    
+    /**
+     * The column number where the error occured, or -1 if there is no column 
+     * number available.
+     */
+    public int getColumnNumber(){
+        return fColumnNumber;
+    }
+    
+    
+    /**
+     * The URI where the error occured, or null if there is no URI available.
+     */
+    public String getUri(){
+        return fUri;
+    }
+    
+    
+    public Node getRelatedNode(){
+        return fRelatedNode;
+    }
+    
+    
+    /**
+     * The byte offset into the input source this locator is pointing to or -1 
+     * if there is no byte offset available
+     */
+    public int getByteOffset(){
+        return fByteOffset;
+    }
+    
+    /**
+     * The UTF-16, as defined in [Unicode] and Amendment 1 of [ISO/IEC 10646], 
+     * offset into the input source this locator is pointing to or -1 if there 
+     * is no UTF-16 offset available.
+     */
+    public int getUtf16Offset(){
+        return fUtf16Offset;
+    }
+    
+}// class DOMLocatorImpl
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMOutputImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOMOutputImpl.java
new file mode 100644
index 0000000..54327c0
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMOutputImpl.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import org.w3c.dom.ls.LSOutput;
+
+import java.io.Writer;
+import java.io.OutputStream;
+
+/**
+ * This is a copy of the Xerces-2J class org.apache.xerces.dom.DOMOutputImpl.java
+ * 
+ * This class represents an output destination for data.
+ * This interface allows an application to encapsulate information about an
+ * output destination in a single object, which may include a URI, a byte stream
+ * (possibly with a specifiedencoding), a base URI, and/or a character stream.
+ * The exact definitions of a byte stream and a character stream are binding
+ * dependent.
+ * The application is expected to provide objects that implement this interface
+ * whenever such objects are needed. The application can either provide its
+ * own objects that implement this interface, or it can use the generic factory
+ * method DOMImplementationLS.createLSOutput() to create objects that
+ * implement this interface.
+ * The DOMSerializer will use the LSOutput object to determine where to
+ * serialize the output to. The DOMSerializer will look at the different
+ * outputs specified in the LSOutput in the following order to know which one
+ * to output to, the first one that data can be output to will be used:
+ * 1.LSOutput.characterStream
+ * 2.LSOutput.byteStream
+ * 3.LSOutput.systemId
+ * LSOutput objects belong to the application. The DOM implementation will
+ * never modify them (though it may make copies and modify the copies,
+ * if necessary).
+ *
+ *
+ * @author Arun Yadav, Sun Microsytems
+ * @author Gopal Sharma, Sun Microsystems
+ * @version $Id : 
+ * @xsl.usage internal 
+ */
+
+final class DOMOutputImpl implements LSOutput {
+    
+    private Writer fCharStream = null;
+    private OutputStream fByteStream = null;
+    private String fSystemId = null;
+    private String fEncoding = null;
+    
+    /**
+     * Default Constructor
+     */
+    DOMOutputImpl() {}
+    
+    /**
+     * An attribute of a language and binding dependent type that represents a
+     * writable stream of bytes. If the application knows the character encoding
+     * of the byte stream, it should set the encoding attribute. Setting the
+     * encoding in this way will override any encoding specified in an XML
+     * declaration in the data.
+     */
+    
+    public Writer getCharacterStream(){
+        return fCharStream;
+    };
+    
+    /**
+     * An attribute of a language and binding dependent type that represents a
+     * writable stream of bytes. If the application knows the character encoding
+     * of the byte stream, it should set the encoding attribute. Setting the
+     * encoding in this way will override any encoding specified in an XML
+     * declaration in the data.
+     */
+    
+    public void setCharacterStream(Writer characterStream){
+        fCharStream = characterStream;
+    };
+    
+    /**
+     * Depending on the language binding in use, this attribute may not be
+     * available. An attribute of a language and binding dependent type that
+     * represents a writable stream to which 16-bit units can be output. The
+     * application must encode the stream using UTF-16 (defined in [Unicode] and
+     *  Amendment 1 of [ISO/IEC 10646]).
+     */
+    
+    public OutputStream getByteStream(){
+        return fByteStream;
+    };
+    
+    /**
+     * Depending on the language binding in use, this attribute may not be
+     * available. An attribute of a language and binding dependent type that
+     * represents a writable stream to which 16-bit units can be output. The
+     * application must encode the stream using UTF-16 (defined in [Unicode] and
+     *  Amendment 1 of [ISO/IEC 10646]).
+     */
+    
+    public void setByteStream(OutputStream byteStream){
+        fByteStream = byteStream;
+    };
+    
+    /**
+     * The system identifier, a URI reference [IETF RFC 2396], for this output
+     *  destination. If the application knows the character encoding of the
+     *  object pointed to by the system identifier, it can set the encoding
+     *  using the encoding attribute. If the system ID is a relative URI
+     *  reference (see section 5 in [IETF RFC 2396]), the behavior is
+     *  implementation dependent.
+     */
+    
+    public String getSystemId(){
+        return fSystemId;
+    };
+    
+    /**
+     * The system identifier, a URI reference [IETF RFC 2396], for this output
+     *  destination. If the application knows the character encoding of the
+     *  object pointed to by the system identifier, it can set the encoding
+     *  using the encoding attribute. If the system ID is a relative URI
+     *  reference (see section 5 in [IETF RFC 2396]), the behavior is
+     *  implementation dependent.
+     */
+    
+    public void setSystemId(String systemId){
+        fSystemId = systemId;
+    };
+    
+    /**
+     * The character encoding, if known. The encoding must be a string
+     * acceptable for an XML encoding declaration ([XML 1.0] section 4.3.3
+     * "Character Encoding in Entities"). This attribute has no effect when the
+     * application provides a character stream or string data. For other sources
+     * of input, an encoding specified by means of this attribute will override
+     * any encoding specified in the XML declaration or the Text declaration, or
+     * an encoding obtained from a higher level protocol, such as HTTP
+     * [IETF RFC 2616].
+     */
+    
+    public String getEncoding(){
+        return fEncoding;
+    };
+    
+    /**
+     * The character encoding, if known. The encoding must be a string
+     * acceptable for an XML encoding declaration ([XML 1.0] section 4.3.3
+     * "Character Encoding in Entities"). This attribute has no effect when the
+     * application provides a character stream or string data. For other sources
+     * of input, an encoding specified by means of this attribute will override
+     * any encoding specified in the XML declaration or the Text declaration, or
+     * an encoding obtained from a higher level protocol, such as HTTP
+     * [IETF RFC 2616].
+     */
+    
+    public void setEncoding(String encoding){
+        fEncoding = encoding;
+    };
+    
+}//DOMOutputImpl
diff --git a/src/main/java/org/apache/xml/serializer/dom3/DOMStringListImpl.java b/src/main/java/org/apache/xml/serializer/dom3/DOMStringListImpl.java
new file mode 100644
index 0000000..5ace83a
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/DOMStringListImpl.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+package org.apache.xml.serializer.dom3;
+
+import java.util.Vector;
+
+//import org.apache.xerces.dom3.DOMStringList;
+import org.w3c.dom.DOMStringList;
+
+/**
+ * This class implemets the DOM Level 3 Core interface DOMStringList.
+ * 
+ * @xsl.usage internal
+ */
+final class DOMStringListImpl implements DOMStringList {
+    
+    //A collection of DOMString values
+    private Vector fStrings;
+    
+    /** 
+     * Construct an empty list of DOMStringListImpl
+     */ 
+    DOMStringListImpl() {
+        fStrings = new Vector();    
+    }
+    
+    /** 
+     * Construct an empty list of DOMStringListImpl
+     */ 
+    DOMStringListImpl(Vector params) {
+        fStrings = params;    
+    }
+    
+    /** 
+     * Construct an empty list of DOMStringListImpl
+     */ 
+    DOMStringListImpl(String[] params ) {
+        fStrings = new Vector();
+        if (params != null) {
+            for (int i=0; i < params.length; i++) {
+                fStrings.add(params[i]);    
+            }
+        }
+    }
+    
+    /**
+     * @see org.apache.xerces.dom3.DOMStringList#item(int)
+     */
+    public String item(int index) {
+        try {
+            return (String) fStrings.elementAt(index);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            return null;
+        }
+    }
+    
+    /**
+     * @see org.apache.xerces.dom3.DOMStringList#getLength()
+     */
+    public int getLength() {
+        return fStrings.size();
+    }
+    
+    /**
+     * @see org.apache.xerces.dom3.DOMStringList#contains(String)
+     */
+    public boolean contains(String param) {
+        return fStrings.contains(param) ;
+    }
+    
+    /**
+     * DOM Internal:
+     * Add a <code>DOMString</code> to the list.
+     * 
+     * @param domString A string to add to the list
+     */
+    public void add(String param) {
+        fStrings.add(param);
+    }
+    
+}
diff --git a/src/main/java/org/apache/xml/serializer/dom3/LSSerializerImpl.java b/src/main/java/org/apache/xml/serializer/dom3/LSSerializerImpl.java
new file mode 100644
index 0000000..acac6fc
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/LSSerializerImpl.java
@@ -0,0 +1,1537 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.xml.serializer.DOM3Serializer;
+import org.apache.xml.serializer.Encodings;
+import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.SystemIDResolver;
+import org.apache.xml.serializer.utils.Utils;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMStringList;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+import org.w3c.dom.ls.LSSerializerFilter;
+
+/**
+ * Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer and 
+ * org.w3c.dom.ls.DOMConfiguration.  Serialization is achieved by delegating 
+ * serialization calls to <CODE>org.apache.xml.serializer.ToStream</CODE> or 
+ * one of its derived classes depending on the serialization method, while walking
+ * the DOM in DOM3TreeWalker.  
+ * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSSerializer">org.w3c.dom.ls.LSSerializer</a>
+ * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration">org.w3c.dom.DOMConfiguration</a>
+ *  
+ * @version $Id:  
+ * 
+ * @xsl.usage internal 
+ */
+final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
+    
+    // The default end-of-line character sequence used in serialization.
+    private static final String DEFAULT_END_OF_LINE;
+    static {
+        String lineSeparator = (String) AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                try {
+                    return System.getProperty("line.separator");
+                }
+                catch (SecurityException ex) {}
+                return null;
+            }
+        });
+        // The DOM Level 3 Load and Save specification requires that implementations choose a default
+        // sequence which matches one allowed by XML 1.0 (or XML 1.1). If the value of "line.separator" 
+        // isn't one of the XML 1.0 end-of-line sequences then we select "\n" as the default value.
+        DEFAULT_END_OF_LINE = lineSeparator != null && 
+            (lineSeparator.equals("\r\n") || lineSeparator.equals("\r")) ? lineSeparator : "\n";
+    }
+    
+    /** private data members */
+    private Serializer fXMLSerializer = null;
+    
+    // Tracks DOMConfiguration features. 
+    protected int fFeatures = 0;
+    
+    // Common DOM serializer
+    private  DOM3Serializer fDOMSerializer = null;
+    
+    // A filter set on the LSSerializer
+    private LSSerializerFilter fSerializerFilter = null;  
+    
+    // Stores the nodeArg parameter to speed up multiple writes of the same node.
+    private Node fVisitedNode = null;
+    
+    // The end-of-line character sequence used in serialization. "\n" is whats used on the web.
+    private String fEndOfLine = DEFAULT_END_OF_LINE;
+    
+    // The DOMErrorhandler.
+    private DOMErrorHandler fDOMErrorHandler = null;
+    
+    // The Configuration parameter to pass to the Underlying serilaizer.
+    private Properties fDOMConfigProperties = null;
+    
+    // The encoding to use during serialization.
+    private String fEncoding; 
+	
+    // ************************************************************************
+    // DOM Level 3 DOM Configuration parameter names
+    // ************************************************************************    
+    // Parameter canonical-form, true [optional] - NOT SUPPORTED 
+    private final static int CANONICAL = 0x1 << 0;
+    
+    // Parameter cdata-sections, true [required] (default)
+    private final static int CDATA = 0x1 << 1;
+    
+    // Parameter check-character-normalization, true [optional] - NOT SUPPORTED 
+    private final static int CHARNORMALIZE = 0x1 << 2;
+    
+    // Parameter comments, true [required] (default)
+    private final static int COMMENTS = 0x1 << 3;
+    
+    // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
+    private final static int DTNORMALIZE = 0x1 << 4;    
+    
+    // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
+    private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;
+    
+    // Parameter entities, true [required] (default)
+    private final static int ENTITIES = 0x1 << 6;
+    
+    // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
+    private final static int INFOSET = 0x1 << 7;
+    
+    // Parameter namespaces, true [required] (default)
+    private final static int NAMESPACES = 0x1 << 8;
+    
+    // Parameter namespace-declarations, true [required] (default)
+    private final static int NAMESPACEDECLS = 0x1 << 9;
+    
+    // Parameter normalize-characters, true [optional] - NOT SUPPORTED
+    private final static int NORMALIZECHARS = 0x1 << 10;
+    
+    // Parameter split-cdata-sections, true [required] (default)
+    private final static int SPLITCDATA = 0x1 << 11;   
+    
+    // Parameter validate, true [optional] - NOT SUPPORTED
+    private final static int VALIDATE = 0x1 << 12;   
+    
+    // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
+    private final static int SCHEMAVALIDATE = 0x1 << 13;
+    
+    // Parameter split-cdata-sections, true [required] (default)
+    private final static int WELLFORMED = 0x1 << 14;   
+    
+    // Parameter discard-default-content, true [required] (default)
+    // Not sure how this will be used in level 2 Documents
+    private final static int DISCARDDEFAULT = 0x1 << 15;       
+    
+    // Parameter format-pretty-print, true [optional] 
+    private final static int PRETTY_PRINT = 0x1 << 16;
+    
+    // Parameter ignore-unknown-character-denormalizations, true [required] (default)
+    // We currently do not support XML 1.1 character normalization
+    private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;
+    
+    // Parameter discard-default-content, true [required] (default)
+    private final static int XMLDECL = 0x1 << 18;    
+    // ************************************************************************
+    
+    // Recognized parameters for which atleast one value can be set
+    private String fRecognizedParameters [] = {
+            DOMConstants.DOM_CANONICAL_FORM,
+            DOMConstants.DOM_CDATA_SECTIONS,
+            DOMConstants.DOM_CHECK_CHAR_NORMALIZATION,
+            DOMConstants.DOM_COMMENTS,
+            DOMConstants.DOM_DATATYPE_NORMALIZATION,
+            DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
+            DOMConstants.DOM_ENTITIES,
+            DOMConstants.DOM_INFOSET,
+            DOMConstants.DOM_NAMESPACES,
+            DOMConstants.DOM_NAMESPACE_DECLARATIONS,
+            //DOMConstants.DOM_NORMALIZE_CHARACTERS,
+            DOMConstants.DOM_SPLIT_CDATA,
+            DOMConstants.DOM_VALIDATE,
+            DOMConstants.DOM_VALIDATE_IF_SCHEMA,
+            DOMConstants.DOM_WELLFORMED,
+            DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
+            DOMConstants.DOM_FORMAT_PRETTY_PRINT,
+            DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS,
+            DOMConstants.DOM_XMLDECL,
+            DOMConstants.DOM_ERROR_HANDLER
+    };
+    
+    
+    /**
+     * Constructor:  Creates a LSSerializerImpl object.  The underlying
+     * XML 1.0 or XML 1.1 org.apache.xml.serializer.Serializer object is
+     * created and initialized the first time any of the write methods are  
+     * invoked to serialize the Node.  Subsequent write methods on the same
+     * LSSerializerImpl object will use the previously created Serializer object.
+     */
+    public LSSerializerImpl () {
+        // set default parameters
+        fFeatures |= CDATA;
+        fFeatures |= COMMENTS;
+        fFeatures |= ELEM_CONTENT_WHITESPACE;
+        fFeatures |= ENTITIES;
+        fFeatures |= NAMESPACES;
+        fFeatures |= NAMESPACEDECLS;
+        fFeatures |= SPLITCDATA;
+        fFeatures |= WELLFORMED;
+        fFeatures |= DISCARDDEFAULT;
+        fFeatures |= XMLDECL;
+        
+        // New OutputFormat properties
+        fDOMConfigProperties = new Properties();
+        
+        // Initialize properties to be passed on the underlying serializer
+        initializeSerializerProps();
+        
+        // Create the underlying serializer.
+        Properties  configProps = OutputPropertiesFactory.getDefaultMethodProperties("xml");
+        
+        // change xml version from 1.0 to 1.1
+        //configProps.setProperty("version", "1.1");
+        
+        // Get a serializer that seriailizes according the the properties,
+        // which in this case is to xml
+        fXMLSerializer = SerializerFactory.getSerializer(configProps);
+        
+        // Initialize Serializer
+        fXMLSerializer.setOutputFormat(fDOMConfigProperties);
+    }
+    
+    /**
+     * Initializes the underlying serializer's configuration depending on the
+     * default DOMConfiguration parameters. This method must be called before a
+     * node is to be serialized.
+     * 
+     * @xsl.usage internal
+     */
+    public void initializeSerializerProps () {
+        // canonical-form
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_DEFAULT_FALSE);
+        
+        // cdata-sections
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // "check-character-normalization"
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION,
+                DOMConstants.DOM3_DEFAULT_FALSE);
+        
+        // comments
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // datatype-normalization
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_DATATYPE_NORMALIZATION,
+                DOMConstants.DOM3_DEFAULT_FALSE);
+        
+        // element-content-whitespace
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
+                DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // entities
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_TRUE);
+        // preserve entities
+        fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS
+                + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_TRUE);
+
+        // error-handler
+        // Should we set our default ErrorHandler
+        /*
+         * if (fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER) != null) {
+         * fDOMErrorHandler =
+         * (DOMErrorHandler)fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER); }
+         */
+        
+        // infoset
+        if ((fFeatures & INFOSET) != 0) {
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
+                    DOMConstants.DOM3_DEFAULT_TRUE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
+                    DOMConstants.DOM3_DEFAULT_TRUE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_FALSE);
+            // preserve entities
+            fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS
+                    + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_FALSE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_CDATA_SECTIONS,
+                    DOMConstants.DOM3_DEFAULT_FALSE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_VALIDATE_IF_SCHEMA,
+                    DOMConstants.DOM3_DEFAULT_FALSE);
+            fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                    + DOMConstants.DOM_DATATYPE_NORMALIZATION,
+                    DOMConstants.DOM3_DEFAULT_FALSE);
+        }
+        
+        // namespaces
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // namespace-declarations
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
+                DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // normalize-characters
+        /*
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_NORMALIZE_CHARACTERS,
+                DOMConstants.DOM3_DEFAULT_FALSE);
+        */
+        
+        // split-cdata-sections
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // validate
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_DEFAULT_FALSE);
+        
+        // validate-if-schema
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_VALIDATE_IF_SCHEMA,
+                DOMConstants.DOM3_DEFAULT_FALSE);
+        
+        // well-formed
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // pretty-print
+        fDOMConfigProperties.setProperty(
+                DOMConstants.S_XSL_OUTPUT_INDENT,
+                DOMConstants.DOM3_DEFAULT_TRUE);
+        fDOMConfigProperties.setProperty(
+                OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, Integer.toString(3));
+        
+        // 
+        
+        // discard-default-content
+        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
+                + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
+                DOMConstants.DOM3_DEFAULT_TRUE);
+        
+        // xml-declaration
+        fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no");
+        
+    }    
+    
+    // ************************************************************************
+    // DOMConfiguraiton implementation
+    // ************************************************************************
+    
+    /** 
+     * Checks if setting a parameter to a specific value is supported.    
+     *  
+     * @see org.w3c.dom.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object)
+     * @since DOM Level 3
+     * @param name A String containing the DOMConfiguration parameter name.
+     * @param value An Object specifying the value of the corresponding parameter. 
+     */
+    public boolean canSetParameter(String name, Object value) {
+        if (value instanceof Boolean){
+            if ( name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)    
+                    || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)    
+                    || name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)                
+                    || name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)){
+                // both values supported
+                return true;
+            }
+            else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
+                    // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
+                    ) {
+                // true is not supported
+                return !((Boolean)value).booleanValue();
+            }
+            else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+                // false is not supported
+                return ((Boolean)value).booleanValue();
+            }
+        }
+        else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) &&
+                value == null || value instanceof DOMErrorHandler){
+            return true;
+        }
+        return false;
+    }
+    /**
+     * This method returns the value of a parameter if known.
+     * 
+     * @see org.w3c.dom.DOMConfiguration#getParameter(java.lang.String)
+     * 
+     * @param name A String containing the DOMConfiguration parameter name 
+     *             whose value is to be returned.
+     * @return Object The value of the parameter if known. 
+     */
+    public Object getParameter(String name) throws DOMException {
+        if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) {
+            return ((fFeatures & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) {
+            return ((fFeatures & CDATA) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) {
+            return ((fFeatures & ENTITIES) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) {
+            return ((fFeatures & NAMESPACES) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) {
+            return ((fFeatures & NAMESPACEDECLS) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) {
+            return ((fFeatures & SPLITCDATA) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) {
+            return ((fFeatures & WELLFORMED) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        }  else if (name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) {
+            return ((fFeatures & DISCARDDEFAULT) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
+            return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) {
+            return ((fFeatures & XMLDECL) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
+            return ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
+            return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+            return Boolean.TRUE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
+                || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
+                || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) 
+                // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)                
+                || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
+                || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
+            return Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)){
+            if ((fFeatures & ENTITIES) == 0 &&
+                    (fFeatures & CDATA) == 0 &&
+                    (fFeatures & ELEM_CONTENT_WHITESPACE) != 0 &&
+                    (fFeatures & NAMESPACES) != 0 &&
+                    (fFeatures & NAMESPACEDECLS) != 0 &&
+                    (fFeatures & WELLFORMED) != 0 &&
+                    (fFeatures & COMMENTS) != 0) {
+                return Boolean.TRUE;
+            }                 
+            return Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) {
+            return fDOMErrorHandler;
+        } else if (
+                name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION)
+                || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) {
+            return null;
+        } else {
+            // Here we have to add the Xalan specific DOM Message Formatter
+            String msg = Utils.messages.createMessage(
+                    MsgKey.ER_FEATURE_NOT_FOUND,
+                    new Object[] { name });
+            throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+        }
+    }
+    
+    /**
+     * This method returns a of the parameters supported by this DOMConfiguration object 
+     * and for which at least one value can be set by the application
+     * 
+     * @see org.w3c.dom.DOMConfiguration#getParameterNames()
+     * 
+     * @return DOMStringList A list of DOMConfiguration parameters recognized
+     *                       by the serializer
+     */
+    public DOMStringList getParameterNames() {
+        return new DOMStringListImpl(fRecognizedParameters);
+    }
+    
+    /**
+     * This method sets the value of the named parameter.
+     *   
+     * @see org.w3c.dom.DOMConfiguration#setParameter(java.lang.String, java.lang.Object)
+     * 
+     * @param name A String containing the DOMConfiguration parameter name.
+     * @param value An Object contaiing the parameters value to set.
+     */
+    public void setParameter(String name, Object value) throws DOMException {
+        // If the value is a boolean
+        if (value instanceof Boolean) {
+            boolean state = ((Boolean) value).booleanValue();
+            
+            if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) {
+                fFeatures = state ? fFeatures | COMMENTS : fFeatures
+                        & ~COMMENTS;
+                // comments
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }                
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) {
+                fFeatures =  state ? fFeatures | CDATA : fFeatures
+                        & ~CDATA;
+                // cdata-sections
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) {
+                fFeatures = state ? fFeatures | ENTITIES : fFeatures
+                        & ~ENTITIES;
+                // entities
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_TRUE);
+                    fDOMConfigProperties.setProperty(
+                            DOMConstants.S_XERCES_PROPERTIES_NS
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    fDOMConfigProperties.setProperty(
+                            DOMConstants.S_XERCES_PROPERTIES_NS
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) {
+                fFeatures = state ? fFeatures | NAMESPACES : fFeatures
+                        & ~NAMESPACES;
+                // namespaces
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_FALSE); 
+                }       
+            } else if (name
+                    .equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) {
+                fFeatures = state ? fFeatures | NAMESPACEDECLS
+                        : fFeatures & ~NAMESPACEDECLS;
+                // namespace-declarations
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_FALSE); 
+                } 
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) {
+                fFeatures = state ? fFeatures | SPLITCDATA : fFeatures
+                        & ~SPLITCDATA;
+                // split-cdata-sections
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_FALSE); 
+                }  
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) {
+                fFeatures = state ? fFeatures | WELLFORMED : fFeatures
+                        & ~WELLFORMED;
+                // well-formed
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_FALSE); 
+                }                  
+            } else if (name
+                    .equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) {
+                fFeatures = state ? fFeatures | DISCARDDEFAULT
+                        : fFeatures & ~DISCARDDEFAULT;
+                // discard-default-content
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_FALSE); 
+                }                    
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
+                fFeatures = state ? fFeatures | PRETTY_PRINT : fFeatures
+                        & ~PRETTY_PRINT;
+                // format-pretty-print
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_TRUE);
+                }
+                else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) {
+                fFeatures = state ? fFeatures | XMLDECL : fFeatures
+                        & ~XMLDECL;
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no");
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "yes"); 
+                }       
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
+                fFeatures = state ? fFeatures | ELEM_CONTENT_WHITESPACE : fFeatures
+                        & ~ELEM_CONTENT_WHITESPACE;
+                // element-content-whitespace
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }            
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+                // false is not supported
+                if (!state) {
+                    // Here we have to add the Xalan specific DOM Message Formatter
+                    String msg = Utils.messages.createMessage(
+                            MsgKey.ER_FEATURE_NOT_SUPPORTED,
+                            new Object[] { name });
+                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+                } else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                }
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
+                    || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)
+                    // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
+                    ) {
+                // true is not supported
+                if (state) {
+                    String msg = Utils.messages.createMessage(
+                            MsgKey.ER_FEATURE_NOT_SUPPORTED,
+                            new Object[] { name });
+                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+                } else {
+                    if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                                + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                                + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                                + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION 
+                                + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } else if (name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                                + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } /* else if (name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)) {
+                        fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                                + DOMConstants.DOM_NORMALIZE_CHARACTERS, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    } */
+                }
+            } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)) {
+                // infoset
+                if (state) {
+                    fFeatures &= ~ENTITIES;
+                    fFeatures &= ~CDATA;
+                    fFeatures &= ~SCHEMAVALIDATE;
+                    fFeatures &= ~DTNORMALIZE;
+                    fFeatures |= NAMESPACES;
+                    fFeatures |= NAMESPACEDECLS;
+                    fFeatures |= WELLFORMED;
+                    fFeatures |= ELEM_CONTENT_WHITESPACE;
+                    fFeatures |= COMMENTS;
+                    
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE); 
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE);
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE);
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE);
+                    
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS
+                            + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE);
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE);            
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }
+            } else {
+                // If this is a non-boolean parameter a type mismatch should be thrown.
+                if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) {
+                    String msg = Utils.messages.createMessage(
+                            MsgKey.ER_TYPE_MISMATCH_ERR,
+                            new Object[] { name });
+                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                }
+                
+                // Parameter is not recognized
+                String msg = Utils.messages.createMessage(
+                        MsgKey.ER_FEATURE_NOT_FOUND,
+                        new Object[] { name });
+                throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+            }
+        } // If the parameter value is not a boolean 
+        else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) {
+            if (value == null || value instanceof DOMErrorHandler) {
+                fDOMErrorHandler = (DOMErrorHandler)value;
+            } else {
+                String msg = Utils.messages.createMessage(
+                        MsgKey.ER_TYPE_MISMATCH_ERR,
+                        new Object[] { name });
+                throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+            }
+        } else if (
+                name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION)
+                || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) {
+            if (value != null) {
+                if (!(value instanceof String)) {
+                    String msg = Utils.messages.createMessage(
+                            MsgKey.ER_TYPE_MISMATCH_ERR,
+                            new Object[] { name });
+                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                }
+                String msg = Utils.messages.createMessage(
+                        MsgKey.ER_FEATURE_NOT_SUPPORTED,
+                        new Object[] { name });
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+            }
+        } else {
+            // If this is a boolean parameter a type mismatch should be thrown.
+            if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) ||
+                    name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)) {
+                String msg = Utils.messages.createMessage(
+                        MsgKey.ER_TYPE_MISMATCH_ERR,
+                        new Object[] { name });
+                throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+            }
+            
+            // Parameter is not recognized
+            String msg = Utils.messages.createMessage(
+                    MsgKey.ER_FEATURE_NOT_FOUND,
+                    new Object[] { name });
+            throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+        }
+    }
+    // ************************************************************************
+    
+    
+    // ************************************************************************
+    // DOMConfiguraiton implementation
+    // ************************************************************************
+    
+    /** 
+     * Returns the DOMConfiguration of the LSSerializer.
+     *  
+     * @see org.w3c.dom.ls.LSSerializer#getDomConfig()
+     * @since DOM Level 3
+     * @return A DOMConfiguration object.
+     */
+    public DOMConfiguration getDomConfig() {
+        return (DOMConfiguration)this;
+    }
+    
+    /** 
+     * Returns the DOMConfiguration of the LSSerializer.
+     *  
+     * @see org.w3c.dom.ls.LSSerializer#getFilter()
+     * @since DOM Level 3
+     * @return A LSSerializerFilter object.
+     */
+    public LSSerializerFilter getFilter() {
+        return fSerializerFilter;
+    }
+    
+    /** 
+     * Returns the End-Of-Line sequence of characters to be used in the XML 
+     * being serialized.  If none is set a default "\n" is returned.
+     * 
+     * @see org.w3c.dom.ls.LSSerializer#getNewLine()
+     * @since DOM Level 3
+     * @return A String containing the end-of-line character sequence  used in 
+     * serialization.
+     */
+    public String getNewLine() {
+        return fEndOfLine;
+    }
+    
+    /** 
+     * Set a LSSerilizerFilter on the LSSerializer.  When set, the filter is
+     * called before each node is serialized which depending on its implemention
+     * determines if the node is to be serialized or not.    
+     *  
+     * @see org.w3c.dom.ls.LSSerializer#setFilter
+     * @since DOM Level 3
+     * @param filter A LSSerializerFilter to be applied to the stream to serialize.
+     */
+    public void setFilter(LSSerializerFilter filter) {
+        fSerializerFilter = filter;
+    }
+    
+    /** 
+     * Sets the End-Of-Line sequence of characters to be used in the XML 
+     * being serialized.  Setting this attribute to null will reset its 
+     * value to the default value i.e. "\n".
+     * 
+     * @see org.w3c.dom.ls.LSSerializer#setNewLine
+     * @since DOM Level 3
+     * @param newLine a String that is the end-of-line character sequence to be used in 
+     * serialization.
+     */
+    public void setNewLine(String newLine) {
+        fEndOfLine = (newLine != null) ? newLine : DEFAULT_END_OF_LINE;
+    }
+    
+    /** 
+     * Serializes the specified node to the specified LSOutput and returns true if the Node 
+     * was successfully serialized. 
+     * 
+     * @see org.w3c.dom.ls.LSSerializer#write(org.w3c.dom.Node, org.w3c.dom.ls.LSOutput)
+     * @since DOM Level 3
+     * @param nodeArg The Node to serialize.
+     * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the 
+     * LSSerializer was unable to serialize the node.
+     *      
+     */
+    public boolean write(Node nodeArg, LSOutput destination) throws LSException {
+        // If the destination is null
+        if (destination == null) {
+            String msg = Utils.messages
+            .createMessage(
+                    MsgKey.ER_NO_OUTPUT_SPECIFIED,
+                    null);
+            if (fDOMErrorHandler != null) {
+                fDOMErrorHandler.handleError(new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR, msg,
+                        MsgKey.ER_NO_OUTPUT_SPECIFIED));
+            }
+            throw new LSException(LSException.SERIALIZE_ERR, msg);
+        } 
+        
+        // If nodeArg is null, return false.  Should we throw and LSException instead?
+        if (nodeArg == null ) {
+            return false;
+        }
+
+        // Obtain a reference to the serializer to use
+        // Serializer serializer = getXMLSerializer(xmlVersion);
+        Serializer serializer = fXMLSerializer;
+        serializer.reset();
+        
+        // If the node has not been seen
+        if ( nodeArg != fVisitedNode) {
+            // Determine the XML Document version of the Node 
+            String xmlVersion = getXMLVersion(nodeArg);
+            
+            // Determine the encoding: 1.LSOutput.encoding, 2.Document.inputEncoding, 3.Document.xmlEncoding. 
+            fEncoding = destination.getEncoding();
+            if (fEncoding == null ) {
+            	fEncoding = getInputEncoding(nodeArg);
+            	fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg);
+            }
+
+            // If the encoding is not recognized throw an exception.
+            // Note: The serializer defaults to UTF-8 when created
+            if (!Encodings.isRecognizedEncoding(fEncoding)) {
+                String msg = Utils.messages
+                .createMessage(
+                        MsgKey.ER_UNSUPPORTED_ENCODING,
+                        null);
+                if (fDOMErrorHandler != null) {
+                    fDOMErrorHandler.handleError(new DOMErrorImpl(
+                            DOMError.SEVERITY_FATAL_ERROR, msg,
+                            MsgKey.ER_UNSUPPORTED_ENCODING));
+                }
+                throw new LSException(LSException.SERIALIZE_ERR, msg);            	
+            }
+            
+            serializer.getOutputFormat().setProperty("version", xmlVersion);
+
+            // Set the output encoding and xml version properties
+            fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
+            fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding);
+            
+            // If the node to be serialized is not a Document, Element, or Entity
+            // node
+            // then the XML declaration, or text declaration, should be never be
+            // serialized.
+            if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE
+                    || nodeArg.getNodeType() != Node.ELEMENT_NODE
+                    || nodeArg.getNodeType() != Node.ENTITY_NODE)
+                    && ((fFeatures & XMLDECL) != 0)) {
+                fDOMConfigProperties.setProperty(
+                        DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
+                        DOMConstants.DOM3_DEFAULT_FALSE);
+            }
+
+            fVisitedNode = nodeArg;
+        } 
+        
+        // Update the serializer properties
+        fXMLSerializer.setOutputFormat(fDOMConfigProperties);
+        
+        // 
+        try {
+            
+            // The LSSerializer will use the LSOutput object to determine 
+            // where to serialize the output to in the following order the  
+            // first one that is not null and not an empty string will be    
+            // used: 1.LSOutput.characterStream, 2.LSOutput.byteStream,   
+            // 3. LSOutput.systemId 
+            // 1.LSOutput.characterStream
+            Writer writer = destination.getCharacterStream();
+            if (writer == null ) {
+                
+                // 2.LSOutput.byteStream
+                OutputStream outputStream = destination.getByteStream();
+                if ( outputStream == null) {
+                    
+                    // 3. LSOutput.systemId
+                    String uri = destination.getSystemId();
+                    if (uri == null) {
+                        String msg = Utils.messages
+                        .createMessage(
+                                MsgKey.ER_NO_OUTPUT_SPECIFIED,
+                                null);
+                        if (fDOMErrorHandler != null) {
+                            fDOMErrorHandler.handleError(new DOMErrorImpl(
+                                    DOMError.SEVERITY_FATAL_ERROR, msg,
+                                    MsgKey.ER_NO_OUTPUT_SPECIFIED));
+                        }
+                        throw new LSException(LSException.SERIALIZE_ERR, msg);
+                        
+                    } else {
+                        // Expand the System Id and obtain an absolute URI for it.
+                        String absoluteURI = SystemIDResolver.getAbsoluteURI(uri);
+                        
+                        URL url = new URL(absoluteURI);
+                        OutputStream urlOutStream = null;
+                        String protocol = url.getProtocol();
+                        String host = url.getHost();
+                        
+                        // For file protocols, there is no need to use a URL to get its
+                        // corresponding OutputStream
+                        
+                        // Scheme names consist of a sequence of characters. The lower case
+                        // letters "a"--"z", digits, and the characters plus ("+"), period
+                        // ("."), and hyphen ("-") are allowed. For resiliency, programs
+                        // interpreting URLs should treat upper case letters as equivalent to
+                        // lower case in scheme names (e.g., allow "HTTP" as well as "http").
+                        if (protocol.equalsIgnoreCase("file") 
+                                && (host == null || host.length() == 0 || host.equals("localhost"))) {
+                            // do we also need to check for host.equals(hostname)
+                            urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath()));
+                           
+                        } else {
+                            // This should support URL's whose schemes are mentioned in 
+                            // RFC1738 other than file
+                            
+                            URLConnection urlCon = url.openConnection();
+                            urlCon.setDoInput(false);
+                            urlCon.setDoOutput(true);
+                            urlCon.setUseCaches(false); 
+                            urlCon.setAllowUserInteraction(false);
+                            
+                            // When writing to a HTTP URI, a HTTP PUT is performed.
+                            if (urlCon instanceof HttpURLConnection) {
+                                HttpURLConnection httpCon = (HttpURLConnection) urlCon;
+                                httpCon.setRequestMethod("PUT");
+                            }
+                            urlOutStream = urlCon.getOutputStream();
+                        }
+                        // set the OutputStream to that obtained from the systemId
+                        serializer.setOutputStream(urlOutStream);
+                    }
+                } else {
+                    // 2.LSOutput.byteStream
+                    serializer.setOutputStream(outputStream);     
+                }
+            } else {
+                // 1.LSOutput.characterStream
+                serializer.setWriter(writer);
+            }
+            
+            // The associated media type by default is set to text/xml on 
+            // org.apache.xml.serializer.SerializerBase.  
+            
+            // Get a reference to the serializer then lets you serilize a DOM
+            // Use this hack till Xalan support JAXP1.3
+            if (fDOMSerializer == null) {
+               fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
+            } 
+            
+            // Set the error handler on the DOM3Serializer interface implementation
+            if (fDOMErrorHandler != null) {
+                fDOMSerializer.setErrorHandler(fDOMErrorHandler);
+            }
+            
+            // Set the filter on the DOM3Serializer interface implementation
+            if (fSerializerFilter != null) {
+                fDOMSerializer.setNodeFilter(fSerializerFilter);
+            }
+            
+            // Set the NewLine character to be used
+            fDOMSerializer.setNewLine(fEndOfLine.toCharArray());
+            
+            // Serializer your DOM, where node is an org.w3c.dom.Node
+            // Assuming that Xalan's serializer can serialize any type of DOM node
+            fDOMSerializer.serializeDOM3(nodeArg);
+            
+        } catch( UnsupportedEncodingException ue) {
+            
+            String msg = Utils.messages
+            .createMessage(
+                    MsgKey.ER_UNSUPPORTED_ENCODING,
+                    null);
+            if (fDOMErrorHandler != null) {
+                fDOMErrorHandler.handleError(new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR, msg,
+                        MsgKey.ER_UNSUPPORTED_ENCODING, ue));
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, ue).fillInStackTrace();
+        } catch (LSException lse) {
+            // Rethrow LSException.
+            throw lse;
+        } catch (RuntimeException e) {
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }  catch (Exception e) {
+            if (fDOMErrorHandler != null) {
+                fDOMErrorHandler.handleError(new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
+                        null, e));
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }        
+        return true;
+    }
+    
+    /** 
+     * Serializes the specified node and returns a String with the serialized
+     * data to the caller.  
+     * 
+     * @see org.w3c.dom.ls.LSSerializer#writeToString(org.w3c.dom.Node)
+     * @since DOM Level 3
+     * @param nodeArg The Node to serialize.
+     * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the 
+     * LSSerializer was unable to serialize the node.
+     *      
+     */
+    public String writeToString(Node nodeArg) throws DOMException, LSException {
+        // return null is nodeArg is null.  Should an Exception be thrown instead?
+        if (nodeArg == null) {
+            return null;
+        }
+
+        // Should we reset the serializer configuration before each write operation?
+        // Obtain a reference to the serializer to use
+        Serializer serializer = fXMLSerializer;
+        serializer.reset();
+        
+        if (nodeArg != fVisitedNode){
+            // Determine the XML Document version of the Node 
+            String xmlVersion = getXMLVersion(nodeArg);
+            
+            serializer.getOutputFormat().setProperty("version", xmlVersion);
+            
+            // Set the output encoding and xml version properties
+            fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
+            fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, "UTF-16");
+            
+            // If the node to be serialized is not a Document, Element, or Entity
+            // node
+            // then the XML declaration, or text declaration, should be never be
+            // serialized.
+            if  ((nodeArg.getNodeType() != Node.DOCUMENT_NODE
+                    || nodeArg.getNodeType() != Node.ELEMENT_NODE
+                    || nodeArg.getNodeType() != Node.ENTITY_NODE)
+                    && ((fFeatures & XMLDECL) != 0)) {
+                fDOMConfigProperties.setProperty(
+                        DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
+                        DOMConstants.DOM3_DEFAULT_FALSE);
+            }            
+
+            fVisitedNode = nodeArg;       
+        } 
+        // Update the serializer properties
+        fXMLSerializer.setOutputFormat(fDOMConfigProperties);
+        
+        // StringWriter to Output to
+        StringWriter output = new StringWriter();
+        
+        // 
+        try {
+            
+            // Set the Serializer's Writer to a StringWriter
+            serializer.setWriter(output);
+            
+            // Get a reference to the serializer then lets you serilize a DOM
+            // Use this hack till Xalan support JAXP1.3
+            if (fDOMSerializer == null) {
+                fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
+            } 
+                        
+            // Set the error handler on the DOM3Serializer interface implementation
+            if (fDOMErrorHandler != null) {
+                fDOMSerializer.setErrorHandler(fDOMErrorHandler);
+            }
+            
+            // Set the filter on the DOM3Serializer interface implementation
+            if (fSerializerFilter != null) {
+                fDOMSerializer.setNodeFilter(fSerializerFilter);
+            }
+            
+            // Set the NewLine character to be used
+            fDOMSerializer.setNewLine(fEndOfLine.toCharArray());
+            
+            // Serializer your DOM, where node is an org.w3c.dom.Node
+            fDOMSerializer.serializeDOM3(nodeArg);
+        } catch (LSException lse) {
+            // Rethrow LSException.
+            throw lse;
+        } catch (RuntimeException e) {
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }  catch (Exception e) {
+            if (fDOMErrorHandler != null) {
+                fDOMErrorHandler.handleError(new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
+                        null, e));
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }        
+        
+        // return the serialized string
+        return output.toString();
+    }
+    
+    /** 
+     * Serializes the specified node to the specified URI and returns true if the Node 
+     * was successfully serialized. 
+     * 
+     * @see org.w3c.dom.ls.LSSerializer#writeToURI(org.w3c.dom.Node, String)
+     * @since DOM Level 3
+     * @param nodeArg The Node to serialize.
+     * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the 
+     * LSSerializer was unable to serialize the node.
+     *      
+     */
+    public boolean writeToURI(Node nodeArg, String uri) throws LSException {
+        // If nodeArg is null, return false.  Should we throw and LSException instead?
+        if (nodeArg == null ) {
+            return false;
+        }
+
+        // Obtain a reference to the serializer to use
+        Serializer serializer = fXMLSerializer;
+        serializer.reset();
+        
+        if (nodeArg != fVisitedNode) {
+            // Determine the XML Document version of the Node 
+            String xmlVersion = getXMLVersion(nodeArg);
+            
+            // Determine the encoding: 1.LSOutput.encoding,
+            // 2.Document.inputEncoding, 3.Document.xmlEncoding.
+            fEncoding = getInputEncoding(nodeArg);
+            if (fEncoding == null ) {
+            	fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg);
+            }
+            
+            serializer.getOutputFormat().setProperty("version", xmlVersion);
+            
+            // Set the output encoding and xml version properties
+            fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
+            fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding);
+            
+            // If the node to be serialized is not a Document, Element, or Entity
+            // node
+            // then the XML declaration, or text declaration, should be never be
+            // serialized.
+            if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE
+                    || nodeArg.getNodeType() != Node.ELEMENT_NODE
+                    || nodeArg.getNodeType() != Node.ENTITY_NODE)
+                    && ((fFeatures & XMLDECL) != 0))  {
+                fDOMConfigProperties.setProperty(
+                        DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
+                        DOMConstants.DOM3_DEFAULT_FALSE);
+            }
+       
+            fVisitedNode = nodeArg;
+        } 
+        
+        // Update the serializer properties
+        fXMLSerializer.setOutputFormat(fDOMConfigProperties);
+        
+        // 
+        try {
+            // If the specified encoding is not supported an
+            // "unsupported-encoding" fatal error is raised. ??
+            if (uri == null) {
+                String msg = Utils.messages.createMessage(
+                        MsgKey.ER_NO_OUTPUT_SPECIFIED, null);
+                if (fDOMErrorHandler != null) {
+                    fDOMErrorHandler.handleError(new DOMErrorImpl(
+                            DOMError.SEVERITY_FATAL_ERROR, msg,
+                            MsgKey.ER_NO_OUTPUT_SPECIFIED));
+                }
+                throw new LSException(LSException.SERIALIZE_ERR, msg);
+                
+            } else {
+                // REVISIT: Can this be used to get an absolute expanded URI
+                String absoluteURI = SystemIDResolver.getAbsoluteURI(uri);
+                
+                URL url = new URL(absoluteURI);
+                OutputStream urlOutStream = null;
+                String protocol = url.getProtocol();
+                String host = url.getHost();
+                
+                // For file protocols, there is no need to use a URL to get its
+                // corresponding OutputStream
+                
+                // Scheme names consist of a sequence of characters. The lower 
+                // case letters "a"--"z", digits, and the characters plus ("+"), 
+                // period ("."), and hyphen ("-") are allowed. For resiliency, 
+                // programs interpreting URLs should treat upper case letters as
+                // equivalent to lower case in scheme names 
+                // (e.g., allow "HTTP" as well as "http").
+                if (protocol.equalsIgnoreCase("file")
+                        && (host == null || host.length() == 0 || host
+                                .equals("localhost"))) {
+                    // do we also need to check for host.equals(hostname)
+                    urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath()));
+                    
+                } else {
+                    // This should support URL's whose schemes are mentioned in
+                    // RFC1738 other than file
+                    
+                    URLConnection urlCon = url.openConnection();
+                    urlCon.setDoInput(false);
+                    urlCon.setDoOutput(true);
+                    urlCon.setUseCaches(false);
+                    urlCon.setAllowUserInteraction(false);
+                    
+                    // When writing to a HTTP URI, a HTTP PUT is performed.
+                    if (urlCon instanceof HttpURLConnection) {
+                        HttpURLConnection httpCon = (HttpURLConnection) urlCon;
+                        httpCon.setRequestMethod("PUT");
+                    }
+                    urlOutStream = urlCon.getOutputStream();
+                }
+                // set the OutputStream to that obtained from the systemId
+                serializer.setOutputStream(urlOutStream);
+            }
+            
+            // Get a reference to the serializer then lets you serilize a DOM
+            // Use this hack till Xalan support JAXP1.3
+            if (fDOMSerializer == null) {
+                fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
+            } 
+            
+            // Set the error handler on the DOM3Serializer interface implementation
+            if (fDOMErrorHandler != null) {
+                fDOMSerializer.setErrorHandler(fDOMErrorHandler);
+            }
+            
+            // Set the filter on the DOM3Serializer interface implementation
+            if (fSerializerFilter != null) {
+                fDOMSerializer.setNodeFilter(fSerializerFilter);
+            }
+            
+            // Set the NewLine character to be used
+            fDOMSerializer.setNewLine(fEndOfLine.toCharArray());
+            
+            // Serializer your DOM, where node is an org.w3c.dom.Node
+            // Assuming that Xalan's serializer can serialize any type of DOM
+            // node
+            fDOMSerializer.serializeDOM3(nodeArg);
+            
+        } catch (LSException lse) {
+            // Rethrow LSException.
+            throw lse;
+        } catch (RuntimeException e) {
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }  catch (Exception e) {
+            if (fDOMErrorHandler != null) {
+                fDOMErrorHandler.handleError(new DOMErrorImpl(
+                        DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
+                        null, e));
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        }        
+        
+        return true;
+    }
+    // ************************************************************************
+    
+    
+    // ************************************************************************
+    // Implementaion methods
+    // ************************************************************************
+    
+    /** 
+     * Determines the XML Version of the Document Node to serialize.  If the Document Node
+     * is not a DOM Level 3 Node, then the default version returned is 1.0.
+     * 
+     * @param  nodeArg The Node to serialize
+     * @return A String containing the version pseudo-attribute of the XMLDecl.  
+     * @throws Throwable if the DOM implementation does not implement Document.getXmlVersion()      
+     */
+    //protected String getXMLVersion(Node nodeArg) throws Throwable {
+    protected String getXMLVersion(Node nodeArg) {
+        Document doc = null;
+        
+        // Determine the XML Version of the document
+        if (nodeArg != null) {
+            if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
+                // The Document node is the Node argument
+                doc = (Document)nodeArg;
+            } else { 
+                // The Document node is the Node argument's ownerDocument
+                doc = nodeArg.getOwnerDocument();
+            }
+            
+            // Determine the DOM Version.
+            if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
+                return doc.getXmlVersion();
+            }
+        } 
+        // The version will be treated as "1.0" which may result in
+        // an ill-formed document being serialized.
+        // If nodeArg does not have an ownerDocument, treat this as XML 1.0
+        return "1.0";
+    }
+    
+    /** 
+     * Determines the XML Encoding of the Document Node to serialize.  If the Document Node
+     * is not a DOM Level 3 Node, then the default encoding "UTF-8" is returned.
+     * 
+     * @param  nodeArg The Node to serialize
+     * @return A String containing the encoding pseudo-attribute of the XMLDecl.  
+     * @throws Throwable if the DOM implementation does not implement Document.getXmlEncoding()     
+     */
+    protected String getXMLEncoding(Node nodeArg) {
+        Document doc = null;
+        
+        // Determine the XML Encoding of the document
+        if (nodeArg != null) {
+            if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
+                // The Document node is the Node argument
+                doc = (Document)nodeArg;
+            } else { 
+                // The Document node is the Node argument's ownerDocument
+                doc = nodeArg.getOwnerDocument();
+            }
+            
+            // Determine the XML Version. 
+            if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
+                return doc.getXmlEncoding();
+            }
+        } 
+        // The default encoding is UTF-8 except for the writeToString method
+        return "UTF-8";
+    }
+    
+    /** 
+     * Determines the Input Encoding of the Document Node to serialize.  If the Document Node
+     * is not a DOM Level 3 Node, then null is returned.
+     * 
+     * @param  nodeArg The Node to serialize
+     * @return A String containing the input encoding.  
+     */
+    protected String getInputEncoding(Node nodeArg)  {
+        Document doc = null;
+        
+        // Determine the Input Encoding of the document
+        if (nodeArg != null) {
+            if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
+                // The Document node is the Node argument
+                doc = (Document)nodeArg;
+            } else { 
+                // The Document node is the Node argument's ownerDocument
+                doc = nodeArg.getOwnerDocument();
+            }
+            
+            // Determine the DOM Version.
+            if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
+                return doc.getInputEncoding();
+            }
+        } 
+        // The default encoding returned is null
+        return null;
+    }
+    
+    /**
+     * This method returns the LSSerializer's error handler.
+     * 
+     * @return Returns the fDOMErrorHandler.
+     */
+    public DOMErrorHandler getErrorHandler() {
+        return fDOMErrorHandler;
+    }
+    
+    /**
+     * Replaces all escape sequences in the given path with their literal characters.
+     */
+    private static String getPathWithoutEscapes(String origPath) {
+        if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) {
+            // Locate the escape characters
+            StringTokenizer tokenizer = new StringTokenizer(origPath, "%");
+            StringBuffer result = new StringBuffer(origPath.length());
+            int size = tokenizer.countTokens();
+            result.append(tokenizer.nextToken());
+            for(int i = 1; i < size; ++i) {
+                String token = tokenizer.nextToken();
+                if (token.length() >= 2 && isHexDigit(token.charAt(0)) && 
+                        isHexDigit(token.charAt(1))) {
+                    // Decode the 2 digit hexadecimal number following % in '%nn'
+                    result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue());
+                    token = token.substring(2);
+                }
+                result.append(token);
+            }
+            return result.toString();
+        }
+        return origPath;
+    }
+
+    /** 
+     * Returns true if the given character is a valid hex character.
+     */
+    private static boolean isHexDigit(char c) {
+        return (c >= '0' && c <= '9' || 
+                c >= 'a' && c <= 'f' || 
+                c >= 'A' && c <= 'F');
+    }
+    
+    /**
+     * Creates an LSException. On J2SE 1.4 and above the cause for the exception will be set.
+     */
+    private static LSException createLSException(short code, Throwable cause) {
+        LSException lse = new LSException(code, cause != null ? cause.getMessage() : null);
+        if (cause != null && ThrowableMethods.fgThrowableMethodsAvailable) {
+            try {
+                ThrowableMethods.fgThrowableInitCauseMethod.invoke(lse, new Object [] {cause});
+            }
+            // Something went wrong. There's not much we can do about it.
+            catch (Exception e) {}
+        }
+        return lse;
+    }
+    
+    /**
+     * Holder of methods from java.lang.Throwable.
+     */
+    static class ThrowableMethods {
+        
+        // Method: java.lang.Throwable.initCause(java.lang.Throwable)
+        private static java.lang.reflect.Method fgThrowableInitCauseMethod = null;
+        
+        // Flag indicating whether or not Throwable methods available.
+        private static boolean fgThrowableMethodsAvailable = false;
+        
+        private ThrowableMethods() {}
+        
+        // Attempt to get methods for java.lang.Throwable on class initialization.
+        static {
+            try {
+                fgThrowableInitCauseMethod = Throwable.class.getMethod("initCause", new Class [] {Throwable.class});
+                fgThrowableMethodsAvailable = true;
+            }
+            // ClassNotFoundException, NoSuchMethodException or SecurityException
+            // Whatever the case, we cannot use java.lang.Throwable.initCause(java.lang.Throwable).
+            catch (Exception exc) {
+                fgThrowableInitCauseMethod = null;
+                fgThrowableMethodsAvailable = false;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/dom3/NamespaceSupport.java b/src/main/java/org/apache/xml/serializer/dom3/NamespaceSupport.java
new file mode 100644
index 0000000..fc2b0ea
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/dom3/NamespaceSupport.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id:  $
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Namespace support for XML document handlers. This class doesn't 
+ * perform any error checking and assumes that all strings passed
+ * as arguments to methods are unique symbols. The SymbolTable class
+ * can be used for this purpose.
+ * 
+ * Derived from org.apache.xerces.util.NamespaceSupport
+ *
+ * @author Andy Clark, IBM
+ *
+ * @version $Id: Exp $
+ */
+public class NamespaceSupport {
+
+	static final String PREFIX_XML = "xml".intern();
+	
+	static final String PREFIX_XMLNS = "xmlns".intern(); 
+    
+    /**
+     * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is
+     * the Namespace URI that is automatically mapped to the "xml" prefix.
+     */
+    public final static String XML_URI = "http://www.w3.org/XML/1998/namespace".intern();
+
+    /**
+     * XML Information Set REC
+     * all namespace attributes (including those named xmlns, 
+     * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/
+     */
+    public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern();
+
+	//
+    // Data
+    //
+
+    /** 
+     * Namespace binding information. This array is composed of a
+     * series of tuples containing the namespace binding information:
+     * &lt;prefix, uri&gt;. The default size can be set to anything
+     * as long as it is a power of 2 greater than 1.
+     *
+     * @see #fNamespaceSize
+     * @see #fContext
+     */
+    protected String[] fNamespace = new String[16 * 2];
+
+    /** The top of the namespace information array. */
+    protected int fNamespaceSize;
+
+    // NOTE: The constructor depends on the initial context size 
+    //       being at least 1. -Ac
+
+    /** 
+     * Context indexes. This array contains indexes into the namespace
+     * information array. The index at the current context is the start
+     * index of declared namespace bindings and runs to the size of the
+     * namespace information array.
+     *
+     * @see #fNamespaceSize
+     */
+    protected int[] fContext = new int[8];
+
+    /** The current context. */
+    protected int fCurrentContext;
+    
+    protected String[] fPrefixes = new String[16];
+    
+    //
+    // Constructors
+    //
+
+    /** Default constructor. */
+    public NamespaceSupport() {
+    } // <init>()
+
+    //
+    // Public methods
+    //
+    
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#reset()
+	 */
+    public void reset() {
+
+        // reset namespace and context info
+        fNamespaceSize = 0;
+        fCurrentContext = 0;
+        fContext[fCurrentContext] = fNamespaceSize;
+
+        // bind "xml" prefix to the XML uri
+        fNamespace[fNamespaceSize++] = PREFIX_XML;
+        fNamespace[fNamespaceSize++] = XML_URI;
+        // bind "xmlns" prefix to the XMLNS uri
+        fNamespace[fNamespaceSize++] = PREFIX_XMLNS;
+        fNamespace[fNamespaceSize++] = XMLNS_URI;
+        ++fCurrentContext;
+
+    } // reset(SymbolTable)
+
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#pushContext()
+	 */
+    public void pushContext() {
+
+        // extend the array, if necessary
+        if (fCurrentContext + 1 == fContext.length) {
+            int[] contextarray = new int[fContext.length * 2];
+            System.arraycopy(fContext, 0, contextarray, 0, fContext.length);
+            fContext = contextarray;
+        }
+
+        // push context
+        fContext[++fCurrentContext] = fNamespaceSize;
+
+    } // pushContext()
+
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#popContext()
+	 */
+    public void popContext() {
+        fNamespaceSize = fContext[fCurrentContext--];
+    } // popContext()
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#declarePrefix(String, String)
+	 */
+    public boolean declarePrefix(String prefix, String uri) {
+        // ignore "xml" and "xmlns" prefixes
+        if (prefix == PREFIX_XML || prefix == PREFIX_XMLNS) {
+            return false;
+        }
+
+        // see if prefix already exists in current context
+        for (int i = fNamespaceSize; i > fContext[fCurrentContext]; i -= 2) {
+            //if (fNamespace[i - 2] == prefix) {
+        	if (fNamespace[i - 2].equals(prefix) )  {
+                // REVISIT: [Q] Should the new binding override the
+                //          previously declared binding or should it
+                //          it be ignored? -Ac
+                // NOTE:    The SAX2 "NamespaceSupport" helper allows
+                //          re-bindings with the new binding overwriting
+                //          the previous binding. -Ac
+                fNamespace[i - 1] = uri;
+                return true;
+            }
+        }
+
+        // resize array, if needed
+        if (fNamespaceSize == fNamespace.length) {
+            String[] namespacearray = new String[fNamespaceSize * 2];
+            System.arraycopy(fNamespace, 0, namespacearray, 0, fNamespaceSize);
+            fNamespace = namespacearray;
+        }
+
+        // bind prefix to uri in current context
+        fNamespace[fNamespaceSize++] = prefix;
+        fNamespace[fNamespaceSize++] = uri;
+
+        return true;
+
+    } // declarePrefix(String,String):boolean
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#getURI(String)
+	 */
+    public String getURI(String prefix) {
+        
+        // find prefix in current context
+        for (int i = fNamespaceSize; i > 0; i -= 2) {
+            //if (fNamespace[i - 2] == prefix) {
+        	if (fNamespace[i - 2].equals(prefix) ) {
+                return fNamespace[i - 1];
+            }
+        }
+
+        // prefix not found
+        return null;
+
+    } // getURI(String):String
+
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#getPrefix(String)
+	 */
+    public String getPrefix(String uri) {
+
+        // find uri in current context
+        for (int i = fNamespaceSize; i > 0; i -= 2) {
+            //if (fNamespace[i - 1] == uri) {
+        	if (fNamespace[i - 1].equals(uri) ) {
+                //if (getURI(fNamespace[i - 2]) == uri)
+        		if (getURI(fNamespace[i - 2]).equals(uri) )
+                    return fNamespace[i - 2];
+            }
+        }
+
+        // uri not found
+        return null;
+
+    } // getPrefix(String):String
+
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixCount()
+	 */
+    public int getDeclaredPrefixCount() {
+        return (fNamespaceSize - fContext[fCurrentContext]) / 2;
+    } // getDeclaredPrefixCount():int
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixAt(int)
+	 */
+    public String getDeclaredPrefixAt(int index) {
+        return fNamespace[fContext[fCurrentContext] + index * 2];
+    } // getDeclaredPrefixAt(int):String
+
+	/**
+	 * @see org.apache.xerces.xni.NamespaceContext#getAllPrefixes()
+	 */
+	public Enumeration getAllPrefixes() {
+        int count = 0;
+        if (fPrefixes.length < (fNamespace.length/2)) {
+            // resize prefix array          
+            String[] prefixes = new String[fNamespaceSize];
+            fPrefixes = prefixes;
+        }
+        String prefix = null;
+        boolean unique = true;
+        for (int i = 2; i < (fNamespaceSize-2); i += 2) {
+            prefix = fNamespace[i + 2];            
+            for (int k=0;k<count;k++){
+                if (fPrefixes[k]==prefix){
+                    unique = false;
+                    break;
+                }               
+            }
+            if (unique){
+                fPrefixes[count++] = prefix;
+            }
+            unique = true;
+        }
+		return new Prefixes(fPrefixes, count);
+	}
+    
+    protected final class Prefixes implements Enumeration {
+        private String[] prefixes;
+        private int counter = 0;
+        private int size = 0;
+               
+		/**
+		 * Constructor for Prefixes.
+		 */
+		public Prefixes(String [] prefixes, int size) {
+			this.prefixes = prefixes;
+            this.size = size;
+		}
+
+       /**
+		 * @see java.util.Enumeration#hasMoreElements()
+		 */
+		public boolean hasMoreElements() {           
+			return (counter< size);
+		}
+
+		/**
+		 * @see java.util.Enumeration#nextElement()
+		 */
+		public Object nextElement() {
+            if (counter< size){
+                return fPrefixes[counter++];
+            }
+			throw new NoSuchElementException("Illegal access to Namespace prefixes enumeration.");
+		}
+        
+        public String toString(){
+            StringBuffer buf = new StringBuffer();
+            for (int i=0;i<size;i++){
+                buf.append(prefixes[i]);
+                buf.append(" ");
+            }
+                
+            return buf.toString(); 
+        }
+
+}
+
+} // class NamespaceSupport
diff --git a/src/main/java/org/apache/xml/serializer/output_html.properties b/src/main/java/org/apache/xml/serializer/output_html.properties
new file mode 100644
index 0000000..71ca138
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/output_html.properties
@@ -0,0 +1,44 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: output_html.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# Specify defaults when method="html".  These defaults use output_xml.properties 
+# as a base.
+#
+
+# XSLT properties do not need namespace qualification.
+method=html
+indent=yes
+media-type=text/html
+version=4.0
+
+# Xalan-specific output properties.  These can be overridden in the stylesheet 
+# assigning a xalan namespace.  For example:
+# <xsl:stylesheet version="1.0"
+#          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+#          xmlns:xalan="http://xml.apache.org/xalan">
+#  <xsl:output method="html" encoding="UTF-8"
+#              xalan:content-handler="MyContentHandler"/>
+#  ...
+# Note that the colon after the protocol needs to be escaped.
+{http\u003a//xml.apache.org/xalan}indent-amount=0
+{http\u003a//xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToHTMLStream
+{http\u003a//xml.apache.org/xalan}entities=org/apache/xml/serializer/HTMLEntities
+{http\u003a//xml.apache.org/xalan}use-url-escaping=yes
+{http\u003a//xml.apache.org/xalan}omit-meta-tag=no
diff --git a/src/main/java/org/apache/xml/serializer/output_text.properties b/src/main/java/org/apache/xml/serializer/output_text.properties
new file mode 100644
index 0000000..25f906e
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/output_text.properties
@@ -0,0 +1,37 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: output_text.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# Specify defaults when method="text".
+#
+
+# XSLT properties do not need namespace qualification.
+method=text
+media-type=text/plain
+
+# Xalan-specific output properties.  These can be overridden in the stylesheet 
+# assigning a xalan namespace.  For example:
+# <xsl:stylesheet version="1.0"
+#          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+#          xmlns:xalan="http://xml.apache.org/xalan">
+#  <xsl:output method="html" encoding="UTF-8"
+#              xalan:content-handler="MyContentHandler"/>
+#  ...
+# Note that the colon after the protocol needs to be escaped.
+{http\u003a//xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToTextStream
diff --git a/src/main/java/org/apache/xml/serializer/output_unknown.properties b/src/main/java/org/apache/xml/serializer/output_unknown.properties
new file mode 100644
index 0000000..dd70ff0
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/output_unknown.properties
@@ -0,0 +1,46 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: output_unknown.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# Specify defaults when no method="..." is specified.
+# This type of output will quickly switch to "xml" or "html"
+# depending on the first element name.
+#
+
+# XSLT properties do not need namespace qualification.
+method=xml
+version=1.0
+encoding=UTF-8
+indent=no
+omit-xml-declaration=no
+standalone=no
+media-type=text/xml
+
+# Xalan-specific output properties.  These can be overridden in the stylesheet 
+# assigning a xalan namespace.  For example:
+# <xsl:stylesheet version="1.0"
+#          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+#          xmlns:xalan="http://xml.apache.org/xalan">
+#  <xsl:output method="html" encoding="UTF-8"
+#              xalan:content-handler="MyContentHandler"/>
+#  ...
+# Note that the colon after the protocol needs to be escaped.
+{http\u003a//xml.apache.org/xalan}indent-amount=0
+{http\u003a//xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToUnknownStream
+
diff --git a/src/main/java/org/apache/xml/serializer/output_xml.properties b/src/main/java/org/apache/xml/serializer/output_xml.properties
new file mode 100644
index 0000000..6a9617c
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/output_xml.properties
@@ -0,0 +1,46 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the  "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+#
+# $Id: output_xml.properties 468654 2006-10-28 07:09:23Z minchau $
+#
+# Specify defaults when method="xml".  These defaults serve as a base for 
+# other defaults, such as output_html and output_text.
+#
+
+# XSLT properties do not need namespace qualification.
+method=xml
+version=1.0
+encoding=UTF-8
+indent=no
+omit-xml-declaration=no
+standalone=no
+media-type=text/xml
+
+# Xalan-specific output properties.  These can be overridden in the stylesheet 
+# assigning a xalan namespace.  For example:
+# <xsl:stylesheet version="1.0"
+#          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+#          xmlns:xalan="http://xml.apache.org/xalan">
+#  <xsl:output method="html" encoding="UTF-8"
+#              xalan:content-handler="MyContentHandler"/>
+#  ...
+# Note that the colon after the protocol needs to be escaped.
+{http\u003a//xml.apache.org/xalan}indent-amount=0
+{http\u003a//xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToXMLStream
+{http\u003a//xml.apache.org/xalan}entities=org/apache/xml/serializer/XMLEntities
+
diff --git a/src/main/java/org/apache/xml/serializer/package.html b/src/main/java/org/apache/xml/serializer/package.html
new file mode 100644
index 0000000..c6bde48
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/package.html
@@ -0,0 +1,43 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468654 2006-10-28 07:09:23Z minchau $ -->
+<html>
+  <title>Xalan Serializer Package.</title>
+  <body>
+    <p>Processes SAX events into streams.</p>
+    
+    <p>The {@link org.apache.xml.serializer.SerializerFactory} is used to 
+    create a {@link org.apache.xml.serializer.Serializer} from a set of 
+    output properties (see {@link javax.xml.transform.OutputKeys}).</p>
+    <p>{@link org.apache.xml.serializer.ToStream} acts as the main 
+    baseclass for the Xalan serializer implementations.  
+    {@link org.apache.xml.serializer.ToHTMLStream} derives from this 
+    to implement HTML serialization.  
+    {@link org.apache.xml.serializer.ToTextStream}
+    implements plain text serialization.
+    {@link org.apache.xml.serializer.ToXMLStream}
+    implements XML serialization.
+    </p>
+    <p>XML mapping from characters to entity references is defined in 
+    XMLEntities.res.  HTML entity reference mapping is defined in HTMLEntities.res.
+    </p>
+    <p>Encoding information is defined in {@link org.apache.xml.serializer.Encodings}.</p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xml/serializer/utils/AttList.java b/src/main/java/org/apache/xml/serializer/utils/AttList.java
new file mode 100644
index 0000000..2d676fa
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/AttList.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AttList.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import org.xml.sax.Attributes;
+
+/**
+ * Wraps a DOM attribute list in a SAX Attributes.
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ * A minor changes from that package are:
+ * DOMHelper reference changed to DOM2Helper, class is not "public"
+ *  
+ * This class is not a public API, it is only public because it is 
+ * used in org.apache.xml.serializer.
+ * 
+ * @xsl.usage internal
+ */
+public final class AttList implements Attributes
+{
+
+  /** List of attribute nodes          */
+  NamedNodeMap m_attrs;
+
+  /** Index of last attribute node          */
+  int m_lastIndex;
+
+  // ARGHH!!  JAXP Uses Xerces without setting the namespace processing to ON!
+  // DOM2Helper m_dh = new DOM2Helper();
+
+  /** Local reference to DOMHelper          */
+  DOM2Helper m_dh;
+
+//  /**
+//   * Constructor AttList
+//   *
+//   *
+//   * @param attrs List of attributes this will contain
+//   */
+//  public AttList(NamedNodeMap attrs)
+//  {
+//
+//    m_attrs = attrs;
+//    m_lastIndex = m_attrs.getLength() - 1;
+//    m_dh = new DOM2Helper();
+//  }
+
+  /**
+   * Constructor AttList
+   *
+   *
+   * @param attrs List of attributes this will contain
+   * @param dh DOMHelper 
+   */
+  public AttList(NamedNodeMap attrs, DOM2Helper dh)
+  {
+    
+    m_attrs = attrs;
+    m_lastIndex = m_attrs.getLength() - 1;
+    m_dh = dh;
+  }
+
+  /**
+   * Get the number of attribute nodes in the list 
+   *
+   *
+   * @return number of attribute nodes
+   */
+  public int getLength()
+  {
+    return m_attrs.getLength();
+  }
+
+  /**
+   * Look up an attribute's Namespace URI by index.
+   *
+   * @param index The attribute index (zero-based).
+   * @return The Namespace URI, or the empty string if none
+   *         is available, or null if the index is out of
+   *         range.
+   */
+  public String getURI(int index)
+  {
+    String ns = m_dh.getNamespaceOfNode(((Attr) m_attrs.item(index)));
+    if(null == ns)
+      ns = "";
+    return ns;
+  }
+
+  /**
+   * Look up an attribute's local name by index.
+   *
+   * @param index The attribute index (zero-based).
+   * @return The local name, or the empty string if Namespace
+   *         processing is not being performed, or null
+   *         if the index is out of range.
+   */
+  public String getLocalName(int index)
+  {
+    return m_dh.getLocalNameOfNode(((Attr) m_attrs.item(index)));
+  }
+
+  /**
+   * Look up an attribute's qualified name by index.
+   *
+   *
+   * @param i The attribute index (zero-based).
+   *
+   * @return The attribute's qualified name
+   */
+  public String getQName(int i)
+  {
+    return ((Attr) m_attrs.item(i)).getName();
+  }
+
+  /**
+   * Get the attribute's node type by index
+   *
+   *
+   * @param i The attribute index (zero-based)
+   *
+   * @return the attribute's node type
+   */
+  public String getType(int i)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Get the attribute's node value by index
+   *
+   *
+   * @param i The attribute index (zero-based)
+   *
+   * @return the attribute's node value
+   */
+  public String getValue(int i)
+  {
+    return ((Attr) m_attrs.item(i)).getValue();
+  }
+
+  /**
+   * Get the attribute's node type by name
+   *
+   *
+   * @param name Attribute name
+   *
+   * @return the attribute's node type
+   */
+  public String getType(String name)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Look up an attribute's type by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty String if the
+   *        name has no Namespace URI.
+   * @param localName The local name of the attribute.
+   * @return The attribute type as a string, or null if the
+   *         attribute is not in the list or if Namespace
+   *         processing is not being performed.
+   */
+  public String getType(String uri, String localName)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Look up an attribute's value by name.
+   *
+   *
+   * @param name The attribute node's name
+   *
+   * @return The attribute node's value
+   */
+  public String getValue(String name)
+  {
+    Attr attr = ((Attr) m_attrs.getNamedItem(name));
+    return (null != attr) 
+          ? attr.getValue() : null;
+  }
+
+  /**
+   * Look up an attribute's value by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty String if the
+   *        name has no Namespace URI.
+   * @param localName The local name of the attribute.
+   * @return The attribute value as a string, or null if the
+   *         attribute is not in the list.
+   */
+  public String getValue(String uri, String localName)
+  {
+        Node a=m_attrs.getNamedItemNS(uri,localName);
+        return (a==null) ? null : a.getNodeValue();
+  }
+
+  /**
+   * Look up the index of an attribute by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty string if
+   *        the name has no Namespace URI.
+   * @param localPart The attribute's local name.
+   * @return The index of the attribute, or -1 if it does not
+   *         appear in the list.
+   */
+  public int getIndex(String uri, String localPart)
+  {
+    for(int i=m_attrs.getLength()-1;i>=0;--i)
+    {
+      Node a=m_attrs.item(i);
+      String u=a.getNamespaceURI();
+      if( (u==null ? uri==null : u.equals(uri))
+      &&
+      a.getLocalName().equals(localPart) )
+    return i;
+    }
+    return -1;
+  }
+
+  /**
+   * Look up the index of an attribute by raw XML 1.0 name.
+   *
+   * @param qName The qualified (prefixed) name.
+   * @return The index of the attribute, or -1 if it does not
+   *         appear in the list.
+   */
+  public int getIndex(String qName)
+  {
+    for(int i=m_attrs.getLength()-1;i>=0;--i)
+    {
+      Node a=m_attrs.item(i);
+      if(a.getNodeName().equals(qName) )
+    return i;
+    }
+    return -1;
+  }
+}
+
diff --git a/src/main/java/org/apache/xml/serializer/utils/DOM2Helper.java b/src/main/java/org/apache/xml/serializer/utils/DOM2Helper.java
new file mode 100644
index 0000000..cafd825
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/DOM2Helper.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOM2Helper.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class provides a DOM level 2 "helper", which provides services currently 
+ * not provided be the DOM standard.
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ * 
+ * The differences from the original class are:
+ * it doesn't extend DOMHelper, not depricated, 
+ * dropped method isNodeAfter(Node node1, Node node2)
+ * dropped method parse(InputSource)
+ * dropped method supportSAX()
+ * dropped method setDocument(doc) 
+ * dropped method checkNode(Node)
+ * dropped method getDocument()
+ * dropped method getElementByID(String id, Document doc)
+ * dropped method getParentOfNode(Node node)
+ * dropped field Document m_doc;
+ * made class non-public
+ *   
+ * This class is not a public API, it is only public because it is 
+ * used in org.apache.xml.serializer.
+ * 
+ * @xsl.usage internal
+ */
+public final class DOM2Helper
+{
+
+  /**
+   * Construct an instance.
+   */
+  public DOM2Helper(){}
+
+  /**
+   * Returns the local name of the given node, as defined by the
+   * XML Namespaces specification. This is prepared to handle documents
+   * built using DOM Level 1 methods by falling back upon explicitly
+   * parsing the node name.
+   *
+   * @param n Node to be examined
+   *
+   * @return String containing the local name, or null if the node
+   * was not assigned a Namespace.
+   */
+  public String getLocalNameOfNode(Node n)
+  {
+
+    String name = n.getLocalName();
+
+    return (null == name) ? getLocalNameOfNodeFallback(n) : name;
+  }
+  
+  /**
+   * Returns the local name of the given node. If the node's name begins
+   * with a namespace prefix, this is the part after the colon; otherwise
+   * it's the full node name.
+   * 
+   * This method is copied from org.apache.xml.utils.DOMHelper
+   *
+   * @param n the node to be examined.
+   *
+   * @return String containing the Local Name
+   */
+  private String getLocalNameOfNodeFallback(Node n)
+  {
+
+    String qname = n.getNodeName();
+    int index = qname.indexOf(':');
+
+    return (index < 0) ? qname : qname.substring(index + 1);
+  }
+
+  /**
+   * Returns the Namespace Name (Namespace URI) for the given node.
+   * In a Level 2 DOM, you can ask the node itself. Note, however, that
+   * doing so conflicts with our decision in getLocalNameOfNode not
+   * to trust the that the DOM was indeed created using the Level 2
+   * methods. If Level 1 methods were used, these two functions will
+   * disagree with each other.
+   * <p>
+   * TODO: Reconcile with getLocalNameOfNode.
+   *
+   * @param n Node to be examined
+   *
+   * @return String containing the Namespace URI bound to this DOM node
+   * at the time the Node was created.
+   */
+  public String getNamespaceOfNode(Node n)
+  {
+    return n.getNamespaceURI();
+  }
+
+  /** Field m_useDOM2getNamespaceURI is a compile-time flag which
+   *  gates some of the parser options used to build a DOM -- but 
+   * that code is commented out at this time and nobody else
+   * references it, so I've commented this out as well. */
+  //private boolean m_useDOM2getNamespaceURI = false;
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/Messages.java b/src/main/java/org/apache/xml/serializer/utils/Messages.java
new file mode 100644
index 0000000..e70fc3a
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/Messages.java
@@ -0,0 +1,366 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Messages.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * A utility class for issuing error messages.
+ * 
+ * A user of this class normally would create a singleton 
+ * instance of this class, passing the name
+ * of the message class on the constructor. For example:
+ * <CODE>
+ * static Messages x = new Messages("org.package.MyMessages");
+ * </CODE>
+ * Later the message is typically generated this way if there are no 
+ * substitution arguments:
+ * <CODE>
+ * String msg = x.createMessage(org.package.MyMessages.KEY_ONE, null); 
+ * </CODE>
+ * If there are arguments substitutions then something like this:
+ * <CODE>
+ * String filename = ...;
+ * String directory = ...;
+ * String msg = x.createMessage(org.package.MyMessages.KEY_TWO, 
+ *   new Object[] {filename, directory) ); 
+ * </CODE>
+ *  
+ * The constructor of an instance of this class must be given
+ * the class name of a class that extends java.util.ListResourceBundle 
+ * ("org.package.MyMessages" in the example above).  
+ * The name should not have any language suffix 
+ * which will be added automatically by this utility class.
+ * 
+ * The message class ("org.package.MyMessages")
+ * must define the abstract method getContents() that is
+ * declared in its base class, for example:
+ * <CODE>
+ * public Object[][] getContents() {return contents;}
+ * </CODE>
+ * 
+ * It is suggested that the message class expose its
+ * message keys like this:
+ * <CODE>
+ *   public static final String KEY_ONE = "KEY1";
+ *   public static final String KEY_TWO = "KEY2";
+ *   . . . 
+ * </CODE>
+ * and used through their names (KEY_ONE ...) rather than
+ * their values ("KEY1" ...).
+ * 
+ * The field contents (returned by getContents()
+ * should be initialized something like this:
+ * <CODE>
+ * public static final Object[][] contents = {
+ * { KEY_ONE, "Something has gone wrong!" },
+ * { KEY_TWO, "The file ''{0}'' does not exist in directory ''{1}''." },
+ * . . .
+ * { KEY_N, "Message N" }  }
+ * </CODE>
+ * 
+ * Where that section of code with the KEY to Message mappings
+ * (where the message classes 'contents' field is initialized)
+ * can have the Message strings translated in an alternate language
+ * in a errorResourceClass with a language suffix.
+ * 
+ * More sophisticated use of this class would be to pass null
+ * when contructing it, but then call loadResourceBundle()
+ * before creating any messages.
+ * 
+ * This class is not a public API, it is only public because it is 
+ * used in org.apache.xml.serializer.
+ *
+ *  @xsl.usage internal
+ */
+public final class Messages
+{
+    /** The local object to use.  */
+    private final Locale m_locale = Locale.getDefault();
+
+    /** The language specific resource object for messages.  */
+    private ListResourceBundle m_resourceBundle;
+
+    /** The class name of the error message string table with no language suffix. */
+    private String m_resourceBundleName;
+
+
+
+    /**
+     * Constructor.
+     * @param resourceBundle the class name of the ListResourceBundle
+     * that the instance of this class is associated with and will use when
+     * creating messages.
+     * The class name is without a language suffix. If the value passed
+     * is null then loadResourceBundle(errorResourceClass) needs to be called
+     * explicitly before any messages are created.
+     * 
+     * @xsl.usage internal
+     */
+    Messages(String resourceBundle)
+    {
+
+        m_resourceBundleName = resourceBundle;
+    }
+    
+    /*
+     * Set the Locale object to use. If this method is not called the
+     * default locale is used. This method needs to be called before
+     * loadResourceBundle().
+     * 
+     * @param locale non-null reference to Locale object.
+     * @xsl.usage internal
+     */
+//    public void setLocale(Locale locale)
+//    {
+//        m_locale = locale;
+//    }
+
+    /**
+     * Get the Locale object that is being used.
+     * 
+     * @return non-null reference to Locale object.
+     * @xsl.usage internal
+     */
+    private Locale getLocale()
+    {
+        return m_locale;
+    }
+
+    /**
+     * Get the ListResourceBundle being used by this Messages instance which was
+     * previously set by a call to loadResourceBundle(className)
+     * @xsl.usage internal
+     */
+    private ListResourceBundle getResourceBundle()
+    {
+        return m_resourceBundle;
+    }
+
+    /**
+     * Creates a message from the specified key and replacement
+     * arguments, localized to the given locale.
+     *
+     * @param msgKey  The key for the message text.
+     * @param args    The arguments to be used as replacement text
+     * in the message created.
+     *
+     * @return The formatted message string.
+     * @xsl.usage internal
+     */
+    public final String createMessage(String msgKey, Object args[])
+    {
+        if (m_resourceBundle == null)
+            m_resourceBundle = loadResourceBundle(m_resourceBundleName);
+
+        if (m_resourceBundle != null)
+        {
+            return createMsg(m_resourceBundle, msgKey, args);
+        }
+        else
+            return "Could not load the resource bundles: "+ m_resourceBundleName;
+    }
+
+    /**
+     * Creates a message from the specified key and replacement
+     * arguments, localized to the given locale.
+     *
+     * @param errorCode The key for the message text.
+     *
+     * @param fResourceBundle The resource bundle to use.
+     * @param msgKey  The message key to use.
+     * @param args      The arguments to be used as replacement text
+     *                  in the message created.
+     *
+     * @return The formatted message string.
+     * @xsl.usage internal
+     */
+    private final String createMsg(
+        ListResourceBundle fResourceBundle,
+        String msgKey,
+        Object args[]) //throws Exception
+    {
+
+        String fmsg = null;
+        boolean throwex = false;
+        String msg = null;
+
+        if (msgKey != null)
+            msg = fResourceBundle.getString(msgKey);
+        else
+            msgKey = "";
+
+        if (msg == null)
+        {
+            throwex = true;
+            /* The message is not in the bundle . . . this is bad,
+             * so try to get the message that the message is not in the bundle
+             */
+            try
+            {
+
+                msg =
+                    java.text.MessageFormat.format(
+                        MsgKey.BAD_MSGKEY,
+                        new Object[] { msgKey, m_resourceBundleName });
+            }
+            catch (Exception e)
+            {
+                /* even the message that the message is not in the bundle is
+                 * not there ... this is really bad
+                 */
+                msg =
+                    "The message key '"
+                        + msgKey
+                        + "' is not in the message class '"
+                        + m_resourceBundleName+"'";
+            }
+        }
+        else if (args != null)
+        {
+            try
+            {
+                // Do this to keep format from crying.
+                // This is better than making a bunch of conditional
+                // code all over the place.
+                int n = args.length;
+
+                for (int i = 0; i < n; i++)
+                {
+                    if (null == args[i])
+                        args[i] = "";
+                }
+
+                fmsg = java.text.MessageFormat.format(msg, args);
+                // if we get past the line above we have create the message ... hurray!
+            }
+            catch (Exception e)
+            {
+                throwex = true;
+                try
+                {
+                    // Get the message that the format failed.
+                    fmsg =
+                        java.text.MessageFormat.format(
+                            MsgKey.BAD_MSGFORMAT,
+                            new Object[] { msgKey, m_resourceBundleName });
+                    fmsg += " " + msg;
+                }
+                catch (Exception formatfailed)
+                {
+                    // We couldn't even get the message that the format of
+                    // the message failed ... so fall back to English.
+                    fmsg =
+                        "The format of message '"
+                            + msgKey
+                            + "' in message class '"
+                            + m_resourceBundleName
+                            + "' failed.";
+                }
+            }
+        }
+        else
+            fmsg = msg;
+
+        if (throwex)
+        {
+            throw new RuntimeException(fmsg);
+        }
+
+        return fmsg;
+    }
+
+    /**
+     * Return a named ResourceBundle for a particular locale.  This method mimics the behavior
+     * of ResourceBundle.getBundle().
+     * 
+     * @param className the name of the class that implements ListResourceBundle,
+     * without language suffix.
+     * @return the ResourceBundle
+     * @throws MissingResourceException
+     * @xsl.usage internal
+     */
+    private ListResourceBundle loadResourceBundle(String resourceBundle)
+        throws MissingResourceException
+    {
+        m_resourceBundleName = resourceBundle;
+        Locale locale = getLocale();
+
+        ListResourceBundle lrb;
+
+        try
+        {
+
+            ResourceBundle rb =
+                ResourceBundle.getBundle(m_resourceBundleName, locale);
+            lrb = (ListResourceBundle) rb;
+        }
+        catch (MissingResourceException e)
+        {
+            try // try to fall back to en_US if we can't load
+                {
+
+                // Since we can't find the localized property file,
+                // fall back to en_US.
+                lrb =
+                    (ListResourceBundle) ResourceBundle.getBundle(
+                        m_resourceBundleName,
+                        new Locale("en", "US"));
+            }
+            catch (MissingResourceException e2)
+            {
+
+                // Now we are really in trouble.
+                // very bad, definitely very bad...not going to get very far
+                throw new MissingResourceException(
+                    "Could not load any resource bundles." + m_resourceBundleName,
+                    m_resourceBundleName,
+                    "");
+            }
+        }
+        m_resourceBundle = lrb;
+        return lrb;
+    }
+
+    /**
+     * Return the resource file suffic for the indicated locale
+     * For most locales, this will be based the language code.  However
+     * for Chinese, we do distinguish between Taiwan and PRC
+     *
+     * @param locale the locale
+     * @return an String suffix which can be appended to a resource name
+     * @xsl.usage internal
+     */
+    private static String getResourceSuffix(Locale locale)
+    {
+
+        String suffix = "_" + locale.getLanguage();
+        String country = locale.getCountry();
+
+        if (country.equals("TW"))
+            suffix += "_" + country;
+
+        return suffix;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/MsgKey.java b/src/main/java/org/apache/xml/serializer/utils/MsgKey.java
new file mode 100644
index 0000000..8ec6336
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/MsgKey.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: MsgKey.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+/**
+ * This class is not a public API,
+ * It is used internally by serializer and is public,
+ * in the Java sense, only because its use crosses
+ * package boundaries.
+ * <p>
+ * This class holds only the message keys used
+ * when generating messages.
+ */
+public class MsgKey {
+
+    /** An internal error with the messages,
+     * this is the message to use if the message key can't be found 
+     */
+    public static final String BAD_MSGKEY = "BAD_MSGKEY";
+
+    /** 
+     * An internal error with the messages,
+     * this is the message to use if the message format operation failed.  
+     */
+    public static final String BAD_MSGFORMAT = "BAD_MSGFORMAT";
+
+    public static final String ER_RESOURCE_COULD_NOT_FIND =
+        "ER_RESOURCE_COULD_NOT_FIND";
+    public static final String ER_RESOURCE_COULD_NOT_LOAD =
+        "ER_RESOURCE_COULD_NOT_LOAD";
+    public static final String ER_BUFFER_SIZE_LESSTHAN_ZERO =
+        "ER_BUFFER_SIZE_LESSTHAN_ZERO";
+    public static final String ER_INVALID_UTF16_SURROGATE =
+        "ER_INVALID_UTF16_SURROGATE";
+    public static final String ER_OIERROR = "ER_OIERROR";
+    public static final String ER_NAMESPACE_PREFIX = "ER_NAMESPACE_PREFIX";
+    public static final String ER_STRAY_ATTRIBUTE = "ER_STRAY_ATTRIBUTE";
+    public static final String ER_STRAY_NAMESPACE = "ER_STRAY_NAMESPACE";
+    public static final String ER_COULD_NOT_LOAD_RESOURCE =
+        "ER_COULD_NOT_LOAD_RESOURCE";
+    public static final String ER_COULD_NOT_LOAD_METHOD_PROPERTY =
+        "ER_COULD_NOT_LOAD_METHOD_PROPERTY";
+    public static final String ER_SERIALIZER_NOT_CONTENTHANDLER =
+        "ER_SERIALIZER_NOT_CONTENTHANDLER";
+    public static final String ER_ILLEGAL_ATTRIBUTE_POSITION =
+        "ER_ILLEGAL_ATTRIBUTE_POSITION";
+    public static final String ER_ILLEGAL_CHARACTER = "ER_ILLEGAL_CHARACTER";
+
+    public static final String ER_INVALID_PORT = "ER_INVALID_PORT";
+    public static final String ER_PORT_WHEN_HOST_NULL =
+        "ER_PORT_WHEN_HOST_NULL";
+    public static final String ER_HOST_ADDRESS_NOT_WELLFORMED =
+        "ER_HOST_ADDRESS_NOT_WELLFORMED";
+    public static final String ER_SCHEME_NOT_CONFORMANT =
+        "ER_SCHEME_NOT_CONFORMANT";
+    public static final String ER_SCHEME_FROM_NULL_STRING =
+        "ER_SCHEME_FROM_NULL_STRING";
+    public static final String ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE =
+        "ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE";
+    public static final String ER_PATH_INVALID_CHAR = "ER_PATH_INVALID_CHAR";
+    public static final String ER_NO_SCHEME_INURI = "ER_NO_SCHEME_INURI";
+    public static final String ER_FRAG_INVALID_CHAR = "ER_FRAG_INVALID_CHAR";
+    public static final String ER_FRAG_WHEN_PATH_NULL =
+        "ER_FRAG_WHEN_PATH_NULL";
+    public static final String ER_FRAG_FOR_GENERIC_URI =
+        "ER_FRAG_FOR_GENERIC_URI";
+    public static final String ER_NO_SCHEME_IN_URI = "ER_NO_SCHEME_IN_URI";
+    public static final String ER_CANNOT_INIT_URI_EMPTY_PARMS =
+        "ER_CANNOT_INIT_URI_EMPTY_PARMS";
+    public static final String ER_NO_FRAGMENT_STRING_IN_PATH =
+        "ER_NO_FRAGMENT_STRING_IN_PATH";
+    public static final String ER_NO_QUERY_STRING_IN_PATH =
+        "ER_NO_QUERY_STRING_IN_PATH";
+    public static final String ER_NO_PORT_IF_NO_HOST = "ER_NO_PORT_IF_NO_HOST";
+    public static final String ER_NO_USERINFO_IF_NO_HOST =
+        "ER_NO_USERINFO_IF_NO_HOST";
+    public static final String ER_SCHEME_REQUIRED = "ER_SCHEME_REQUIRED";
+    public static final String ER_XML_VERSION_NOT_SUPPORTED = "ER_XML_VERSION_NOT_SUPPORTED";
+    public static final String ER_FACTORY_PROPERTY_MISSING = "ER_FACTORY_PROPERTY_MISSING";
+    public static final String ER_ENCODING_NOT_SUPPORTED = "ER_ENCODING_NOT_SUPPORTED";
+    // DOM Exceptions
+    public static final String ER_FEATURE_NOT_FOUND = "FEATURE_NOT_FOUND";
+    public static final String ER_FEATURE_NOT_SUPPORTED = "FEATURE_NOT_SUPPORTED";
+    public static final String ER_STRING_TOO_LONG = "DOMSTRING_SIZE_ERR";
+    public static final String ER_TYPE_MISMATCH_ERR = "TYPE_MISMATCH_ERR";  
+    
+    // DOM Level 3 load and save messages
+    public static final String ER_NO_OUTPUT_SPECIFIED = "no-output-specified";   
+    public static final String ER_UNSUPPORTED_ENCODING = "unsupported-encoding";
+    public static final String ER_ELEM_UNBOUND_PREFIX_IN_ENTREF = "unbound-prefix-in-entity-reference";
+    public static final String ER_ATTR_UNBOUND_PREFIX_IN_ENTREF = "unbound-prefix-in-entity-reference";
+    public static final String ER_CDATA_SECTIONS_SPLIT = "cdata-sections-splitted";
+    public static final String ER_WF_INVALID_CHARACTER = "wf-invalid-character";
+    public static final String ER_WF_INVALID_CHARACTER_IN_NODE_NAME = "wf-invalid-character-in-node-name";
+    
+    // DOM Level 3 Implementation specific Exceptions
+    public static final String ER_UNABLE_TO_SERIALIZE_NODE = "ER_UNABLE_TO_SERIALIZE_NODE";
+    public static final String ER_WARNING_WF_NOT_CHECKED = "ER_WARNING_WF_NOT_CHECKED";
+    
+    public static final String ER_WF_INVALID_CHARACTER_IN_COMMENT = "ER_WF_INVALID_CHARACTER_IN_COMMENT";
+    public static final String ER_WF_INVALID_CHARACTER_IN_PI = "ER_WF_INVALID_CHARACTER_IN_PI";
+    public static final String ER_WF_INVALID_CHARACTER_IN_CDATA = "ER_WF_INVALID_CHARACTER_IN_CDATA";
+    public static final String ER_WF_INVALID_CHARACTER_IN_TEXT = "ER_WF_INVALID_CHARACTER_IN_TEXT";
+    public static final String ER_WF_DASH_IN_COMMENT = "ER_WF_DASH_IN_COMMENT";
+    public static final String ER_WF_LT_IN_ATTVAL = "ER_WF_LT_IN_ATTVAL";
+    public static final String ER_WF_REF_TO_UNPARSED_ENT = "ER_WF_REF_TO_UNPARSED_ENT";
+    public static final String ER_WF_REF_TO_EXTERNAL_ENT =  "ER_WF_REF_TO_EXTERNAL_ENT";
+    public static final String ER_NS_PREFIX_CANNOT_BE_BOUND =  "ER_NS_PREFIX_CANNOT_BE_BOUND";
+    public static final String ER_NULL_LOCAL_ELEMENT_NAME = "ER_NULL_LOCAL_ELEMENT_NAME";
+    public static final String ER_NULL_LOCAL_ATTR_NAME = "ER_NULL_LOCAL_ATTR_NAME";
+    public static final String ER_WRITING_INTERNAL_SUBSET = "ER_WRITING_INTERNAL_SUBSET";
+
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages.java
new file mode 100644
index 0000000..997bfc1
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated. 
+ * 
+ * This class is not a public API, it is only public because it is 
+ * used in the serializer.
+ * 
+ * @xsl.usage internal
+ */
+public class SerializerMessages extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+    
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+    
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "The message key ''{0}'' is not in the message class ''{1}''" },
+                
+            {   MsgKey.BAD_MSGFORMAT,
+                "The format of message ''{0}'' in message class ''{1}'' failed." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "The serializer class ''{0}'' does not implement org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "The resource [ {0} ] could not be found.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "The resource [ {0} ] could not load: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO, 
+                    "Buffer size <=0" }, 
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Invalid UTF-16 surrogate detected: {0} ?" },
+
+            {   MsgKey.ER_OIERROR, 
+                "IO error" }, 
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Cannot add attribute {0} after child nodes or before an element is produced.  Attribute will be ignored." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */ 
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Namespace for prefix ''{0}'' has not been declared." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */ 
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Attribute ''{0}'' outside of element." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */ 
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Namespace declaration ''{0}''=''{1}'' outside of element." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Could not load ''{0}'' (check CLASSPATH), now using just the defaults" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Attempt to output character of integral value {0} that is not represented in specified output encoding of {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Could not load the propery file ''{0}'' for output method ''{1}'' (check CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT, 
+                "Invalid port number" }, 
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Port cannot be set when host is null" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Host is not a well formed address" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "The scheme is not conformant." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Cannot set scheme from null string" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Path contains invalid escape sequence" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Path contains invalid character: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment contains invalid character" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Fragment cannot be set when path is null" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment can only be set for a generic URI" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI, 
+                "No scheme found in URI" }, 
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Cannot initialize URI with empty parameters" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Fragment cannot be specified in both the path and fragment" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Query string cannot be specified in path and query string" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Port may not be specified if host is not specified" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Userinfo may not be specified if host is not specified" },
+
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Warning:  The version of the output document is requested to be ''{0}''.  This version of XML is not supported.  The version of the output document will be ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED, 
+                "Scheme is required!" },
+                
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */    
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "The Properties object passed to the SerializerFactory does not have a ''{0}'' property." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Warning:  The encoding ''{0}'' is not supported by the Java runtime." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "The parameter ''{0}'' is not recognized."},
+            
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "The parameter ''{0}'' is recognized but the requested value cannot be set."},
+            
+             {MsgKey.ER_STRING_TOO_LONG,
+             "The resulting string is too long to fit in a DOMString: ''{0}''."},  
+            
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "The value type for this parameter name is incompatible with the expected value type."},
+            
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "The output destination for data to be written to was null."},
+            
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "An unsupported encoding is encountered."},
+            
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "The node could not be serialized."},
+            
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT, 
+             "The CDATA Section contains one or more termination markers ']]>'."},
+            
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED, 
+                 "An instance of the Well-Formedness checker could not be created.  The well-formed parameter was set to true but well-formedness checking can not be performed."    
+             },
+            
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "The node ''{0}'' contains invalid XML characters."
+             },
+            
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "An invalid XML character (Unicode: 0x{0}) was found in the comment."
+             },
+            
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "An invalid XML character (Unicode: 0x{0}) was found in the processing instructiondata."
+             },             
+            
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "An invalid XML character (Unicode: 0x{0}) was found in the contents of the CDATASection."
+             },
+            
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "An invalid XML character (Unicode: 0x{0}) was found in the node''s character data content."
+             },                        
+            
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "An invalid XML character(s) was found in the {0} node named ''{1}''."
+             },
+            
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "The string \"--\" is not permitted within comments."
+             },
+            
+             {MsgKey.ER_WF_LT_IN_ATTVAL,  
+                 "The value of attribute \"{1}\" associated with an element type \"{0}\" must not contain the ''<'' character." 
+             },
+            
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,  
+                 "The unparsed entity reference \"&{0};\" is not permitted." 
+             },
+            
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,  
+                 "The external entity reference \"&{0};\" is not permitted in an attribute value." 
+             },             
+            
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "The prefix \"{0}\" can not be bound to namespace \"{1}\"."
+             },
+            
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "The local name of element \"{0}\" is null."
+             },
+            
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "The local name of attr \"{0}\" is null."
+             },             
+            
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "The replacement text of the entity node \"{0}\" contains an element node \"{1}\" with an unbound prefix \"{2}\"."
+             },
+            
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "The replacement text of the entity node \"{0}\" contains an attribute node \"{1}\" with an unbound prefix \"{2}\"."
+             },
+             
+             { MsgKey.ER_WRITING_INTERNAL_SUBSET,
+                 "An error occured while writing the internal subset."
+             },
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ca.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ca.java
new file mode 100644
index 0000000..ad5b3ae
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ca.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_ca.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_ca extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "La clau del missatge ''{0}'' no est\u00e0 a la classe del missatge ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "El format del missatge ''{0}'' a la classe del missatge ''{1}'' ha fallat." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "La classe de serialitzador ''{0}'' no implementa org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "No s''ha trobat el recurs [ {0} ].\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "No s''ha pogut carregar el recurs [ {0} ]: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Grand\u00e0ria del buffer <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "S''ha detectat un suplent UTF-16 no v\u00e0lid: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Error d'E/S" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "No es pot afegir l''atribut {0} despr\u00e9s dels nodes subordinats o abans que es produeixi un element. Es passar\u00e0 per alt l''atribut." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "No s''ha declarat l''espai de noms pel prefix ''{0}''." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "L''atribut ''{0}'' es troba fora de l''element." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "La declaraci\u00f3 de l''espai de noms ''{0}''=''{1}'' es troba fora de l''element." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "No s''ha pogut carregar ''{0}'' (comproveu CLASSPATH), ara s''est\u00e0 fent servir els valors per defecte." },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "S''ha intentat un car\u00e0cter de sortida del valor integral {0} que no est\u00e0 representat a una codificaci\u00f3 de sortida especificada de {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "No s''ha pogut carregar el fitxer de propietats ''{0}'' del m\u00e8tode de sortida ''{1}'' (comproveu CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "N\u00famero de port no v\u00e0lid" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "El port no es pot establir quan el sistema principal \u00e9s nul" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "El format de l'adre\u00e7a del sistema principal no \u00e9s el correcte" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "L'esquema no t\u00e9 conformitat." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "No es pot establir un esquema des d'una cadena nul\u00b7la" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "La via d'acc\u00e9s cont\u00e9 una seq\u00fc\u00e8ncia d'escapament no v\u00e0lida" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "La via d''acc\u00e9s cont\u00e9 un car\u00e0cter no v\u00e0lid {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "El fragment cont\u00e9 un car\u00e0cter no v\u00e0lid" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "El fragment no es pot establir si la via d'acc\u00e9s \u00e9s nul\u00b7la" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "El fragment nom\u00e9s es pot establir per a un URI gen\u00e8ric" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "No s'ha trobat cap esquema a l'URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "No es pot inicialitzar l'URI amb par\u00e0metres buits" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "No es pot especificar un fragment tant en la via d'acc\u00e9s com en el fragment" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "No es pot especificar una cadena de consulta en la via d'acc\u00e9s i la cadena de consulta" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "No es pot especificar el port si no s'especifica el sistema principal" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "No es pot especificar informaci\u00f3 de l'usuari si no s'especifica el sistema principal" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Av\u00eds: la versi\u00f3 del document de sortida s''ha sol\u00b7licitat que sigui ''{0}''. Aquesta versi\u00f3 de XML no est\u00e0 suportada. La versi\u00f3 del document de sortida ser\u00e0 ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Es necessita l'esquema" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "L''objecte de propietats passat a SerializerFactory no t\u00e9 cap propietat ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Av\u00eds: el temps d''execuci\u00f3 de Java no d\u00f3na suport a la codificaci\u00f3 ''{0}''." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "El par\u00e0metre ''{0}'' no es reconeix."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "El par\u00e0metre ''{0}'' es reconeix per\u00f2 el valor sol\u00b7licitat no es pot establir."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "La cadena resultant \u00e9s massa llarga per cabre en una DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "El tipus de valor per a aquest nom de par\u00e0metre \u00e9s incompatible amb el tipus de valor esperat."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "La destinaci\u00f3 de sortida per a les dades que s'ha d'escriure era nul\u00b7la."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "S'ha trobat una codificaci\u00f3 no suportada."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "El node no s'ha pogut serialitzat."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "La secci\u00f3 CDATA cont\u00e9 un o m\u00e9s marcadors d'acabament ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "No s'ha pogut crear cap inst\u00e0ncia per comprovar si t\u00e9 un format correcte o no. El par\u00e0metre del tipus ben format es va establir en cert, per\u00f2 la comprovaci\u00f3 de format no s'ha pogut realitzar."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "El node ''{0}'' cont\u00e9 car\u00e0cters XML no v\u00e0lids."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "S''ha trobat un car\u00e0cter XML no v\u00e0lid (Unicode: 0x{0}) en el comentari."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "S''ha trobat un car\u00e0cter XML no v\u00e0lid (Unicode: 0x{0}) en les dades d''instrucci\u00f3 de proc\u00e9s."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "S''ha trobat un car\u00e0cter XML no v\u00e0lid (Unicode: 0x''{0})'' en els continguts de la CDATASection."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "S''ha trobat un car\u00e0cter XML no v\u00e0lid (Unicode: 0x''{0})'' en el contingut de dades de car\u00e0cter del node."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "S''han trobat car\u00e0cters XML no v\u00e0lids al node {0} anomenat ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "La cadena \"--\" no est\u00e0 permesa dins dels comentaris."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "El valor d''atribut \"{1}\" associat amb un tipus d''element \"{0}\" no pot contenir el car\u00e0cter ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "La refer\u00e8ncia de l''entitat no analitzada \"&{0};\" no est\u00e0 permesa."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "La refer\u00e8ncia externa de l''entitat \"&{0};\" no est\u00e0 permesa en un valor d''atribut."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "El prefix \"{0}\" no es pot vincular a l''espai de noms \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "El nom local de l''element \"{0}\" \u00e9s nul."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "El nom local d''atr \"{0}\" \u00e9s nul."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "El text de recanvi del node de l''entitat \"{0}\" cont\u00e9 un node d''element \"{1}\" amb un prefix de no enlla\u00e7at \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "El text de recanvi del node de l''entitat \"{0}\" cont\u00e9 un node d''atribut \"{1}\" amb un prefix de no enlla\u00e7at \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_cs.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_cs.java
new file mode 100644
index 0000000..12b61bc
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_cs.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_cs.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_cs extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "Kl\u00ed\u010d zpr\u00e1vy ''{0}'' nen\u00ed obsa\u017een ve t\u0159\u00edd\u011b zpr\u00e1v ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Form\u00e1t zpr\u00e1vy ''{0}'' ve t\u0159\u00edd\u011b zpr\u00e1v ''{1}'' selhal. " },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "T\u0159\u00edda serializace ''{0}'' neimplementuje obslu\u017en\u00fd program org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Nelze naj\u00edt zdroj [ {0} ].\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Nelze zav\u00e9st zdroj [ {0} ]: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Velikost vyrovn\u00e1vac\u00ed pam\u011bti <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Byla zji\u0161t\u011bna neplatn\u00e1 n\u00e1hrada UTF-16: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Chyba vstupu/v\u00fdstupu" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Nelze p\u0159idat atribut {0} po uzlech potomk\u016f ani p\u0159ed t\u00edm, ne\u017e je vytvo\u0159en prvek. Atribut bude ignorov\u00e1n." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Obor n\u00e1zv\u016f pro p\u0159edponu ''{0}'' nebyl deklarov\u00e1n." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atribut ''{0}'' se nach\u00e1z\u00ed vn\u011b prvku." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Deklarace oboru n\u00e1zv\u016f ''{0}''=''{1}'' se nach\u00e1z\u00ed vn\u011b prvku." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Nelze zav\u00e9st prost\u0159edek ''{0}'' (zkontrolujte prom\u011bnnou CLASSPATH) - budou pou\u017eity pouze v\u00fdchoz\u00ed prost\u0159edky" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Byl proveden pokus o v\u00fdstup znaku s celo\u010d\u00edselnou hodnotou {0}, kter\u00e1 nen\u00ed reprezentov\u00e1na v ur\u010den\u00e9m v\u00fdstupn\u00edm k\u00f3dov\u00e1n\u00ed {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Nelze na\u010d\u00edst soubor vlastnost\u00ed ''{0}'' pro v\u00fdstupn\u00ed metodu ''{1}'' (zkontrolujte prom\u011bnnou CLASSPATH)." },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Neplatn\u00e9 \u010d\u00edslo portu." },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "M\u00e1-li hostitel hodnotu null, nelze nastavit port." },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Adresa hostitele m\u00e1 nespr\u00e1vn\u00fd form\u00e1t." },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Sch\u00e9ma nevyhovuje." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Nelze nastavit sch\u00e9ma \u0159et\u011bzce s hodnotou null." },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Cesta obsahuje neplatnou escape sekvenci" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Cesta obsahuje neplatn\u00fd znak: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment obsahuje neplatn\u00fd znak." },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "M\u00e1-li cesta hodnotu null, nelze nastavit fragment." },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment lze nastavit jen u generick\u00e9ho URI." },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "V URI nebylo nalezeno \u017e\u00e1dn\u00e9 sch\u00e9ma" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "URI nelze inicializovat s pr\u00e1zdn\u00fdmi parametry." },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Fragment nelze ur\u010dit z\u00e1rove\u0148 v cest\u011b i ve fragmentu." },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "V \u0159et\u011bzci cesty a dotazu nelze zadat \u0159et\u011bzec dotazu." },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Nen\u00ed-li ur\u010den hostitel, nelze zadat port." },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Nen\u00ed-li ur\u010den hostitel, nelze zadat \u00fadaje o u\u017eivateli." },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Varov\u00e1n\u00ed: Je po\u017eadov\u00e1na verze ''{0}'' v\u00fdstupn\u00edho dokumentu. Tato verze form\u00e1tu XML nen\u00ed podporov\u00e1na. Bude pou\u017eita verze ''1.0'' v\u00fdstupn\u00edho dokumentu. " },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Je vy\u017eadov\u00e1no sch\u00e9ma!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "Objekt vlastnost\u00ed p\u0159edan\u00fd faktorii SerializerFactory neobsahuje vlastnost ''{0}''. " },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Varov\u00e1n\u00ed: K\u00f3dov\u00e1n\u00ed ''{0}'' nen\u00ed v b\u011bhov\u00e9m prost\u0159ed\u00ed Java podporov\u00e1no." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Parametr ''{0}'' nebyl rozpozn\u00e1n."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Parametr ''{0}'' byl rozpozn\u00e1n, ale nelze nastavit po\u017eadovanou hodnotu."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "V\u00fdsledn\u00fd \u0159et\u011bzec je p\u0159\u00edli\u0161 dlouh\u00fd pro \u0159et\u011bzec DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Typ hodnoty pro tento n\u00e1zev parametru nen\u00ed kompatibiln\u00ed s o\u010dek\u00e1van\u00fdm typem hodnoty."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "C\u00edlov\u00e9 um\u00edst\u011bn\u00ed v\u00fdstupu pro data ur\u010den\u00e1 k z\u00e1pisu je rovno hodnot\u011b Null. "},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Bylo nalezeno nepodporovan\u00e9 k\u00f3dov\u00e1n\u00ed."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Nelze prov\u00e9st serializaci uzlu. "},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "Sekce CDATA obsahuje jednu nebo v\u00edce ukon\u010dovac\u00edch zna\u010dek ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Nelze vytvo\u0159it instanci modulu pro kontrolu spr\u00e1vn\u00e9ho utvo\u0159en\u00ed. Parametr spr\u00e1vn\u00e9ho utvo\u0159en\u00ed byl nastaven na hodnotu true, nepoda\u0159ilo se v\u0161ak zkontrolovat spr\u00e1vnost utvo\u0159en\u00ed. "
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Uzel ''{0}'' obsahuje neplatn\u00e9 znaky XML. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "V pozn\u00e1mce byl zji\u0161t\u011bn neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "V datech instrukce zpracov\u00e1n\u00ed byl nalezen neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "V odd\u00edlu CDATASection byl nalezen neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "V obsahu znakov\u00fdch dat uzlu byl nalezen neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "V objektu {0} s n\u00e1zvem ''{1}'' byl nalezen neplatn\u00fd znak XML. "
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "V pozn\u00e1mk\u00e1ch nen\u00ed povolen \u0159et\u011bzec \"--\"."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Hodnota atributu \"{1}\" souvisej\u00edc\u00edho s typem prvku \"{0}\" nesm\u00ed obsahovat znak ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Odkaz na neanalyzovanou entitu \"&{0};\" nen\u00ed povolen."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Extern\u00ed odkaz na entitu \"&{0};\" nen\u00ed v hodnot\u011b atributu povolen."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "P\u0159edpona \"{0}\" nesm\u00ed b\u00fdt v\u00e1zan\u00e1 k oboru n\u00e1zv\u016f \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Lok\u00e1ln\u00ed n\u00e1zev prvku \"{0}\" m\u00e1 hodnotu Null. "
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Lok\u00e1ln\u00ed n\u00e1zev atributu \"{0}\" m\u00e1 hodnotu Null. "
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "Nov\u00fd text uzlu entity \"{0}\" obsahuje uzel prvku \"{1}\" s nesv\u00e1zanou p\u0159edponou \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Nov\u00fd text uzlu entity \"{0}\" obsahuje uzel atributu \"{1}\" s nesv\u00e1zanou p\u0159edponou \"{2}\". "
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_de.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_de.java
new file mode 100644
index 0000000..e583e87
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_de.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_de.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_de extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "Der Nachrichtenschl\u00fcssel ''{0}'' ist nicht in der Nachrichtenklasse ''{1}'' enthalten." },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Das Format der Nachricht ''{0}'' in der Nachrichtenklasse ''{1}'' ist fehlgeschlagen." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "Die Parallel-Seriell-Umsetzerklasse ''{0}'' implementiert org.xml.sax.ContentHandler nicht." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Die Ressource [ {0} ] konnte nicht gefunden werden.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Die Ressource [ {0} ] konnte nicht geladen werden: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Puffergr\u00f6\u00dfe <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Ung\u00fcltige UTF-16-Ersetzung festgestellt: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "E/A-Fehler" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Attribut {0} kann nicht nach Kindknoten oder vor dem Erstellen eines Elements hinzugef\u00fcgt werden.  Das Attribut wird ignoriert." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Der Namensbereich f\u00fcr Pr\u00e4fix ''{0}'' wurde nicht deklariert." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Attribut ''{0}'' befindet sich nicht in einem Element." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Namensbereichdeklaration ''{0}''=''{1}'' befindet sich nicht in einem Element." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "''{0}'' konnte nicht geladen werden (CLASSPATH pr\u00fcfen). Es werden die Standardwerte verwendet." },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Es wurde versucht, ein Zeichen des Integralwerts {0} auszugeben, der nicht in der angegebenen Ausgabeverschl\u00fcsselung von {1} dargestellt ist." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Die Merkmaldatei ''{0}'' konnte f\u00fcr die Ausgabemethode ''{1}'' nicht geladen werden (CLASSPATH pr\u00fcfen)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Ung\u00fcltige Portnummer" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Der Port kann nicht festgelegt werden, wenn der Host gleich Null ist." },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Der Host ist keine syntaktisch korrekte Adresse." },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Das Schema ist nicht angepasst." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Schema kann nicht von Nullzeichenfolge festgelegt werden." },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Der Pfad enth\u00e4lt eine ung\u00fcltige Escapezeichenfolge." },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Pfad enth\u00e4lt ung\u00fcltiges Zeichen: {0}." },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment enth\u00e4lt ein ung\u00fcltiges Zeichen." },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Fragment kann nicht festgelegt werden, wenn der Pfad gleich Null ist." },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment kann nur f\u00fcr eine generische URI (Uniform Resource Identifier) festgelegt werden." },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Kein Schema gefunden in URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "URI (Uniform Resource Identifier) kann nicht mit leeren Parametern initialisiert werden." },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Fragment kann nicht im Pfad und im Fragment angegeben werden." },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Abfragezeichenfolge kann nicht im Pfad und in der Abfragezeichenfolge angegeben werden." },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Der Port kann nicht angegeben werden, wenn der Host nicht angegeben wurde." },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Benutzerinformationen k\u00f6nnen nicht angegeben werden, wenn der Host nicht angegeben wurde." },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Warnung: Die Version des Ausgabedokuments muss ''{0}'' lauten.  Diese XML-Version wird nicht unterst\u00fctzt.  Die Version des Ausgabedokuments ist ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Schema ist erforderlich!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "Das an SerializerFactory \u00fcbermittelte Merkmalobjekt weist kein Merkmal ''{0}'' auf." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Warnung:  Die Codierung ''{0}'' wird von Java Runtime nicht unterst\u00fctzt." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Der Parameter ''{0}'' wird nicht erkannt."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Der Parameter ''{0}'' wird erkannt, der angeforderte Wert kann jedoch nicht festgelegt werden."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "Die Ergebniszeichenfolge ist zu lang f\u00fcr eine DOM-Zeichenfolge: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Der Werttyp f\u00fcr diesen Parameternamen ist nicht kompatibel mit dem erwarteten Werttyp."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Das Ausgabeziel f\u00fcr die zu schreibenden Daten war leer."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Eine nicht unterst\u00fctzte Codierung wurde festgestellt."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Der Knoten konnte nicht serialisiert werden."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "Der Abschnitt CDATA enth\u00e4lt mindestens eine Beendigungsmarkierung ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Eine Instanz des Pr\u00fcfprogramms f\u00fcr korrekte Formatierung konnte nicht erstellt werden.  F\u00fcr den korrekt formatierten Parameter wurde der Wert 'True' festgelegt, die Pr\u00fcfung auf korrekte Formatierung kann jedoch nicht durchgef\u00fchrt werden."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Der Knoten ''{0}'' enth\u00e4lt ung\u00fcltige XML-Zeichen."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "Im Kommentar wurde ein ung\u00fcltiges XML-Zeichen (Unicode: 0x{0}) gefunden."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "In der Verarbeitungsanweisung wurde ein ung\u00fcltiges XML-Zeichen (Unicode: 0x{0}) gefunden."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "Im Inhalt von CDATASection wurde ein ung\u00fcltiges XML-Zeichen (Unicode: 0x{0}) gefunden."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "Ein ung\u00fcltiges XML-Zeichen  (Unicode: 0x{0}) wurde im Inhalt der Zeichendaten des Knotens gefunden."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "Ung\u00fcltige XML-Zeichen wurden gefunden in {0} im Knoten ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "Die Zeichenfolge \"--\" ist innerhalb von Kommentaren nicht zul\u00e4ssig."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Der Wert des Attributs \"{1}\" mit einem Elementtyp \"{0}\" darf nicht das Zeichen ''<'' enthalten."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Der syntaktisch nicht analysierte Entit\u00e4tenverweis \"&{0};\" ist nicht zul\u00e4ssig."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Der externe Entit\u00e4tenverweis \"&{0};\" ist in einem Attributwert nicht zul\u00e4ssig."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Das Pr\u00e4fix \"{0}\" kann nicht an den Namensbereich \"{1}\" gebunden werden."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Der lokale Name von Element \"{0}\" ist nicht angegeben."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Der lokale Name des Attributs \"{0}\" ist nicht angegeben."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "Der Ersatztext des Entit\u00e4tenknotens \"{0}\" enth\u00e4lt einen Elementknoten \"{1}\" mit einem nicht gebundenen Pr\u00e4fix \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Der Ersatztext des Entit\u00e4tenknotens \"{0}\" enth\u00e4lt einen Attributknoten \"{1}\" mit einem nicht gebundenen Pr\u00e4fix \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_en.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_en.java
new file mode 100644
index 0000000..f79d1c6
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_en.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_en.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+
+/**
+ * Default implementation.  This is just an empty class.
+ * @xsl.usage internal
+ */
+public final class SerializerMessages_en extends SerializerMessages
+{
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_es.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_es.java
new file mode 100644
index 0000000..7f69976
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_es.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_es.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_es extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "La clave de mensaje ''{0}'' no est\u00e1 en la clase de mensaje ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Se ha producido un error en el formato de mensaje ''{0}'' de la clase de mensaje ''{1}''." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "La clase serializer ''{0}'' no implementa org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "No se ha podido encontrar el recurso [ {0} ].\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "No se ha podido cargar el recurso [ {0} ]: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Tama\u00f1o de almacenamiento intermedio <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u00bfSe ha detectado un sustituto UTF-16 no v\u00e1lido: {0}?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Error de ES" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "No se puede a\u00f1adir el atributo {0} despu\u00e9s de nodos hijo o antes de que se produzca un elemento.  Se ignorar\u00e1 el atributo." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "No se ha declarado el espacio de nombres para el prefijo ''{0}''." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atributo ''{0}'' fuera del elemento." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Declaraci\u00f3n del espacio de nombres ''{0}''=''{1}'' fuera del elemento." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "No se ha podido cargar ''{0}'' (compruebe la CLASSPATH), ahora s\u00f3lo se est\u00e1n utilizando los valores predeterminados" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Se ha intentado dar salida a un car\u00e1cter del valor integral {0} que no est\u00e1 representado en la codificaci\u00f3n de salida especificada de {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "No se ha podido cargar el archivo de propiedades ''{0}'' para el m\u00e9todo de salida ''{1}'' (compruebe la CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "N\u00famero de puerto no v\u00e1lido" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "No se puede establecer el puerto si el sistema principal es nulo" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "El sistema principal no es una direcci\u00f3n bien formada" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "El esquema no es compatible." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "No se puede establecer un esquema de una serie nula" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "La v\u00eda de acceso contiene una secuencia de escape no v\u00e1lida" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "La v\u00eda de acceso contiene un car\u00e1cter no v\u00e1lido: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "El fragmento contiene un car\u00e1cter no v\u00e1lido" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "No se puede establecer el fragmento si la v\u00eda de acceso es nula" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "S\u00f3lo se puede establecer el fragmento para un URI gen\u00e9rico" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "No se ha encontrado un esquema en el URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "No se puede inicializar el URI con par\u00e1metros vac\u00edos" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "No se puede especificar el fragmento en la v\u00eda de acceso y en el fragmento" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "No se puede especificar la serie de consulta en la v\u00eda de acceso y en la serie de consulta" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "No se puede especificar el puerto si no se ha especificado el sistema principal" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "No se puede especificar la informaci\u00f3n de usuario si no se ha especificado el sistema principal" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Aviso: la versi\u00f3n del documento de salida tiene que ser ''{0}''.  No se admite esta versi\u00f3n de XML.  La versi\u00f3n del documento de salida ser\u00e1 ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u00a1Se necesita un esquema!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "El objeto Properties pasado a SerializerFactory no tiene una propiedad ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Aviso: La codificaci\u00f3n ''{0}'' no est\u00e1 soportada por Java Runtime." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "El par\u00e1metro ''{0}'' no se reconoce."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Se reconoce el par\u00e1metro ''{0}'' pero no puede establecerse el valor solicitado."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "La serie producida es demasiado larga para ajustarse a DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "El tipo de valor para este nombre de par\u00e1metro es incompatible con el tipo de valor esperado."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "El destino de salida de escritura de los datos es nulo."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Se ha encontrado una codificaci\u00f3n no soportada."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "No se ha podido serializar el nodo."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "La secci\u00f3n CDATA contiene uno o m\u00e1s marcadores ']]>' de terminaci\u00f3n."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "No se ha podido crear una instancia del comprobador de gram\u00e1tica correcta.  El par\u00e1metro well-formed se ha establecido en true pero no se puede realizar la comprobaci\u00f3n de gram\u00e1tica correcta."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "El nodo ''{0}'' contiene caracteres XML no v\u00e1lidos."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "Se ha encontrado un car\u00e1cter XML no v\u00e1lido (Unicode: 0x{0}) en el comentario."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "Se ha encontrado un car\u00e1cter XML no v\u00e1lido (Unicode: 0x{0}) en los datos de la instrucci\u00f3n de proceso."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "Se ha encontrado un car\u00e1cter XML no v\u00e1lido (Unicode: 0x{0}) en el contenido de CDATASection."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "Se ha encontrado un car\u00e1cter XML no v\u00e1lido (Unicode: 0x{0}) en el contenido de datos de caracteres del nodo."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "Se ha encontrado un car\u00e1cter o caracteres XML no v\u00e1lidos en el nodo {0} denominado ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "No se permite la serie \"--\" dentro de los comentarios."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "El valor del atributo \"{1}\" asociado a un tipo de elemento \"{0}\" no debe contener el car\u00e1cter ''''<''''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "No se permite la referencia de entidad no analizada \"&{0};\"."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "La referencia de entidad externa \"&{0};\" no est\u00e1 permitida en un valor de atributo."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "No se puede encontrar el prefijo \"{0}\" en el espacio de nombres \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "El nombre local del elemento \"{0}\" es null."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "El nombre local del atributo \"{0}\" es null."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "El texto de sustituci\u00f3n del nodo de entidad \"{0}\" contiene un nodo de elemento \"{1}\" con un prefijo no enlazado \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "El texto de sustituci\u00f3n del nodo de entidad \"{0}\" contiene un nodo de atributo \"{1}\" con un prefijo no enlazado \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_fr.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_fr.java
new file mode 100644
index 0000000..1f45524
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_fr.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_fr.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_fr extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "La cl\u00e9 du message ''{0}'' ne se trouve pas dans la classe du message ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Le format du message ''{0}'' de la classe du message ''{1}'' est incorrect." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "La classe de la m\u00e9thode de s\u00e9rialisation ''{0}'' n''impl\u00e9mente pas org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "La ressource [ {0} ] est introuvable.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "La ressource [ {0} ] n''a pas pu charger : {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Taille du tampon <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Substitut UTF-16 non valide d\u00e9tect\u00e9 : {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Erreur d'E-S" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Ajout impossible de l''attribut {0} apr\u00e8s des noeuds enfants ou avant la production d''un \u00e9l\u00e9ment.  L''attribut est ignor\u00e9." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "L''espace de noms du pr\u00e9fixe ''{0}'' n''a pas \u00e9t\u00e9 d\u00e9clar\u00e9." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "L''attribut ''{0}'' est \u00e0 l''ext\u00e9rieur de l''\u00e9l\u00e9ment." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "La d\u00e9claration d''espace de noms ''{0}''=''{1}'' est \u00e0 l''ext\u00e9rieur de l''\u00e9l\u00e9ment." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Impossible de charger ''{0}'' (v\u00e9rifier CLASSPATH), les valeurs par d\u00e9faut sont donc employ\u00e9es" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Tentative de sortie d''un caract\u00e8re de la valeur enti\u00e8re {0} non repr\u00e9sent\u00e9e dans l''encodage de sortie de {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Impossible de charger le fichier de propri\u00e9t\u00e9s ''{0}'' pour la m\u00e9thode de sortie ''{1}'' (v\u00e9rifier CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Num\u00e9ro de port non valide" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Le port ne peut \u00eatre d\u00e9fini quand l'h\u00f4te est vide" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "L'h\u00f4te n'est pas une adresse bien form\u00e9e" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Le processus n'est pas conforme." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Impossible de d\u00e9finir le processus \u00e0 partir de la cha\u00eene vide" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Le chemin d'acc\u00e8s contient une s\u00e9quence d'\u00e9chappement non valide" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Le chemin contient un caract\u00e8re non valide : {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Le fragment contient un caract\u00e8re non valide" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Le fragment ne peut \u00eatre d\u00e9fini quand le chemin d'acc\u00e8s est vide" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Le fragment ne peut \u00eatre d\u00e9fini que pour un URI g\u00e9n\u00e9rique" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Processus introuvable dans l'URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Impossible d'initialiser l'URI avec des param\u00e8tres vides" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Le fragment ne doit pas \u00eatre indiqu\u00e9 \u00e0 la fois dans le chemin et dans le fragment" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "La cha\u00eene de requ\u00eate ne doit pas figurer dans un chemin et une cha\u00eene de requ\u00eate" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Le port peut ne pas \u00eatre sp\u00e9cifi\u00e9 si l'h\u00f4te n'est pas sp\u00e9cifi\u00e9" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Userinfo ne peut \u00eatre sp\u00e9cifi\u00e9 si l'h\u00f4te ne l'est pas" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Avertissement : La version du document de sortie doit \u00eatre ''{0}''.  Cette version XML n''est pas prise en charge.  La version du document de sortie sera ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Processus requis !" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "L''objet Properties transmis \u00e0 SerializerFactory ne dispose pas de propri\u00e9t\u00e9 ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Avertissement : Le codage ''{0}'' n''est pas pris en charge par l''environnement d''ex\u00e9cution Java." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Le param\u00e8tre ''{0}'' n''est pas reconnu."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Le param\u00e8tre ''{0}'' est reconnu mas la valeur demand\u00e9e ne peut pas \u00eatre d\u00e9finie."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "La cha\u00eene obtenue est trop longue pour un DOMString : ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Le type de valeur de ce param\u00e8tre est incompatible avec le type de valeur attendu."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "La sortie de destination des donn\u00e9es \u00e0 \u00e9crire \u00e9tait vide."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Codage non pris en charge."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Le noeud ne peut pas \u00eatre s\u00e9rialis\u00e9."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "La section CDATA contient un ou plusieurs marqueurs de fin ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Aucune instance du programme de v\u00e9rification de la formation n'a pu \u00eatre cr\u00e9\u00e9e.  La valeur true a \u00e9t\u00e9 attribu\u00e9e au param\u00e8tre well-formed mais la v\u00e9rification de la formation n'a pas pu \u00eatre effectu\u00e9e."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Le noeud ''{0}'' contient des caract\u00e8res XML non valides."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "Un caract\u00e8re XML non valide (Unicode : 0x{0}) a \u00e9t\u00e9 trouv\u00e9 dans le commentaire."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "Un caract\u00e8re XML non valide (Unicode : 0x{0}) a \u00e9t\u00e9 trouv\u00e9 dans les donn\u00e9es de l''instruction de traitement."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "Un caract\u00e8re XML non valide (Unicode: 0x{0}) a \u00e9t\u00e9 trouv\u00e9 dans le contenu de la CDATASection"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "Un caract\u00e8re XML non valide (Unicode : 0x{0}) a \u00e9t\u00e9 trouv\u00e9 dans le contenu des donn\u00e9es de type caract\u00e8res du noeud."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "Un ou plusieurs caract\u00e8res non valides ont \u00e9t\u00e9 trouv\u00e9s dans le noeud {0} nomm\u00e9 ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "La cha\u00eene \"--\" est interdite dans des commentaires."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "La valeur de l''attribut \"{1}\" associ\u00e9 \u00e0 un type d''\u00e9l\u00e9ment \"{0}\" ne doit pas contenir le caract\u00e8re ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "La r\u00e9f\u00e9rence d''entit\u00e9 non analys\u00e9e \"&{0};\" n''est pas admise."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "La r\u00e9f\u00e9rence d''entit\u00e9 externe \"&{0};\" n''est pas admise dans une valeur d''attribut."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Le pr\u00e9fixe \"{0}\" ne peut pas \u00eatre li\u00e9 \u00e0 l''espace de noms \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Le nom local de l''\u00e9l\u00e9ment \"{0}\" a une valeur null."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Le nom local de l''attribut \"{0}\" a une valeur null."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "le texte de remplacement du noeud de l''entit\u00e9 \"{0}\" contaient un noeud d''\u00e9l\u00e9ment \"{1}\" avec un pr\u00e9fixe non li\u00e9 \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Le texte de remplacement du noeud de l''entit\u00e9 \"{0}\" contient un noeud d''attribut \"{1}\" avec un pr\u00e9fixe non li\u00e9 \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_hu.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_hu.java
new file mode 100644
index 0000000..3e3c60e
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_hu.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_hu.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_hu extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "A(z) ''{0}'' \u00fczenetkulcs nem tal\u00e1lhat\u00f3 a(z) ''{1}'' \u00fczenetoszt\u00e1lyban." },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "A(z) ''{1}'' \u00fczenetoszt\u00e1ly ''{0}'' \u00fczenet\u00e9nek form\u00e1tuma hib\u00e1s." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "A(z) ''{0}'' p\u00e9ld\u00e1nyos\u00edt\u00f3 oszt\u00e1ly nem val\u00f3s\u00edtja meg az org.xml.sax.ContentHandler f\u00fcggv\u00e9nyt." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "A(z) [ {0} ] er\u0151forr\u00e1s nem tal\u00e1lhat\u00f3.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "A(z) [ {0} ] er\u0151forr\u00e1st nem lehet bet\u00f6lteni: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Pufferm\u00e9ret <= 0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u00c9rv\u00e9nytelen UTF-16 helyettes\u00edt\u00e9s: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "IO hiba" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Nem lehet {0} attrib\u00fatumot hozz\u00e1adni ut\u00f3d csom\u00f3pontok ut\u00e1n vagy egy elem el\u0151\u00e1ll\u00edt\u00e1sa el\u0151tt.  Az attrib\u00fatum figyelmen k\u00edv\u00fcl marad." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "A(z) ''{0}'' el\u0151tag n\u00e9vtere nincs deklar\u00e1lva." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "A(z) ''{0}'' attrib\u00fatum k\u00edv\u00fcl esik az elemen." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "A(z) ''{0}''=''{1}'' n\u00e9vt\u00e9rdeklar\u00e1ci\u00f3 k\u00edv\u00fcl esik az elemen." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Nem lehet bet\u00f6lteni ''{0}'' er\u0151forr\u00e1st (ellen\u0151rizze a CLASSPATH be\u00e1ll\u00edt\u00e1st), a rendszer az alap\u00e9rtelmez\u00e9seket haszn\u00e1lja." },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "K\u00eds\u00e9rletet tett {0} \u00e9rt\u00e9k\u00e9nek karakteres ki\u00edr\u00e1s\u00e1ra, de nem jelen\u00edthet\u0151 meg a megadott {1} kimeneti k\u00f3dol\u00e1ssal." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Nem lehet bet\u00f6lteni a(z) ''{0}'' tulajdons\u00e1gf\u00e1jlt a(z) ''{1}'' met\u00f3dushoz (ellen\u0151rizze a CLASSPATH be\u00e1ll\u00edt\u00e1st)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\u00c9rv\u00e9nytelen portsz\u00e1m" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "A portot nem \u00e1ll\u00edthatja be, ha a hoszt null" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "A hoszt nem j\u00f3l form\u00e1zott c\u00edm" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "A s\u00e9ma nem megfelel\u0151." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Nem lehet be\u00e1ll\u00edtani a s\u00e9m\u00e1t null karaktersorozatb\u00f3l" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Az el\u00e9r\u00e9si \u00fat \u00e9rv\u00e9nytelen vez\u00e9rl\u0151 jelsorozatot tartalmaz" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Az el\u00e9r\u00e9si \u00fat \u00e9rv\u00e9nytelen karaktert tartalmaz: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "A t\u00f6red\u00e9k \u00e9rv\u00e9nytelen karaktert tartalmaz" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "A t\u00f6red\u00e9ket nem \u00e1ll\u00edthatja be, ha az el\u00e9r\u00e9si \u00fat null" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Csak \u00e1ltal\u00e1nos URI-hoz \u00e1ll\u00edthat be t\u00f6red\u00e9ket" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Nem tal\u00e1lhat\u00f3 s\u00e9ma az URI-ban" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Az URI nem inicializ\u00e1lhat\u00f3 \u00fcres param\u00e9terekkel" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Nem adhat meg t\u00f6red\u00e9ket az el\u00e9r\u00e9si \u00fatban \u00e9s a t\u00f6red\u00e9kben is" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Nem adhat meg lek\u00e9rdez\u00e9si karaktersorozatot az el\u00e9r\u00e9si \u00fatban \u00e9s a lek\u00e9rdez\u00e9si karaktersorozatban" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Nem adhatja meg a portot, ha nincs megadva hoszt" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Nem adhatja meg a felhaszn\u00e1l\u00f3i inform\u00e1ci\u00f3kat, ha nincs megadva hoszt" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Figyelmeztet\u00e9s: A kimeneti dokumentum k\u00e9rt verzi\u00f3ja ''{0}''.  Az XML ezen verzi\u00f3ja nem t\u00e1mogatott.  A kimeneti dokumentum verzi\u00f3ja ''1.0'' lesz." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "S\u00e9m\u00e1ra van sz\u00fcks\u00e9g!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "A SerializerFactory oszt\u00e1lynak \u00e1tadott Properties objektumnak nincs ''{0}'' tulajdons\u00e1ga." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Figyelmeztet\u00e9s: A(z) ''{0}'' k\u00f3dol\u00e1st nem t\u00e1mogatja a Java fut\u00e1si k\u00f6rnyezet." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "A(z) ''{0}'' param\u00e9ter nem ismerhet\u0151 fel."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "A(z) ''{0}'' param\u00e9ter ismert, de a k\u00e9rt \u00e9rt\u00e9k nem \u00e1ll\u00edthat\u00f3 be."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "A l\u00e9trej\u00f6v\u0151 karaktersorozat t\u00fal hossz\u00fa, nem f\u00e9r el egy DOMString-ben: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "A param\u00e9tern\u00e9v \u00e9rt\u00e9k\u00e9nek t\u00edpusa nem kompatibilis a v\u00e1rt t\u00edpussal."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Az adatki\u00edr\u00e1s c\u00e9ljak\u00e9nt megadott \u00e9rt\u00e9k \u00fcres volt."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Nem t\u00e1mogatott k\u00f3dol\u00e1s."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "A csom\u00f3pont nem p\u00e9ld\u00e1nyos\u00edthat\u00f3."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "A CDATA szakasz legal\u00e1bb egy ']]>' lez\u00e1r\u00f3 jelz\u0151t tartalmaz."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "A szab\u00e1lyos form\u00e1z\u00e1st ellen\u0151rz\u0151 p\u00e9ld\u00e1nyt nem siker\u00fclt l\u00e9trehozni.  A well-formed param\u00e9ter \u00e9rt\u00e9ke true, de a szab\u00e1lyos form\u00e1z\u00e1st nem lehet ellen\u0151rizni."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "A(z) ''{0}'' csom\u00f3pont \u00e9rv\u00e9nytelen XML karaktereket tartalmaz."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\u00c9rv\u00e9nytelen XML karakter (Unicode: 0x{0}) szerepelt a megjegyz\u00e9sben."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u00c9rv\u00e9nytelen XML karakter (Unicode: 0x{0}) szerepelt a feldolgoz\u00e1si utas\u00edt\u00e1sadatokban."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "\u00c9rv\u00e9nytelen XML karakter (Unicode: 0x{0}) szerepelt a CDATASection tartalm\u00e1ban."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\u00c9rv\u00e9nytelen XML karakter (Unicode: 0x{0}) szerepelt a csom\u00f3pont karakteradat tartalm\u00e1ban."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "\u00c9rv\u00e9nytelen XML karakter tal\u00e1lhat\u00f3 a(z) ''{1}'' nev\u0171 {0} csom\u00f3pontban."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "A \"--\" karaktersorozat nem megengedett a megjegyz\u00e9sekben."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "A(z) \"{0}\" elemt\u00edpussal t\u00e1rs\u00edtott \"{1}\" attrib\u00fatum \u00e9rt\u00e9ke nem tartalmazhat ''<'' karaktert."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Az \u00e9rtelmez\u00e9s n\u00e9lk\u00fcli \"&{0};\" entit\u00e1shivatkoz\u00e1s nem megengedett."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "A(z) \"&{0};\" k\u00fcls\u0151 entit\u00e1shivatkoz\u00e1s nem megengedett egy attrib\u00fatum\u00e9rt\u00e9kben."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "A(z) \"{0}\" el\u0151tag nem k\u00f6thet\u0151 a(z) \"{1}\" n\u00e9vt\u00e9rhez."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "A(z) \"{0}\" elem helyi neve null."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "A(z) \"{0}\" attrib\u00fatum helyi neve null."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "A(z) \"{0}\" entit\u00e1scsom\u00f3pont helyettes\u00edt\u0151 sz\u00f6vege a(z) \"{1}\" elemcsom\u00f3pontot tartalmazza, amelynek nem k\u00f6t\u00f6tt el\u0151tagja \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "A(z) \"{0}\" entit\u00e1scsom\u00f3pont helyettes\u00edt\u0151 sz\u00f6vege a(z) \"{1}\" attrib\u00fatum-csom\u00f3pontot tartalmazza, amelynek nem k\u00f6t\u00f6tt el\u0151tagja \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_it.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_it.java
new file mode 100644
index 0000000..d116bd9
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_it.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_it.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_it extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "La chiave messaggio ''{0}'' non si trova nella classe del messaggio ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Il formato del messaggio ''{0}'' nella classe del messaggio ''{1}'' non \u00e8 riuscito." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "La classe del serializzatore ''{0}'' non implementa org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Risorsa [ {0} ] non trovata.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Impossibile caricare la risorsa [ {0} ]: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Dimensione buffer <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Rilevato surrogato UTF-16 non valido: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Errore IO" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Impossibile aggiungere l''''attributo {0} dopo i nodi secondari o prima che sia prodotto un elemento.  L''''attributo verr\u00e0 ignorato." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Lo spazio nomi per il prefisso ''{0}'' non \u00e8 stato dichiarato." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "L''''attributo ''{0}'' al di fuori dell''''elemento." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Dichiarazione dello spazio nome ''{0}''=''{1}'' al di fuori dell''''elemento." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Impossibile caricare ''{0}'' (verificare CLASSPATH), verranno utilizzati i valori predefiniti" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Tentare di generare l''''output del carattere di valor integrale {0} che non \u00e8 rappresentato nella codifica di output specificata di {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Impossibile caricare il file delle propriet\u00e0 ''{0}'' per il metodo di emissione ''{1}'' (verificare CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Numero di porta non valido" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "La porta non pu\u00f2 essere impostata se l'host \u00e8 nullo" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Host non \u00e8 un'indirizzo corretto" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Lo schema non \u00e8 conforme." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Impossibile impostare lo schema da una stringa nulla" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Il percorso contiene sequenza di escape non valida" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Il percorso contiene un carattere non valido: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Il frammento contiene un carattere non valido" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Il frammento non pu\u00f2 essere impostato se il percorso \u00e8 nullo" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Il frammento pu\u00f2 essere impostato solo per un URI generico" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Non \u00e8 stato trovato alcuno schema nell'URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Impossibile inizializzare l'URI con i parametri vuoti" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Il frammento non pu\u00f2 essere specificato sia nel percorso che nel frammento" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "La stringa di interrogazione non pu\u00f2 essere specificata nella stringa di interrogazione e percorso." },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "La porta non pu\u00f2 essere specificata se l'host non S specificato" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Userinfo non pu\u00f2 essere specificato se l'host non S specificato" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Attenzione:  La versione del documento di emissione \u00e8 obbligatorio che sia ''{0}''.  Questa versione di XML non \u00e8 supportata.  La versione del documento di emissione sar\u00e0 ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Lo schema \u00e8 obbligatorio." },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "L''''oggetto Properties passato al SerializerFactory non ha una propriet\u00e0 ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Avvertenza:  La codifica ''{0}'' non \u00e8 supportata da Java runtime." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Il parametro ''{0}'' non \u00e8 riconosciuto."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Il parametro ''{0}'' \u00e8 riconosciuto ma non \u00e8 possibile impostare il valore richiesto."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "La stringa risultante \u00e8 troppo lunga per essere inserita in DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Il tipo di valore per questo nome di parametro non \u00e8 compatibile con il tipo di valore previsto."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "La destinazione di output in cui scrivere i dati era nulla."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\u00c8 stata rilevata una codifica non supportata."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Impossibile serializzare il nodo."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "La Sezione CDATA contiene uno o pi\u00f9 markers di termine ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Impossibile creare un'istanza del controllore Well-Formedness.  Il parametro well-formed \u00e8 stato impostato su true ma non \u00e8 possibile eseguire i controlli well-formedness."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Il nodo ''{0}'' contiene caratteri XML non validi."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "Trovato un carattere XML non valido (Unicode: 0x{0}) nel commento."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "Carattere XML non valido (Unicode: 0x{0}) rilevato nell''elaborazione di instructiondata."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "Carattere XML non valido (Unicode: 0x{0}) rilevato nel contenuto di CDATASection."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "Carattere XML non valido (Unicode: 0x{0}) rilevato nel contenuto dati di caratteri del nodo. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "Carattere XML non valido rilevato nel nodo {0} denominato ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "La stringa \"--\" non \u00e8 consentita nei commenti."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Il valore dell''''attributo \"{1}\" associato con un tipo di elemento \"{0}\" non deve contenere il carattere ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Il riferimento entit\u00e0 non analizzata \"&{0};\" non \u00e8 permesso."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Il riferimento all''''entit\u00e0 esterna \"&{0};\" non \u00e8 permesso in un valore attributo."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Il prefisso \"{0}\" non pu\u00f2 essere associato allo spazio nome \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Il nome locale dell''''elemento \"{0}\" \u00e8 null."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Il nome locale dell''''attributo \"{0}\" \u00e8  null."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "Il testo di sostituzione del nodo di entit\u00e0 \"{0}\" contiene un nodo di elemento \"{1}\" con un prefisso non associato \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Il testo di sostituzione del nodo di entit\u00e0 \"{0}\" contiene un nodo di attributo \"{1}\" con un prefisso non associato \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ja.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ja.java
new file mode 100644
index 0000000..0a969b9
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ja.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_ja.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_ja extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "\u30e1\u30c3\u30bb\u30fc\u30b8\u30fb\u30ad\u30fc ''{0}'' \u306f\u30e1\u30c3\u30bb\u30fc\u30b8\u30fb\u30af\u30e9\u30b9 ''{1}'' \u306b\u3042\u308a\u307e\u305b\u3093\u3002" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "\u30e1\u30c3\u30bb\u30fc\u30b8\u30fb\u30af\u30e9\u30b9 ''{1}'' \u306e\u30e1\u30c3\u30bb\u30fc\u30b8 ''{0}'' \u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u8a2d\u5b9a\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002" },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "\u30b7\u30ea\u30a2\u30e9\u30a4\u30b6\u30fc\u30fb\u30af\u30e9\u30b9 ''{0}'' \u306f org.xml.sax.ContentHandler \u3092\u5b9f\u88c5\u3057\u307e\u305b\u3093\u3002" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "\u30ea\u30bd\u30fc\u30b9 [ {0} ] \u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "\u30ea\u30bd\u30fc\u30b9 [ {0} ] \u3092\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "\u30d0\u30c3\u30d5\u30a1\u30fc\u30fb\u30b5\u30a4\u30ba <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u7121\u52b9\u306a UTF-16 \u30b5\u30ed\u30b2\u30fc\u30c8\u304c\u691c\u51fa\u3055\u308c\u307e\u3057\u305f: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "\u5165\u51fa\u529b\u30a8\u30e9\u30fc" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "\u4e0b\u4f4d\u30ce\u30fc\u30c9\u306e\u5f8c\u307e\u305f\u306f\u8981\u7d20\u304c\u751f\u6210\u3055\u308c\u308b\u524d\u306b\u5c5e\u6027 {0} \u306f\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002  \u5c5e\u6027\u306f\u7121\u8996\u3055\u308c\u307e\u3059\u3002" },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "\u63a5\u982d\u90e8 ''{0}'' \u306e\u540d\u524d\u7a7a\u9593\u304c\u5ba3\u8a00\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002" },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "\u5c5e\u6027 ''{0}'' \u304c\u8981\u7d20\u306e\u5916\u5074\u3067\u3059\u3002" },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "\u540d\u524d\u7a7a\u9593\u5ba3\u8a00 ''{0}''=''{1}'' \u304c\u8981\u7d20\u306e\u5916\u5074\u3067\u3059\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "''{0}'' \u3092\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f (CLASSPATH \u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044)\u3002\u73fe\u5728\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u3082\u306e\u306e\u307f\u3092\u4f7f\u7528\u3057\u3066\u3044\u307e\u3059\u3002" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "{1} \u306e\u6307\u5b9a\u3055\u308c\u305f\u51fa\u529b\u30a8\u30f3\u30b3\u30fc\u30c9\u3067\u8868\u305b\u306a\u3044\u6574\u6570\u5024 {0} \u306e\u6587\u5b57\u306e\u51fa\u529b\u3092\u8a66\u307f\u307e\u3057\u305f\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "\u51fa\u529b\u30e1\u30bd\u30c3\u30c9 ''{1}'' \u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u30fb\u30d5\u30a1\u30a4\u30eb ''{0}'' \u3092\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f (CLASSPATH \u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\u7121\u52b9\u306a\u30dd\u30fc\u30c8\u756a\u53f7" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "\u30db\u30b9\u30c8\u304c\u30cc\u30eb\u3067\u3042\u308b\u3068\u30dd\u30fc\u30c8\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "\u30db\u30b9\u30c8\u306f\u3046\u307e\u304f\u69cb\u6210\u3055\u308c\u305f\u30a2\u30c9\u30ec\u30b9\u3067\u3042\u308a\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\u30b9\u30ad\u30fc\u30e0\u306f\u4e00\u81f4\u3057\u3066\u3044\u307e\u305b\u3093\u3002" },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "\u30cc\u30eb\u30fb\u30b9\u30c8\u30ea\u30f3\u30b0\u304b\u3089\u306f\u30b9\u30ad\u30fc\u30e0\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\u30d1\u30b9\u306b\u7121\u52b9\u306a\u30a8\u30b9\u30b1\u30fc\u30d7\u30fb\u30b7\u30fc\u30b1\u30f3\u30b9\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\u30d1\u30b9\u306b\u7121\u52b9\u6587\u5b57: {0} \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "\u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u306b\u7121\u52b9\u6587\u5b57\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "\u30d1\u30b9\u304c\u30cc\u30eb\u3067\u3042\u308b\u3068\u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "\u7dcf\u79f0 URI \u306e\u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u3057\u304b\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "\u30b9\u30ad\u30fc\u30e0\u306f URI \u3067\u898b\u3064\u304b\u308a\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "URI \u306f\u7a7a\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u4f7f\u7528\u3057\u3066\u521d\u671f\u5316\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "\u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u306f\u30d1\u30b9\u3068\u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u306e\u4e21\u65b9\u306b\u6307\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "\u7167\u4f1a\u30b9\u30c8\u30ea\u30f3\u30b0\u306f\u30d1\u30b9\u304a\u3088\u3073\u7167\u4f1a\u30b9\u30c8\u30ea\u30f3\u30b0\u5185\u306b\u6307\u5b9a\u3067\u304d\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "\u30db\u30b9\u30c8\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u30dd\u30fc\u30c8\u3092\u6307\u5b9a\u3057\u3066\u306f\u3044\u3051\u307e\u305b\u3093" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "\u30db\u30b9\u30c8\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f Userinfo \u3092\u6307\u5b9a\u3057\u3066\u306f\u3044\u3051\u307e\u305b\u3093" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "\u8b66\u544a: \u51fa\u529b\u6587\u66f8\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3068\u3057\u3066 ''{0}'' \u304c\u8981\u6c42\u3055\u308c\u307e\u3057\u305f\u3002  \u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306e XML \u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002  \u51fa\u529b\u6587\u66f8\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306f ''1.0'' \u306b\u306a\u308a\u307e\u3059\u3002" },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u30b9\u30ad\u30fc\u30e0\u304c\u5fc5\u8981\u3067\u3059\u3002" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "SerializerFactory \u306b\u6e21\u3055\u308c\u305f Properties \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u306f ''{0}'' \u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u304c\u3042\u308a\u307e\u305b\u3093\u3002" },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "\u8b66\u544a:  \u30a8\u30f3\u30b3\u30fc\u30c9 ''{0}'' \u306f\u3053\u306e Java \u30e9\u30f3\u30bf\u30a4\u30e0\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002" },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc ''{0}'' \u306f\u8a8d\u8b58\u3055\u308c\u307e\u305b\u3093\u3002"},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc ''{0}'' \u306f\u8a8d\u8b58\u3055\u308c\u307e\u3059\u304c\u3001\u8981\u6c42\u3055\u308c\u305f\u5024\u306f\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093\u3002"},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "\u7d50\u679c\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u304c\u9577\u3059\u304e\u308b\u305f\u3081\u3001DOMString \u5185\u306b\u53ce\u307e\u308a\u307e\u305b\u3093: ''{0}''\u3002"},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "\u3053\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u540d\u306e\u5024\u306e\u578b\u306f\u3001\u671f\u5f85\u3055\u308c\u308b\u5024\u306e\u578b\u3068\u4e0d\u9069\u5408\u3067\u3059\u3002"},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "\u66f8\u304d\u8fbc\u307e\u308c\u308b\u30c7\u30fc\u30bf\u306e\u51fa\u529b\u5b9b\u5148\u304c\u30cc\u30eb\u3067\u3059\u3002"},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u306a\u3044\u30a8\u30f3\u30b3\u30fc\u30c9\u304c\u691c\u51fa\u3055\u308c\u307e\u3057\u305f\u3002"},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "\u30ce\u30fc\u30c9\u3092\u76f4\u5217\u5316\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002"},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "CDATA \u30bb\u30af\u30b7\u30e7\u30f3\u306b 1 \u3064\u4ee5\u4e0a\u306e\u7d42\u4e86\u30de\u30fc\u30ab\u30fc ']]>' \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002"},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "\u6574\u5f62\u5f0f\u6027\u30c1\u30a7\u30c3\u30ab\u30fc\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002  well-formed \u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u306e\u8a2d\u5b9a\u306f true \u3067\u3057\u305f\u304c\u3001\u6574\u5f62\u5f0f\u6027\u306e\u691c\u67fb\u306f\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "\u30ce\u30fc\u30c9 ''{0}'' \u306b\u7121\u52b9\u306a XML \u6587\u5b57\u304c\u3042\u308a\u307e\u3059\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\u30b3\u30e1\u30f3\u30c8\u306e\u4e2d\u306b\u7121\u52b9\u306a XML \u6587\u5b57 (Unicode: 0x{0}) \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u51e6\u7406\u547d\u4ee4\u30c7\u30fc\u30bf\u306e\u4e2d\u306b\u7121\u52b9\u306a XML \u6587\u5b57 (Unicode: 0x{0}) \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "CDATA \u30bb\u30af\u30b7\u30e7\u30f3\u306e\u4e2d\u306b\u7121\u52b9\u306a XML \u6587\u5b57 (Unicode: 0x{0}) \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\u30ce\u30fc\u30c9\u306e\u6587\u5b57\u30c7\u30fc\u30bf\u306e\u5185\u5bb9\u306b\u7121\u52b9\u306a XML \u6587\u5b57 (Unicode: 0x{0}) \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "''{1}'' \u3068\u3044\u3046\u540d\u524d\u306e {0} \u30ce\u30fc\u30c9\u306e\u4e2d\u306b\u7121\u52b9\u306a XML \u6587\u5b57\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002"
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "\u30b9\u30c8\u30ea\u30f3\u30b0 \"--\" \u306f\u30b3\u30e1\u30f3\u30c8\u5185\u3067\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\u8981\u7d20\u578b \"{0}\" \u306b\u95a2\u9023\u3057\u305f\u5c5e\u6027 \"{1}\" \u306e\u5024\u306b\u306f ''<'' \u6587\u5b57\u3092\u542b\u3081\u3066\u306f\u3044\u3051\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\u89e3\u6790\u5bfe\u8c61\u5916\u5b9f\u4f53\u53c2\u7167 \"&{0};\" \u306f\u8a31\u53ef\u3055\u308c\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\u5c5e\u6027\u5024\u3067\u306e\u5916\u90e8\u5b9f\u4f53\u53c2\u7167 \"&{0};\" \u306f\u8a31\u53ef\u3055\u308c\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\u63a5\u982d\u90e8 \"{0}\" \u306f\u540d\u524d\u7a7a\u9593 \"{1}\" \u306b\u7d50\u5408\u3067\u304d\u307e\u305b\u3093\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\u8981\u7d20 \"{0}\" \u306e\u30ed\u30fc\u30ab\u30eb\u540d\u304c\u30cc\u30eb\u3067\u3059\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\u5c5e\u6027 \"{0}\" \u306e\u30ed\u30fc\u30ab\u30eb\u540d\u304c\u30cc\u30eb\u3067\u3059\u3002"
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5b9f\u4f53\u30ce\u30fc\u30c9 \"{0}\" \u306e\u7f6e\u63db\u30c6\u30ad\u30b9\u30c8\u306b\u3001\u672a\u7d50\u5408\u306e\u63a5\u982d\u90e8 \"{2}\" \u3092\u6301\u3064\u8981\u7d20\u30ce\u30fc\u30c9 \"{1}\" \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002"
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5b9f\u4f53\u30ce\u30fc\u30c9 \"{0}\" \u306e\u7f6e\u63db\u30c6\u30ad\u30b9\u30c8\u306b\u3001\u672a\u7d50\u5408\u306e\u63a5\u982d\u90e8 \"{2}\" \u3092\u6301\u3064\u5c5e\u6027\u30ce\u30fc\u30c9 \"{1}\" \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002"
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ko.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ko.java
new file mode 100644
index 0000000..3d2f011
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ko.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_ko.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_ko extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "''{0}'' \uba54\uc2dc\uc9c0 \ud0a4\uac00 ''{1}'' \uba54\uc2dc\uc9c0 \ud074\ub798\uc2a4\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "''{1}'' \uba54\uc2dc\uc9c0 \ud074\ub798\uc2a4\uc5d0 \uc788\ub294 ''{0}'' \uba54\uc2dc\uc9c0\uc758 \ud615\uc2dd\uc774 \uc798\ubabb \ub418\uc5c8\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "''{0}'' \uc9c1\ub82c \ud504\ub85c\uadf8\ub7a8 \ud074\ub798\uc2a4\uac00 org.xml.sax.ContentHandler\ub97c \uad6c\ud604\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "[ {0} ] \uc790\uc6d0\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n{1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "[ {0} ] \uc790\uc6d0\uc774 {1} \n {2} \t {3}\uc744(\ub97c) \ub85c\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "\ubc84\ud37c \ud06c\uae30 <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\uc798\ubabb\ub41c UTF-16 \ub300\ub9ac\uc790(surrogate)\uac00 \ubc1c\uacac\ub418\uc5c8\uc2b5\ub2c8\ub2e4: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "IO \uc624\ub958" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "\ud558\uc704 \ub178\ub4dc\uac00 \uc0dd\uc131\ub41c \uc774\ud6c4 \ub610\ub294 \uc694\uc18c\uac00 \uc791\uc131\ub418\uae30 \uc774\uc804\uc5d0 {0} \uc18d\uc131\uc744 \ucd94\uac00\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc18d\uc131\uc774 \ubb34\uc2dc\ub429\ub2c8\ub2e4." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "''{0}'' \uc811\ub450\ubd80\uc5d0 \ub300\ud55c \uc774\ub984 \uacf5\uac04\uc774 \uc120\uc5b8\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "''{0}'' \uc18d\uc131\uc774 \uc694\uc18c\uc758 \uc678\ubd80\uc5d0 \uc788\uc2b5\ub2c8\ub2e4." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "''{0}''=''{1}'' \uc774\ub984 \uacf5\uac04 \uc120\uc5b8\uc774 \uc694\uc18c\uc758 \uc678\ubd80\uc5d0 \uc788\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "''{0}''(CLASSPATH \ud655\uc778)\uc744(\ub97c) \ub85c\ub4dc\ud560 \uc218 \uc5c6\uc73c\ubbc0\ub85c, \ud604\uc7ac \uae30\ubcf8\uac12\ub9cc\uc744 \uc0ac\uc6a9\ud558\ub294 \uc911\uc785\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "{1}\uc758 \uc9c0\uc815\ub41c \ucd9c\ub825 \uc778\ucf54\ub529\uc5d0 \ud45c\uc2dc\ub418\uc9c0 \uc54a\uc740 \ubb34\uacb0\uc131 \uac12 {0}\uc758 \ubb38\uc790\ub97c \ucd9c\ub825\ud558\uc2ed\uc2dc\uc624. " },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "''{1}'' \ucd9c\ub825 \uba54\uc18c\ub4dc(CLASSPATH \ud655\uc778)\uc5d0 \ub300\ud55c ''{0}'' \ud2b9\uc131 \ud30c\uc77c\uc744 \ub85c\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\uc798\ubabb\ub41c \ud3ec\ud2b8 \ubc88\ud638" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "\ud638\uc2a4\ud2b8\uac00 \ub110(null)\uc774\uba74 \ud3ec\ud2b8\ub97c \uc124\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "\ud638\uc2a4\ud2b8\uac00 \uc644\uc804\ud55c \uc8fc\uc18c\uac00 \uc544\ub2d9\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\uc2a4\ud0a4\ub9c8\uac00 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "\ub110(null) \ubb38\uc790\uc5f4\uc5d0\uc11c \uc2a4\ud0a4\ub9c8\ub97c \uc124\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\uacbd\ub85c\uc5d0 \uc798\ubabb\ub41c \uc774\uc2a4\ucf00\uc774\ud504 \uc21c\uc11c\uac00 \uc788\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\uacbd\ub85c\uc5d0 \uc798\ubabb\ub41c \ubb38\uc790\uac00 \uc788\uc2b5\ub2c8\ub2e4: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "\ub2e8\ud3b8\uc5d0 \uc798\ubabb\ub41c \ubb38\uc790\uac00 \uc788\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "\uacbd\ub85c\uac00 \ub110(null)\uc774\uba74 \ub2e8\ud3b8\uc744 \uc124\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "\uc77c\ubc18 URI\uc5d0 \ub300\ud574\uc11c\ub9cc \ub2e8\ud3b8\uc744 \uc124\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "URI\uc5d0 \uc2a4\ud0a4\ub9c8\uac00 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "\ube48 \ub9e4\uac1c\ubcc0\uc218\ub85c URI\ub97c \ucd08\uae30\ud654\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "\uacbd\ub85c \ubc0f \ub2e8\ud3b8 \ub458 \ub2e4\uc5d0 \ub2e8\ud3b8\uc744 \uc9c0\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "\uacbd\ub85c \ubc0f \uc870\ud68c \ubb38\uc790\uc5f4\uc5d0 \uc870\ud68c \ubb38\uc790\uc5f4\uc744 \uc9c0\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "\ud638\uc2a4\ud2b8\ub97c \uc9c0\uc815\ud558\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uc5d0\ub294 \ud3ec\ud2b8\ub97c \uc9c0\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "\ud638\uc2a4\ud2b8\ub97c \uc9c0\uc815\ud558\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uc5d0\ub294 Userinfo\ub97c \uc9c0\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4." },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "\uacbd\uace0:  \uc694\uccad\ub41c \ucd9c\ub825 \ubb38\uc11c\uc758 \ubc84\uc804\uc740 ''{0}''\uc785\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 XML \ubc84\uc804\uc740 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \ucd9c\ub825 \ubb38\uc11c\uc758 \ubc84\uc804\uc740 ''1.0''\uc774 \ub429\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\uc2a4\ud0a4\ub9c8\uac00 \ud544\uc694\ud569\ub2c8\ub2e4." },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "SerializerFactory\uc5d0 \uc804\ub2ec\ub41c \ud2b9\uc131 \uc624\ube0c\uc81d\ud2b8\uc5d0 ''{0}'' \ud2b9\uc131\uc774 \uc5c6\uc2b5\ub2c8\ub2e4." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "\uacbd\uace0: ''{0}'' \uc778\ucf54\ub529\uc740 Java Runtime\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "''{0}'' \ub9e4\uac1c\ubcc0\uc218\ub97c \uc778\uc2dd\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "''{0}'' \ub9e4\uac1c\ubcc0\uc218\ub294 \uc778\uc2dd\ud560 \uc218 \uc788\uc73c\ub098 \uc694\uccad\ub41c \uac12\uc744 \uc124\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "\uacb0\uacfc \ubb38\uc790\uc5f4\uc774 \ub108\ubb34 \uae38\uc5b4 DOMString\uc5d0 \ub9de\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4: ''{0}'' "},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "\uc774 \ub9e4\uac1c\ubcc0\uc218 \uc774\ub984\uc5d0 \ub300\ud55c \uac12 \uc720\ud615\uc774 \uc608\uc0c1 \uac12 \uc720\ud615\uacfc \ud638\ud658\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "\ub370\uc774\ud130\ub97c \uae30\ub85d\ud560 \ucd9c\ub825 \ub300\uc0c1\uc774 \ub110(null)\uc785\ub2c8\ub2e4."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\uc9c0\uc6d0\ub418\uc9c0 \uc54a\ub294 \uc778\ucf54\ub529\uc774 \ubc1c\uacac\ub418\uc5c8\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "\ub178\ub4dc\ub97c \uc9c1\ub82c\ud654\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "CDATA \uc139\uc158\uc5d0 \uc885\ub8cc \ud45c\uc2dc \ubb38\uc790\uc778 ']]>'\uac00 \ud558\ub098 \uc774\uc0c1 \ud3ec\ud568\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Well-Formedness \uac80\uc0ac\uae30\uc758 \uc778\uc2a4\ud134\uc2a4\ub97c \uc791\uc131\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. Well-Formed \ub9e4\uac1c\ubcc0\uc218\uac00 true\ub85c \uc124\uc815\ub418\uc5c8\uc9c0\ub9cc Well-Formedness \uac80\uc0ac\ub97c \uc218\ud589\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "''{0}'' \ub178\ub4dc\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790\uac00 \uc788\uc2b5\ub2c8\ub2e4."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\uc124\uba85\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790(Unicode: 0x{0})\uac00 \uc788\uc2b5\ub2c8\ub2e4. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\ucc98\ub9ac \uba85\ub839\uc5b4 \ub370\uc774\ud130\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790(Unicode: 0x{0})\uac00 \uc788\uc2b5\ub2c8\ub2e4 "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "CDATASection\uc758 \ub0b4\uc6a9\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790(Unicode: 0x{0})\uac00 \uc788\uc2b5\ub2c8\ub2e4. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\ub178\ub4dc\uc758 \ubb38\uc790 \ub370\uc774\ud130 \ub0b4\uc6a9\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790(Unicode: 0x{0})\uac00 \uc788\uc2b5\ub2c8\ub2e4. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "\uc774\ub984\uc774 ''{1}''\uc778 {0} \ub178\ub4dc\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 XML \ubb38\uc790\uac00 \uc788\uc2b5\ub2c8\ub2e4. "
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "\uc124\uba85 \ub0b4\uc5d0\uc11c\ub294 \"--\" \ubb38\uc790\uc5f4\uc774 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\"{0}\" \uc694\uc18c \uc720\ud615\uacfc \uc5f0\uad00\ub41c \"{1}\" \uc18d\uc131\uac12\uc5d0 ''<'' \ubb38\uc790\uac00 \ud3ec\ud568\ub418\uba74 \uc548\ub429\ub2c8\ub2e4."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\"&{0};\"\uc758 \uad6c\ubd84 \ubd84\uc11d\ub418\uc9c0 \uc54a\uc740 \uc5d4\ud2f0\ud2f0 \ucc38\uc870\ub294 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. "
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\uc18d\uc131\uac12\uc5d0\ub294 \"&{0};\" \uc678\ubd80 \uc5d4\ud2f0\ud2f0 \ucc38\uc870\uac00 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. "
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\"{0}\" \uc811\ub450\ubd80\ub97c \"{1}\" \uc774\ub984 \uacf5\uac04\uc5d0 \ubc14\uc778\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\"{0}\" \uc694\uc18c\uc758 \ub85c\uceec \uc774\ub984\uc774 \ub110(null)\uc785\ub2c8\ub2e4."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\"{0}\" \uc18d\uc131\uc758 \ub85c\uceec \uc774\ub984\uc774 \ub110(null)\uc785\ub2c8\ub2e4."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\"{0}\" \uc5d4\ud2f0\ud2f0 \ub178\ub4dc\uc758 \ub300\uccb4 \ud14d\uc2a4\ud2b8\uc5d0 \ubc14\uc778\ub4dc\ub418\uc9c0 \uc54a\uc740 \uc811\ub450\ubd80 \"{2}\"\uc744(\ub97c) \uac16\ub294 \"{1}\" \uc694\uc18c \ub178\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\"{0}\" \uc5d4\ud2f0\ud2f0 \ub178\ub4dc\uc758 \ub300\uccb4 \ud14d\uc2a4\ud2b8\uc5d0 \ubc14\uc778\ub4dc\ub418\uc9c0 \uc54a\uc740 \uc811\ub450\ubd80 \"{2}\"\uc744(\ub97c) \uac16\ub294 \"{1}\" \uc18d\uc131 \ub178\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pl.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pl.java
new file mode 100644
index 0000000..06d97ae
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pl.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_pl.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_pl extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "Klucz komunikatu ''{0}'' nie znajduje si\u0119 w klasie komunikat\u00f3w ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Nie powiod\u0142o si\u0119 sformatowanie komunikatu ''{0}'' w klasie komunikat\u00f3w ''{1}''." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "Klasa szereguj\u0105ca ''{0}'' nie implementuje org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Nie mo\u017cna znale\u017a\u0107 zasobu [ {0} ].\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Zas\u00f3b [ {0} ] nie m\u00f3g\u0142 za\u0142adowa\u0107: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Wielko\u015b\u0107 buforu <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Wykryto niepoprawny odpowiednik UTF-16: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "B\u0142\u0105d we/wy" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Nie mo\u017cna doda\u0107 atrybutu {0} po bezpo\u015brednich w\u0119z\u0142ach potomnych ani przed wyprodukowaniem elementu.  Atrybut zostanie zignorowany." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Nie zadeklarowano przestrzeni nazw dla przedrostka ''{0}''." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atrybut ''{0}'' znajduje si\u0119 poza elementem." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Deklaracja przestrzeni nazw ''{0}''=''{1}'' znajduje si\u0119 poza elementem." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Nie mo\u017cna za\u0142adowa\u0107 ''{0}'' (sprawd\u017a CLASSPATH) - u\u017cywane s\u0105 teraz warto\u015bci domy\u015blne" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Pr\u00f3ba wyprowadzenia znaku warto\u015bci ca\u0142kowitej {0}, kt\u00f3ry nie jest reprezentowany w podanym kodowaniu wyj\u015bciowym {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Nie mo\u017cna za\u0142adowa\u0107 pliku w\u0142a\u015bciwo\u015bci ''{0}'' dla metody wyj\u015bciowej ''{1}'' (sprawd\u017a CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Niepoprawny numer portu" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Nie mo\u017cna ustawi\u0107 portu, kiedy host jest pusty" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Host nie jest poprawnie skonstruowanym adresem" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Schemat nie jest zgodny." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Nie mo\u017cna ustawi\u0107 schematu z pustego ci\u0105gu znak\u00f3w" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\u015acie\u017cka zawiera nieznan\u0105 sekwencj\u0119 o zmienionym znaczeniu" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\u015acie\u017cka zawiera niepoprawny znak {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment zawiera niepoprawny znak" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Nie mo\u017cna ustawi\u0107 fragmentu, kiedy \u015bcie\u017cka jest pusta" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment mo\u017cna ustawi\u0107 tylko dla og\u00f3lnego URI" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Nie znaleziono schematu w URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Nie mo\u017cna zainicjowa\u0107 URI z pustymi parametrami" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Nie mo\u017cna poda\u0107 fragmentu jednocze\u015bnie w \u015bcie\u017cce i fragmencie" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Tekstu zapytania nie mo\u017cna poda\u0107 w tek\u015bcie \u015bcie\u017cki i zapytania" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Nie mo\u017cna poda\u0107 portu, je\u015bli nie podano hosta" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Nie mo\u017cna poda\u0107 informacji o u\u017cytkowniku, je\u015bli nie podano hosta" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Ostrze\u017cenie:  Wymagan\u0105 wersj\u0105 dokumentu wyj\u015bciowego jest ''{0}''.  Ta wersja XML nie jest obs\u0142ugiwana.  Wersj\u0105 dokumentu wyj\u015bciowego b\u0119dzie ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Schemat jest wymagany!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "Obiekt klasy Properties przekazany do klasy SerializerFactory nie ma w\u0142a\u015bciwo\u015bci ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Ostrze\u017cenie:  dekodowany ''{0}'' nie jest obs\u0142ugiwany przez \u015brodowisko wykonawcze Java." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Parametr ''{0}'' nie zosta\u0142 rozpoznany."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Parametr ''{0}'' zosta\u0142 rozpoznany, ale nie mo\u017cna ustawi\u0107 \u017c\u0105danej warto\u015bci."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "Wynikowy \u0142a\u0144cuch jest zbyt d\u0142ugi, aby si\u0119 zmie\u015bci\u0107 w obiekcie DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Typ warto\u015bci parametru o tej nazwie jest niezgodny z oczekiwanym typem warto\u015bci. "},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Docelowe miejsce zapisu danych wyj\u015bciowych by\u0142o puste (null)."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Napotkano nieobs\u0142ugiwane kodowanie."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Nie mo\u017cna przekszta\u0142ci\u0107 w\u0119z\u0142a do postaci szeregowej."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "Sekcja CDATA zawiera jeden lub kilka znacznik\u00f3w zako\u0144czenia ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Nie mo\u017cna utworzy\u0107 instancji obiektu sprawdzaj\u0105cego Well-Formedness.  Parametr well-formed ustawiono na warto\u015b\u0107 true, ale nie mo\u017cna by\u0142o dokona\u0107 sprawdzenia poprawno\u015bci konstrukcji."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "W\u0119ze\u0142 ''{0}'' zawiera niepoprawne znaki XML."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "W komentarzu znaleziono niepoprawny znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "W danych instrukcji przetwarzania znaleziono niepoprawny znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "W sekcji CDATA znaleziono niepoprawny znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "W tre\u015bci danych znakowych w\u0119z\u0142a znaleziono niepoprawny znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "W {0} o nazwie ''{1}'' znaleziono niepoprawne znaki XML."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "Ci\u0105g znak\u00f3w \"--\" jest niedozwolony w komentarzu."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Warto\u015b\u0107 atrybutu \"{1}\" zwi\u0105zanego z typem elementu \"{0}\" nie mo\u017ce zawiera\u0107 znaku ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Odwo\u0142anie do encji nieprzetwarzanej \"&{0};\" jest niedozwolone."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Odwo\u0142anie do zewn\u0119trznej encji \"&{0};\" jest niedozwolone w warto\u015bci atrybutu."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Nie mo\u017cna zwi\u0105za\u0107 przedrostka \"{0}\" z przestrzeni\u0105 nazw \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Nazwa lokalna elementu \"{0}\" jest pusta (null)."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Nazwa lokalna atrybutu \"{0}\" jest pusta (null)."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "Tekst zast\u0119puj\u0105cy w\u0119z\u0142a encji \"{0}\" zawiera w\u0119ze\u0142 elementu \"{1}\" o niezwi\u0105zanym przedrostku \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Tekst zast\u0119puj\u0105cy w\u0119z\u0142a encji \"{0}\" zawiera w\u0119ze\u0142 atrybutu \"{1}\" o niezwi\u0105zanym przedrostku \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pt_BR.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pt_BR.java
new file mode 100644
index 0000000..b5bdb23
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_pt_BR.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_pt_BR.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_pt_BR extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "A chave de mensagem ''{0}'' n\u00e3o est\u00e1 na classe de mensagem ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "O formato da mensagem ''{0}'' na classe de mensagem ''{1}'' falhou." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "A classe de serializador ''{0}'' n\u00e3o implementa org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "O recurso [ {0} ] n\u00e3o p\u00f4de ser encontrado.\n{1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "O recurso [ {0} ] n\u00e3o p\u00f4de carregar: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Tamanho do buffer <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Detectado substituto UTF-16 inv\u00e1lido: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Erro de E/S" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Imposs\u00edvel incluir atributo {0} depois de n\u00f3s filhos ou antes da gera\u00e7\u00e3o de um elemento. O atributo ser\u00e1 ignorado." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "O espa\u00e7o de nomes do prefixo ''{0}'' n\u00e3o foi declarado. " },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atributo ''{0}'' fora do elemento. " },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Declara\u00e7\u00e3o de espa\u00e7o de nomes ''{0}''=''{1}'' fora do elemento. " },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "N\u00e3o foi poss\u00edvel carregar ''{0}'' (verifique CLASSPATH) agora , utilizando somente os padr\u00f5es" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Tentativa de processar o caractere de um valor integral {0} que n\u00e3o \u00e9 representado na codifica\u00e7\u00e3o de sa\u00edda especificada de {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "N\u00e3o foi poss\u00edvel carregar o arquivo de propriedade ''{0}'' para o m\u00e9todo de sa\u00edda ''{1}'' (verifique CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "N\u00famero de porta inv\u00e1lido" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "A porta n\u00e3o pode ser definida quando o host \u00e9 nulo" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "O host n\u00e3o \u00e9 um endere\u00e7o formado corretamente" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "O esquema n\u00e3o est\u00e1 em conformidade." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Imposs\u00edvel definir esquema a partir da cadeia nula" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "O caminho cont\u00e9m seq\u00fc\u00eancia de escape inv\u00e1lida" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "O caminho cont\u00e9m caractere inv\u00e1lido: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "O fragmento cont\u00e9m caractere inv\u00e1lido" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "O fragmento n\u00e3o pode ser definido quando o caminho \u00e9 nulo" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "O fragmento s\u00f3 pode ser definido para um URI gen\u00e9rico" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Nenhum esquema encontrado no URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Imposs\u00edvel inicializar URI com par\u00e2metros vazios" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "O fragmento n\u00e3o pode ser especificado no caminho e fragmento" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "A cadeia de consulta n\u00e3o pode ser especificada na cadeia de consulta e caminho" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Port n\u00e3o pode ser especificado se host n\u00e3o for especificado" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Userinfo n\u00e3o pode ser especificado se host n\u00e3o for especificado" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Aviso:  A vers\u00e3o do documento de sa\u00edda precisa ser ''{0}''.  Essa vers\u00e3o do XML n\u00e3o \u00e9 suportada. A vers\u00e3o do documento de sa\u00edda ser\u00e1 ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "O esquema \u00e9 obrigat\u00f3rio!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "O objeto Properties transmitido para SerializerFactory n\u00e3o tem uma propriedade ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Aviso:  A codifica\u00e7\u00e3o ''{0}'' n\u00e3o \u00e9 suportada pelo Java Runtime." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "O par\u00e2metro ''{0}'' n\u00e3o \u00e9 reconhecido."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "O par\u00e2metro ''{0}'' \u00e9 reconhecido, mas o valor pedido n\u00e3o pode ser definido. "},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "A cadeia resultante \u00e9 muito longa para caber em uma DOMString: ''{0}''. "},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "O tipo de valor para este nome de par\u00e2metro \u00e9 incompat\u00edvel com o tipo de valor esperado. "},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "O destino de sa\u00edda para os dados a serem gravados era nulo. "},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Uma codifica\u00e7\u00e3o n\u00e3o suportada foi encontrada. "},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "O n\u00f3 n\u00e3o p\u00f4de ser serializado."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "A Se\u00e7\u00e3o CDATA cont\u00e9m um ou mais marcadores de t\u00e9rmino ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Uma inst\u00e2ncia do verificador Well-Formedness n\u00e3o p\u00f4de ser criada. O par\u00e2metro well-formed foi definido como true, mas a verifica\u00e7\u00e3o well-formedness n\u00e3o pode ser executada."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "O n\u00f3 ''{0}'' cont\u00e9m caracteres XML inv\u00e1lidos. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "Um caractere XML inv\u00e1lido (Unicode: 0x{0}) foi encontrado no coment\u00e1rio. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "Um caractere XML inv\u00e1lido (Unicode: 0x{0}) foi encontrado no processo instructiondata."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "Um caractere XML inv\u00e1lido (Unicode: 0x{0}) foi encontrado nos conte\u00fados do CDATASection. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "Um caractere XML inv\u00e1lido (Unicode: 0x{0}) foi encontrado no conte\u00fado dos dados de caractere dos n\u00f3s. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "Um caractere inv\u00e1lido foi encontrado no {0} do n\u00f3 denominado ''{1}''."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "A cadeia \"--\" n\u00e3o \u00e9 permitida dentro dos coment\u00e1rios. "
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "O valor do atributo \"{1}\" associado a um tipo de elemento \"{0}\" n\u00e3o deve conter o caractere ''<''. "
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "A refer\u00eancia de entidade n\u00e3o analisada \"&{0};\" n\u00e3o \u00e9 permitida. "
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "A refer\u00eancia de entidade externa \"&{0};\" n\u00e3o \u00e9 permitida em um valor de atributo. "
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "O prefixo \"{0}\" n\u00e3o pode ser vinculado ao espa\u00e7o de nomes \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "O nome local do elemento \"{0}\" \u00e9 nulo."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "O nome local do atributo \"{0}\" \u00e9 nulo."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "O texto de substitui\u00e7\u00e3o do n\u00f3 de entidade \"{0}\" cont\u00e9m um n\u00f3 de elemento \"{1}\" com um prefixo n\u00e3o vinculado \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "O texto de substitui\u00e7\u00e3o do n\u00f3 de entidade \"{0}\" cont\u00e9m um n\u00f3 de atributo \"{1}\" com um prefixo n\u00e3o vinculado \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ru.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ru.java
new file mode 100644
index 0000000..2935048
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_ru.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_ru.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_ru extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "\u041a\u043b\u044e\u0447 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f ''{0}'' \u043d\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043a\u043b\u0430\u0441\u0441\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "\u0424\u043e\u0440\u043c\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f ''{0}'' \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f ''{1}'' \u0432\u044b\u0437\u0432\u0430\u043b \u043e\u0448\u0438\u0431\u043a\u0443. " },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "\u041a\u043b\u0430\u0441\u0441 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 ''{0}'' \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 org.xml.sax.ContentHandler. " },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "\u0420\u0435\u0441\u0443\u0440\u0441 [ {0} ] \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441 [ {0} ]: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "\u0420\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 UTF-16: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435\u043b\u044c\u0437\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0443\u0437\u043b\u043e\u0432 \u0438 \u0434\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0410\u0442\u0440\u0438\u0431\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d. " },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "\u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430 ''{0}'' \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043e. " },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "\u0410\u0442\u0440\u0438\u0431\u0443\u0442 ''{0}'' \u0432\u043d\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. " },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "\u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438\u043c\u0435\u043d ''{0}''=''{1}'' \u0432\u043d\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. " },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c ''{0}'' (\u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 CLASSPATH), \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "\u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 {0} \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 {1}. " },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0441\u0432\u043e\u0439\u0441\u0442\u0432 ''{0}'' \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 ''{1}'' (\u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 \u0445\u043e\u0441\u0442\u0430" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0445\u043e\u0441\u0442\u0430" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\u0421\u0445\u0435\u043c\u0430 \u043d\u0435 \u043a\u043e\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u0430." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\u0412 \u0438\u043c\u0435\u043d\u0438 \u043f\u0443\u0442\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f Esc-\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\u0412 \u0438\u043c\u0435\u043d\u0438 \u043f\u0443\u0442\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043f\u0443\u0442\u0438" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 URI" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "\u0412 URI \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0441\u0445\u0435\u043c\u0430" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c URI \u0441 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u043f\u0443\u0442\u0438 \u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "\u041d\u0435\u043b\u044c\u0437\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u043f\u0443\u0442\u0438 \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "\u041d\u0435\u043b\u044c\u0437\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d \u0445\u043e\u0441\u0442" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "\u041d\u0435\u043b\u044c\u0437\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d \u0445\u043e\u0441\u0442" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 ''{0}''. \u042d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f XML \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0412\u0435\u0440\u0441\u0438\u0435\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 ''1.0''. " },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0441\u0445\u0435\u043c\u0430!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "\u041e\u0431\u044a\u0435\u043a\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0432 SerializerFactory, \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c ''{0}''. " },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435:  \u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 ''{0}'' \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f Java." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 ''{0}'' \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d. "},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 ''{0}'' \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d, \u043d\u043e \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c. "},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "\u0421\u0442\u0440\u043e\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 DOMString: ''{0}''. "},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "\u0422\u0438\u043f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0441 \u044d\u0442\u0438 \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c \u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c \u0442\u0438\u043f\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. "},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. "},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043d\u0435\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430. "},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u0435\u043b. "},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "\u0420\u0430\u0437\u0434\u0435\u043b CDATA \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u0435\u0439 ']]>'. "},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 true, \u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c. "
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "\u0423\u0437\u0435\u043b ''{0}'' \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b XML. "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\u0412 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b XML (\u042e\u043d\u0438\u043a\u043e\u0434: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u041f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 instructiondata \u0431\u044b\u043b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b XML (\u042e\u043d\u0438\u043a\u043e\u0434: 0x{0}). "
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "\u0412 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c CDATASection \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b XML (\u042e\u043d\u0438\u043a\u043e\u0434: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\u0412 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b XML (\u042e\u043d\u0438\u043a\u043e\u0434: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b XML \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b \u0432 \u0443\u0437\u043b\u0435 {0} \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{1}''. "
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "\u0421\u0442\u0440\u043e\u043a\u0430 \"--\" \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. "
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \"{1}\", \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u0442\u0438\u043f\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \"{0}\", \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b ''<''. "
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\u041d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \"&{0};\" \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430. "
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\u0412\u043d\u0435\u0448\u043d\u044f\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \"&{0};\" \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430 \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430. "
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\u041f\u0440\u0435\u0444\u0438\u043a\u0441 \"{0}\" \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435  \u0438\u043c\u0435\u043d \"{1}\". "
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \"{0}\" \u043f\u0443\u0441\u0442\u043e. "
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \"{0}\" \u043f\u0443\u0441\u0442\u043e.  "
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u0422\u0435\u043a\u0441\u0442 \u0437\u0430\u043c\u0435\u043d\u044b \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \"{0}\" \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0443\u0437\u0435\u043b \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \"{1}\" \u0441 \u043d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \"{2}\". "
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u0422\u0435\u043a\u0441\u0442 \u0437\u0430\u043c\u0435\u043d\u044b \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \"{0}\" \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0443\u0437\u0435\u043b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \"{1}\" \u0441 \u043d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \"{2}\". "
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sk.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sk.java
new file mode 100755
index 0000000..fdabf07
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sk.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_sk.java,v 1.7 2005/03/07 20:34:36 minchau Exp $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_sk extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "K\u013e\u00fa\u010d spr\u00e1vy ''{0}'' sa nenach\u00e1dza v triede spr\u00e1v ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Zlyhal form\u00e1t spr\u00e1vy ''{0}'' v triede spr\u00e1v ''{1}''." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "Trieda serializ\u00e1tora ''{0}'' neimplementuje org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Prostriedok [ {0} ] nemohol by\u0165 n\u00e1jden\u00fd.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Prostriedok [ {0} ] sa nedal na\u010d\u00edta\u0165: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Ve\u013ekos\u0165 vyrovn\u00e1vacej pam\u00e4te <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Bolo zisten\u00e9 neplatn\u00e9 nahradenie UTF-16: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "chyba IO" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Nie je mo\u017en\u00e9 prida\u0165 atrib\u00fat {0} po uzloch potomka alebo pred vytvoren\u00edm elementu.  Atrib\u00fat bude ignorovan\u00fd." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "N\u00e1zvov\u00fd priestor pre predponu ''{0}'' nebol deklarovan\u00fd." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atrib\u00fat ''{0}'' je mimo prvku." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Deklar\u00e1cia n\u00e1zvov\u00e9ho priestoru ''{0}''=''{1}'' je mimo prvku." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Nebolo mo\u017en\u00e9 zavies\u0165 ''{0}'' (skontrolujte CLASSPATH), teraz sa pou\u017e\u00edvaj\u00fa iba \u0161tandardn\u00e9 nastavenia" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Pokus o v\u00fdstup znaku integr\u00e1lnej hodnoty {0}, ktor\u00e1 nie je reprezentovan\u00e1 v zadanom v\u00fdstupnom k\u00f3dovan\u00ed {1}." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Nebolo mo\u017en\u00e9 zavies\u0165 s\u00fabor vlastnost\u00ed ''{0}'' pre v\u00fdstupn\u00fa met\u00f3du ''{1}'' (skontrolujte CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Neplatn\u00e9 \u010d\u00edslo portu" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Nem\u00f4\u017ee by\u0165 stanoven\u00fd port, ak je hostite\u013e nulov\u00fd" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Hostite\u013e nie je spr\u00e1vne form\u00e1tovan\u00e1 adresa" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Nezhodn\u00e1 sch\u00e9ma." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Nie je mo\u017en\u00e9 stanovi\u0165 sch\u00e9mu z nulov\u00e9ho re\u0165azca" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Cesta obsahuje neplatn\u00fa \u00fanikov\u00fa sekvenciu" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Cesta obsahuje neplatn\u00fd znak: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment obsahuje neplatn\u00fd znak" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Ak je cesta nulov\u00e1, nem\u00f4\u017ee by\u0165 stanoven\u00fd fragment" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment m\u00f4\u017ee by\u0165 stanoven\u00fd len pre v\u0161eobecn\u00e9 URI" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "V URI nebola n\u00e1jden\u00e1 \u017eiadna sch\u00e9ma" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Nie je mo\u017en\u00e9 inicializova\u0165 URI s pr\u00e1zdnymi parametrami" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Fragment nem\u00f4\u017ee by\u0165 zadan\u00fd v ceste, ani vo fragmente" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Re\u0165azec dotazu nem\u00f4\u017ee by\u0165 zadan\u00fd v ceste a re\u0165azci dotazu" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Ak nebol zadan\u00fd hostite\u013e, mo\u017eno nebol zadan\u00fd port" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Ak nebol zadan\u00fd hostite\u013e, mo\u017eno nebolo zadan\u00e9 userinfo" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Varovanie:  Verzia v\u00fdstupn\u00e9ho dokumentu mus\u00ed by\u0165 povinne ''{0}''.  T\u00e1to verzia XML nie je podporovan\u00e1.  Verzia v\u00fdstupn\u00e9ho dokumentu bude ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Je po\u017eadovan\u00e1 sch\u00e9ma!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "Objekt Properties, ktor\u00fd pre\u0161iel do SerializerFactory, nem\u00e1 vlastnos\u0165 ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Varovanie:  Java runtime nepodporuje k\u00f3dovanie ''{0}''." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Parameter ''{0}'' nebol rozpoznan\u00fd."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Parameter ''{0}'' bol rozpoznan\u00fd, ale vy\u017eadovan\u00e1 hodnota sa ned\u00e1 nastavi\u0165."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "V\u00fdsledn\u00fd re\u0165azec je pr\u00edli\u0161 dlh\u00fd a nezmest\u00ed sa do DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Typ hodnoty pre tento n\u00e1zov parametra je nekompatibiln\u00fd s o\u010dak\u00e1van\u00fdm typom hodnoty."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Cie\u013e v\u00fdstupu pre zap\u00edsanie \u00fadajov bol null."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Bolo zaznamenan\u00e9 nepodporovan\u00e9 k\u00f3dovanie."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Uzol nebolo mo\u017en\u00e9 serializova\u0165."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "\u010cas\u0165 CDATA obsahuje jeden alebo viacer\u00e9 ozna\u010dova\u010de konca ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Nebolo mo\u017en\u00e9 vytvori\u0165 in\u0161tanciu kontrol\u00f3ra Well-Formedness.  Parameter well-formed bol nastaven\u00fd na hodnotu true, ale kontrola well-formedness sa ned\u00e1 vykona\u0165."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Uzol ''{0}'' obsahuje neplatn\u00e9 znaky XML."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "V koment\u00e1ri bol n\u00e1jden\u00fd neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "Pri spracovan\u00ed d\u00e1t in\u0161trukci\u00ed sa na\u0161iel neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "V obsahu CDATASection sa na\u0161iel neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "V obsahu znakov\u00fdch d\u00e1t uzla sa na\u0161iel neplatn\u00fd znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "V uzle {0} s n\u00e1zvom ''{1}'' sa na\u0161iel neplatn\u00fd znak XML."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "Re\u0165azec \"--\" nie je povolen\u00fd v r\u00e1mci koment\u00e1rov."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Hodnota atrib\u00fatu \"{1}\", ktor\u00e1 je priraden\u00e1 k prvku typu \"{0}\", nesmie obsahova\u0165 znak ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Neanalyzovan\u00fd odkaz na entitu \"&{0};\" nie je povolen\u00fd."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Odkaz na extern\u00fa entitu \"&{0};\" nie je povolen\u00fd v hodnote atrib\u00fatu."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Predpona \"{0}\" nem\u00f4\u017ee by\u0165 naviazan\u00e1 na n\u00e1zvov\u00fd priestor \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Lok\u00e1lny n\u00e1zov prvku \"{0}\" je null."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Lok\u00e1lny n\u00e1zov atrib\u00fatu \"{0}\" je null."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "N\u00e1hradn\u00fd text pre uzol entity \"{0}\" obsahuje uzol prvku \"{1}\" s nenaviazanou predponou \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "N\u00e1hradn\u00fd text uzla entity \"{0}\" obsahuje uzol atrib\u00fatu \"{1}\" s nenaviazanou predponou \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sl.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sl.java
new file mode 100755
index 0000000..fa40d4e
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sl.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_sl.java,v 1.7 2005/03/07 20:34:36 minchau Exp $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_sl extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "Klju\u010d sporo\u010dila ''{0}'' ni v rezredu sporo\u010dila ''{1}''" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "Format sporo\u010dila ''{0}'' v razredu sporo\u010dila ''{1}'' je spodletel." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "Razred serializerja ''{0}'' ne izvede org.xml.sax.ContentHandler." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Vira [ {0} ] ni mogo\u010de najti.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Sredstva [ {0} ] ni bilo mogo\u010de nalo\u017eiti: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Velikost medpomnilnika <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "Zaznan neveljaven nadomestek UTF-16: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "Napaka V/I" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Atributa {0} ne morem dodati za podrejenimi vozli\u0161\u010di ali pred izdelavo elementa.  Atribut bo prezrt." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "Imenski prostor za predpono ''{0}'' ni bil naveden." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "Atribut ''{0}'' je zunaj elementa." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "Deklaracija imenskega prostora ''{0}''=''{1}'' je zunaj elementa." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "Ni bilo mogo\u010de nalo\u017eiti ''{0}'' (preverite CLASSPATH), trenutno se uporabljajo samo privzete vrednosti" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Poskus izpisa znaka integralne vrednosti {0}, ki v navedenem izhodnem kodiranju {1} ni zastopan." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "Datoteke z lastnostmi ''{0}'' ni bilo mogo\u010de nalo\u017eiti za izhodno metodo ''{1}'' (preverite CLASSPATH)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Neveljavna \u0161tevilka vrat" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Ko je gostitelj NULL, nastavitev vrat ni mogo\u010da" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Naslov gostitelja ni pravilno oblikovan" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "Shema ni skladna." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Ni mogo\u010de nastaviti sheme iz niza NULL" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Pot vsebuje neveljavno zaporedje za izhod" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Pot vsebuje neveljaven znak: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Fragment vsebuje neveljaven znak" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Ko je pot NULL, nastavitev fragmenta ni mogo\u010da" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Fragment je lahko nastavljen samo za splo\u0161ni URI" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "Ne najdem sheme v URI" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Ni mogo\u010de inicializirati URI-ja s praznimi parametri" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Fragment ne more biti hkrati naveden v poti in v fragmentu" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Poizvedbeni niz ne more biti naveden v nizu poti in poizvedbenem nizu" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Vrata ne morejo biti navedena, \u010de ni naveden gostitelj" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Informacije o uporabniku ne morejo biti navedene, \u010de ni naveden gostitelj" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Opozorilo: Zahtevana razli\u010dica izhodnega dokumenta je ''{0}''.  Ta razli\u010dica XML ni podprta.  Razli\u010dica izhodnega dokumenta bo ''1.0''." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "Zahtevana je shema!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "Predmet Properties (lastnosti), ki je prene\u0161en v SerializerFactory, nima lastnosti ''{0}''." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Opozorilo:  Izvajalno okolje Java ne podpira kodiranja ''{0}''." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "Parameter ''{0}'' ni prepoznan."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "Parameter ''{0}'' je prepoznan, vendar pa zahtevane vrednosti ni mogo\u010de nastaviti."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "Nastali niz je predolg za DOMString: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Tip vrednosti za to ime parametra je nezdru\u017eljiv s pri\u010dakovanim tipom vrednosti."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Izhodno mesto za vpisovanje podatkov je bilo ni\u010d."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Odkrito je nepodprto kodiranje."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "Vozli\u0161\u010da ni mogo\u010de serializirati."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "Odsek CDATA vsebuje enega ali ve\u010d ozna\u010devalnikov prekinitve ']]>'."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Primerka preverjevalnika Well-Formedness ni bilo mogo\u010de ustvariti.  Parameter well-formed je bil nastavljen na True, ampak ni mogo\u010de preveriti well-formedness."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "Vozli\u0161\u010de ''{0}'' vsebuje neveljavne znake XML."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "V komentarju je bil najden neveljaven XML znak (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "V podatkih navodila za obdelavo je bil najden neveljaven znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "V vsebini odseka CDATASection je bil najden neveljaven znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "V podatkovni vsebini znaka vozli\u0161\u010da je bil najden neveljaven znak XML (Unicode: 0x{0})."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "V vozli\u0161\u010du {0} z imenom ''{1}'' je bil najden neveljaven znak XML."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "Niz \"--\" ni dovoljen v komentarjih."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "Vrednost atributa \"{1}\", ki je povezan s tipom elementa \"{0}\", ne sme vsebovati znaka ''<''."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "Neraz\u010dlenjeni sklic entitete \"&{0};\" ni dovoljen."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "Zunanji sklic entitete \"&{0};\" ni dovoljen v vrednosti atributa."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "Predpona \"{0}\" ne more biti povezana z imenskim prostorom \"{1}\"."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "Lokalno ime elementa \"{0}\" je ni\u010d."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "Lokalno ime atributa \"{0}\" je ni\u010d."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "Besedilo za zamenjavo za vozli\u0161\u010de entitete \"{0}\" vsebuje vozli\u0161\u010de elementa \"{1}\" z nevezano predpono \"{2}\"."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "Besedilo za zamenjavo za vozli\u0161\u010de entitete \"{0}\" vsebuje vozli\u0161\u010de atributa \"{1}\" z nevezano predpono \"{2}\"."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sv.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sv.java
new file mode 100644
index 0000000..717ac41
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_sv.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_sv.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+
+public class SerializerMessages_sv extends ListResourceBundle {
+  public Object[][] getContents() {
+    Object[][] contents =  new Object[][] {
+        // BAD_MSGKEY needs translation
+        // BAD_MSGFORMAT needs translation
+        // ER_SERIALIZER_NOT_CONTENTHANDLER needs translation
+        // ER_RESOURCE_COULD_NOT_FIND needs translation
+        // ER_RESOURCE_COULD_NOT_LOAD needs translation
+        // ER_BUFFER_SIZE_LESSTHAN_ZERO needs translation
+        // ER_INVALID_UTF16_SURROGATE needs translation
+        // ER_OIERROR needs translation
+        // ER_ILLEGAL_ATTRIBUTE_POSITION needs translation
+        // ER_NAMESPACE_PREFIX needs translation
+        // ER_STRAY_ATTRIBUTE needs translation
+        // ER_STRAY_NAMESPACE needs translation
+        // ER_COULD_NOT_LOAD_RESOURCE needs translation
+        // ER_ILLEGAL_CHARACTER needs translation
+        // ER_COULD_NOT_LOAD_METHOD_PROPERTY needs translation
+      { MsgKey.ER_INVALID_PORT,
+        "Ogiltigt portnummer"},
+
+      { MsgKey.ER_PORT_WHEN_HOST_NULL,
+        "Port kan inte s\u00e4ttas n\u00e4r v\u00e4rd \u00e4r null"},
+
+      { MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+        "V\u00e4rd \u00e4r inte en v\u00e4lformulerad adress"},
+
+      { MsgKey.ER_SCHEME_NOT_CONFORMANT,
+        "Schemat \u00e4r inte likformigt."},
+
+      { MsgKey.ER_SCHEME_FROM_NULL_STRING,
+        "Kan inte s\u00e4tta schema fr\u00e5n null-str\u00e4ng"},
+
+      { MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+        "V\u00e4g inneh\u00e5ller ogiltig flyktsekvens"},
+
+      { MsgKey.ER_PATH_INVALID_CHAR,
+        "V\u00e4g inneh\u00e5ller ogiltigt tecken: {0}"},
+
+      { MsgKey.ER_FRAG_INVALID_CHAR,
+        "Fragment inneh\u00e5ller ogiltigt tecken"},
+
+      { MsgKey.ER_FRAG_WHEN_PATH_NULL,
+        "Fragment kan inte s\u00e4ttas n\u00e4r v\u00e4g \u00e4r null"},
+
+      { MsgKey.ER_FRAG_FOR_GENERIC_URI,
+        "Fragment kan bara s\u00e4ttas f\u00f6r en allm\u00e4n URI"},
+
+      { MsgKey.ER_NO_SCHEME_IN_URI,
+        "Schema saknas i URI: {0}"},
+
+      { MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+        "Kan inte initialisera URI med tomma parametrar"},
+
+      { MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+        "Fragment kan inte anges i b\u00e5de v\u00e4gen och fragmentet"},
+
+      { MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+        "F\u00f6rfr\u00e5gan-str\u00e4ng kan inte anges i v\u00e4g och f\u00f6rfr\u00e5gan-str\u00e4ng"},
+
+      { MsgKey.ER_NO_PORT_IF_NO_HOST,
+        "Port f\u00e5r inte anges om v\u00e4rden inte \u00e4r angiven"},
+
+      { MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+        "Userinfo f\u00e5r inte anges om v\u00e4rden inte \u00e4r angiven"},
+
+      { MsgKey.ER_SCHEME_REQUIRED,
+        "Schema kr\u00e4vs!"}
+
+    };
+    return contents;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_tr.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_tr.java
new file mode 100644
index 0000000..58d0088
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_tr.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_tr.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_tr extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "''{0}'' ileti anahtar\u0131 ''{1}'' ileti s\u0131n\u0131f\u0131nda yok" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "''{1}'' ileti s\u0131n\u0131f\u0131ndaki ''{0}'' iletisinin bi\u00e7imi ba\u015far\u0131s\u0131z." },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "''{0}'' diziselle\u015ftirme s\u0131n\u0131f\u0131 org.xml.sax.ContentHandler s\u0131n\u0131f\u0131n\u0131 ger\u00e7ekle\u015ftirmiyor." },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "Kaynak [ {0} ] bulunamad\u0131.\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "Kaynak [ {0} ] y\u00fckleyemedi: {1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "Arabellek b\u00fcy\u00fckl\u00fc\u011f\u00fc <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "UTF-16 yerine kullan\u0131lan de\u011fer ge\u00e7ersiz: {0} ?" },
+
+            {   MsgKey.ER_OIERROR,
+                "G\u00c7 hatas\u0131" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "Alt d\u00fc\u011f\u00fcmlerden sonra ya da bir \u00f6\u011fe \u00fcretilmeden \u00f6nce {0} \u00f6zniteli\u011fi eklenemez.  \u00d6znitelik yoksay\u0131lacak." },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "''{0}'' \u00f6nekine ili\u015fkin ad alan\u0131 bildirilmedi." },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "''{0}'' \u00f6zniteli\u011fi \u00f6\u011fenin d\u0131\u015f\u0131nda." },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "''{0}''=''{1}'' ad alan\u0131 bildirimi \u00f6\u011fenin d\u0131\u015f\u0131nda." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "''{0}'' y\u00fcklenemedi (CLASSPATH de\u011fi\u015fkeninizi inceleyin), yaln\u0131zca varsay\u0131lanlar kullan\u0131l\u0131yor" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "Belirtilen {1} \u00e7\u0131k\u0131\u015f kodlamas\u0131nda g\u00f6sterilmeyen {0} t\u00fcmlev de\u011feri karakteri \u00e7\u0131k\u0131\u015f giri\u015fimi." },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "''{1}'' \u00e7\u0131k\u0131\u015f y\u00f6ntemi i\u00e7in ''{0}'' \u00f6zellik dosyas\u0131 y\u00fcklenemedi (CLASSPATH de\u011fi\u015fkenini inceleyin)" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "Kap\u0131 numaras\u0131 ge\u00e7ersiz" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "Anasistem bo\u015f de\u011ferliyken kap\u0131 tan\u0131mlanamaz" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "Anasistem do\u011fru bi\u00e7imli bir adres de\u011fil" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\u015eema uyumlu de\u011fil." },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "Bo\u015f de\u011ferli dizgiden \u015fema tan\u0131mlanamaz" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "Yol ge\u00e7ersiz ka\u00e7\u0131\u015f dizisi i\u00e7eriyor" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "Yol ge\u00e7ersiz karakter i\u00e7eriyor: {0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "Par\u00e7a ge\u00e7ersiz karakter i\u00e7eriyor" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "Yol bo\u015f de\u011ferliyken par\u00e7a tan\u0131mlanamaz" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "Par\u00e7a yaln\u0131zca soysal URI i\u00e7in tan\u0131mlanabilir" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "URI i\u00e7inde \u015fema bulunamad\u0131" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "Bo\u015f de\u011fi\u015ftirgelerle URI kullan\u0131ma haz\u0131rlanamaz" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "Par\u00e7a hem yolda, hem de par\u00e7ada belirtilemez" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "Yol ve sorgu dizgisinde sorgu dizgisi belirtilemez" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "Anasistem belirtilmediyse kap\u0131 belirtilemez" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "Anasistem belirtilmediyse kullan\u0131c\u0131 bilgisi belirtilemez" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "Uyar\u0131:  \u00c7\u0131k\u0131\u015f belgesinin s\u00fcr\u00fcm\u00fcn\u00fcn ''{0}'' olmas\u0131 isteniyor.  Bu XML s\u00fcr\u00fcm\u00fc desteklenmez.  \u00c7\u0131k\u0131\u015f dosyas\u0131n\u0131n s\u00fcr\u00fcm\u00fc ''1.0'' olacak." },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u015eema gerekli!" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "SerializerFactory''ye ge\u00e7irilen Properties nesnesinin bir ''{0}'' \u00f6zelli\u011fi yok." },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "Uyar\u0131: ''{0}'' kodlamas\u0131 Java Runtime taraf\u0131ndan desteklenmiyor." },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "''{0}'' de\u011fi\u015ftirgesi tan\u0131nm\u0131yor."},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "''{0}'' de\u011fi\u015ftirgesi tan\u0131n\u0131yor, ancak istenen de\u011fer tan\u0131mlanam\u0131yor."},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "Sonu\u00e7 dizgisi DOMString i\u00e7in \u00e7ok uzun: ''{0}''."},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "Bu de\u011fi\u015ftirge ad\u0131na ili\u015fkin de\u011fer tipi, beklenen de\u011fer tipiyle uyumlu de\u011fil."},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "Yaz\u0131lacak verilerin \u00e7\u0131k\u0131\u015f hedefi bo\u015f de\u011ferli."},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "Desteklenmeyen bir kodlama saptand\u0131."},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "D\u00fc\u011f\u00fcm diziselle\u015ftirilemedi."},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "CDATA k\u0131sm\u0131nda bir ya da daha \u00e7ok ']]>' sonland\u0131rma imleyicisi var."},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "Well-Formedness denet\u015feyicisinin somut \u00f6rne\u011fi yarat\u0131lamad\u0131.  well-formed de\u011fi\u015ftirgesi true de\u011ferine ayarland\u0131, ancak do\u011fru bi\u00e7im denetimi ger\u00e7ekle\u015ftirilemiyor."
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "''{0}'' d\u00fc\u011f\u00fcm\u00fc ge\u00e7ersiz XML karakterleri i\u00e7eriyor."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "A\u00e7\u0131klamada ge\u00e7ersiz bir XML karakteri (Unicode: 0x{0}) saptand\u0131."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u0130\u015fleme y\u00f6nergesi verilerinde ge\u00e7ersiz bir XML karakteri (Unicode: 0x{0}) saptand\u0131."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "CDATASection i\u00e7eri\u011finde ge\u00e7ersiz bir XML karakteri (Unicode: 0x{0}) saptand\u0131."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "D\u00fc\u011f\u00fcm\u00fcn karakter verileri i\u00e7eri\u011finde ge\u00e7ersiz bir XML karakteri (Unicode: 0x{0}) saptand\u0131."
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "''{1}'' adl\u0131 {0} d\u00fc\u011f\u00fcm\u00fcnde ge\u00e7ersiz XML karakteri saptand\u0131."
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "A\u00e7\u0131klamalar i\u00e7inde \"--\" dizgisine izin verilmez."
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\"{0}\" \u00f6\u011fe tipiyle ili\u015fkilendirilen \"{1}\" \u00f6zniteli\u011finin de\u011feri ''<'' karakteri i\u00e7ermemelidir."
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\"&{0};\" ayr\u0131\u015ft\u0131r\u0131lmam\u0131\u015f varl\u0131k ba\u015fvurusuna izin verilmez."
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\u00d6znitelik de\u011ferinde \"&{0};\" d\u0131\u015f varl\u0131k ba\u015fvurusuna izin verilmez."
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\"{0}\" \u00f6neki \"{1}\" ad alan\u0131na ba\u011flanam\u0131yor."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\"{0}\" \u00f6\u011fesinin yerel ad\u0131 bo\u015f de\u011ferli."
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\"{0}\" \u00f6zniteli\u011finin yerel ad\u0131 bo\u015f de\u011ferli."
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\"{0}\" varl\u0131k d\u00fc\u011f\u00fcm\u00fcn\u00fcn yerine koyma metninde, ba\u011flanmam\u0131\u015f \"{2}\" \u00f6neki bulunan bir \u00f6\u011fe d\u00fc\u011f\u00fcm\u00fc (\"{1}\") var."
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\"{0}\" varl\u0131k d\u00fc\u011f\u00fcm\u00fcn\u00fcn yerine koyma metninde, ba\u011flanmam\u0131\u015f \"{2}\" \u00f6neki bulunan bir \u00f6znitelik d\u00fc\u011f\u00fcm\u00fc (\"{1}\") var."
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh.java
new file mode 100755
index 0000000..dbb230d
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh.java
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_zh.java,v 1.7 2005/03/07 20:34:36 minchau Exp $
+ */
+
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_zh extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "\u6d88\u606f\u5bc6\u94a5\u201c{0}\u201d\u4e0d\u5728\u6d88\u606f\u7c7b\u201c{1}\u201d\u4e2d" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "\u6d88\u606f\u7c7b\u201c{1}\u201d\u4e2d\u7684\u6d88\u606f\u201c{0}\u201d\u7684\u683c\u5f0f\u65e0\u6548\u3002" },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "\u4e32\u884c\u5668\u7c7b\u201c{0}\u201d\u4e0d\u80fd\u5b9e\u73b0 org.xml.sax.ContentHandler\u3002" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "\u627e\u4e0d\u5230\u8d44\u6e90 [ {0} ]\u3002\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "\u8d44\u6e90 [ {0} ] \u65e0\u6cd5\u88c5\u5165\uff1a{1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "\u7f13\u51b2\u533a\u5927\u5c0f <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u68c0\u6d4b\u5230\u65e0\u6548\u7684 UTF-16 \u8d85\u5927\u5b57\u7b26\u96c6\uff1a{0}\uff1f" },
+
+            {   MsgKey.ER_OIERROR,
+                "IO \u9519\u8bef" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "\u5728\u751f\u6210\u5b50\u8282\u70b9\u4e4b\u540e\u6216\u5728\u751f\u6210\u5143\u7d20\u4e4b\u524d\u65e0\u6cd5\u6dfb\u52a0\u5c5e\u6027 {0}\u3002\u5c06\u5ffd\u7565\u5c5e\u6027\u3002" },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "\u5c1a\u672a\u58f0\u660e\u524d\u7f00\u201c{0}\u201d\u7684\u540d\u79f0\u7a7a\u95f4\u3002" },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "\u5c5e\u6027\u201c{0}\u201d\u5728\u5143\u7d20\u5916\u3002" },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "\u540d\u79f0\u7a7a\u95f4\u58f0\u660e\u201c{0}\u201d=\u201c{1}\u201d\u5728\u5143\u7d20\u5916\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "\u65e0\u6cd5\u88c5\u5165\u201c{0}\u201d\uff08\u68c0\u67e5 CLASSPATH\uff09\uff0c\u73b0\u5728\u53ea\u4f7f\u7528\u7f3a\u7701\u503c" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "\u5c1d\u8bd5\u8f93\u51fa\u6574\u6570\u503c {0}\uff08\u5b83\u4e0d\u662f\u4ee5\u6307\u5b9a\u7684 {1} \u8f93\u51fa\u7f16\u7801\u8868\u793a\uff09\u7684\u5b57\u7b26\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "\u65e0\u6cd5\u4e3a\u8f93\u51fa\u65b9\u6cd5\u201c{1}\u201d\u88c5\u5165\u5c5e\u6027\u6587\u4ef6\u201c{0}\u201d\uff08\u68c0\u67e5 CLASSPATH\uff09" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\u7aef\u53e3\u53f7\u65e0\u6548" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "\u4e3b\u673a\u4e3a\u7a7a\u65f6\uff0c\u65e0\u6cd5\u8bbe\u7f6e\u7aef\u53e3" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "\u4e3b\u673a\u4e0d\u662f\u683c\u5f0f\u6b63\u786e\u7684\u5730\u5740" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\u6a21\u5f0f\u4e0d\u4e00\u81f4\u3002" },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "\u65e0\u6cd5\u4ece\u7a7a\u5b57\u7b26\u4e32\u8bbe\u7f6e\u6a21\u5f0f" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\u8def\u5f84\u5305\u542b\u65e0\u6548\u7684\u8f6c\u4e49\u5e8f\u5217" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\u8def\u5f84\u5305\u542b\u65e0\u6548\u7684\u5b57\u7b26\uff1a{0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "\u7247\u6bb5\u5305\u542b\u65e0\u6548\u7684\u5b57\u7b26" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "\u8def\u5f84\u4e3a\u7a7a\u65f6\uff0c\u65e0\u6cd5\u8bbe\u7f6e\u7247\u6bb5" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "\u53ea\u80fd\u4e3a\u7c7b\u5c5e URI \u8bbe\u7f6e\u7247\u6bb5" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "URI \u4e2d\u627e\u4e0d\u5230\u4efb\u4f55\u6a21\u5f0f" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "\u4e0d\u80fd\u4ee5\u7a7a\u53c2\u6570\u521d\u59cb\u5316 URI" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "\u8def\u5f84\u548c\u7247\u6bb5\u4e2d\u90fd\u4e0d\u80fd\u6307\u5b9a\u7247\u6bb5" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "\u8def\u5f84\u548c\u67e5\u8be2\u5b57\u7b26\u4e32\u4e2d\u4e0d\u80fd\u6307\u5b9a\u67e5\u8be2\u5b57\u7b26\u4e32" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u4e3b\u673a\uff0c\u5219\u4e0d\u53ef\u4ee5\u6307\u5b9a\u7aef\u53e3" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u4e3b\u673a\uff0c\u5219\u4e0d\u53ef\u4ee5\u6307\u5b9a\u7528\u6237\u4fe1\u606f" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "\u8b66\u544a\uff1a\u8981\u6c42\u8f93\u51fa\u6587\u6863\u7684\u7248\u672c\u662f\u201c{0}\u201d\u3002\u4e0d\u652f\u6301\u6b64 XML \u7248\u672c\u3002\u8f93\u51fa\u6587\u6863\u7684\u7248\u672c\u5c06\u4f1a\u662f\u201c1.0\u201d\u3002" },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u6a21\u5f0f\u662f\u5fc5\u9700\u7684\uff01" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "\u4f20\u9012\u7ed9 SerializerFactory \u7684 Properties \u5bf9\u8c61\u4e0d\u5177\u6709\u5c5e\u6027\u201c{0}\u201d\u3002" },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "\u672a\u8bc6\u522b\u51fa\u53c2\u6570\u201c{0}\u201d\u3002"},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "\u5df2\u8bc6\u522b\u51fa\u53c2\u6570\u201c{0}\u201d\uff0c\u4f46\u65e0\u6cd5\u8bbe\u7f6e\u8bf7\u6c42\u7684\u503c\u3002"},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "\u4ea7\u751f\u7684\u5b57\u7b26\u4e32\u8fc7\u957f\u4e0d\u80fd\u88c5\u5165 DOMString\uff1a\u201c{0}\u201d\u3002"},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "\u6b64\u53c2\u6570\u540d\u79f0\u7684\u503c\u7c7b\u578b\u4e0e\u671f\u671b\u7684\u503c\u7c7b\u578b\u4e0d\u517c\u5bb9\u3002"},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "\u5c06\u8981\u5199\u5165\u6570\u636e\u7684\u8f93\u51fa\u76ee\u6807\u4e3a\u7a7a\u3002"},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\u9047\u5230\u4e0d\u53d7\u652f\u6301\u7684\u7f16\u7801\u3002"},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "\u65e0\u6cd5\u5c06\u8282\u70b9\u5e8f\u5217\u5316\u3002 "},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "CDATA \u90e8\u5206\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u7ec8\u6b62\u6807\u8bb0\u201c]]>\u201d\u3002"},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "\u65e0\u6cd5\u521b\u5efa\u683c\u5f0f\u6b63\u786e\u6027\u68c0\u67e5\u5668\u7684\u5b9e\u4f8b\u3002\u201c\u683c\u5f0f\u6b63\u786e\u201d\u53c2\u6570\u5df2\u8bbe\u7f6e\u4e3a true\uff0c\u4f46\u65e0\u6cd5\u6267\u884c\u683c\u5f0f\u6b63\u786e\u6027\u68c0\u67e5\u3002"
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "\u8282\u70b9\u201c{0}\u201d\u5305\u542b\u65e0\u6548\u7684 XML \u5b57\u7b26\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\u5728\u6ce8\u91ca\u4e2d\u627e\u5230\u65e0\u6548\u7684 XML \u5b57\u7b26 (Unicode: 0x''{0})''\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u5728\u5904\u7406\u6307\u4ee4\u6570\u636e\u4e2d\u627e\u5230\u65e0\u6548\u7684 XML \u5b57\u7b26 (Unicode: 0x''{0})''\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "\u5728 CDATA \u90e8\u5206\u7684\u5185\u5bb9\u4e2d\u627e\u5230\u65e0\u6548\u7684 XML \u5b57\u7b26 (Unicode: 0x''{0})''\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\u5728\u8282\u70b9\u7684\u5b57\u7b26\u6570\u636e\u5185\u5bb9\u4e2d\u627e\u5230\u65e0\u6548\u7684 XML \u5b57\u7b26 (Unicode: 0x''{0})''\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "\u540d\u79f0\u4e3a\u201c{1})\u201d\u7684\u201c{0})\u201d\u4e2d\u627e\u5230\u65e0\u6548\u7684 XML \u5b57\u7b26\u3002"
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "\u6ce8\u91ca\u4e2d\u4e0d\u5141\u8bb8\u6709\u5b57\u7b26\u4e32\u201c--\u201d\u3002"
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\u4e0e\u5143\u7d20\u7c7b\u578b\u201c{0}\u201d\u5173\u8054\u7684\u5c5e\u6027\u201c{1}\u201d\u7684\u503c\u4e0d\u5f97\u5305\u542b\u201c<\u201d\u5b57\u7b26\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\u4e0d\u5141\u8bb8\u6709\u672a\u89e3\u6790\u7684\u5b9e\u4f53\u5f15\u7528\u201c&{0};\u201d\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\u5c5e\u6027\u503c\u4e2d\u4e0d\u5141\u8bb8\u6709\u5916\u90e8\u5b9e\u4f53\u5f15\u7528\u201c&{0};\u201d\u3002"
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\u524d\u7f00\u201c{0}\u201d\u4e0d\u80fd\u7ed1\u5b9a\u5230\u540d\u79f0\u7a7a\u95f4\u201c{1}\u201d\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\u5143\u7d20\u201c{0}\u201d\u7684\u5c40\u90e8\u540d\u4e3a\u7a7a\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\u5c5e\u6027\u201c{0}\u201d\u7684\u5c40\u90e8\u540d\u4e3a\u7a7a\u3002"
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5b9e\u4f53\u8282\u70b9\u201c{0}\u201d\u7684\u66ff\u4ee3\u6587\u672c\u4e2d\u5305\u542b\u5143\u7d20\u8282\u70b9\u201c{1}\u201d\uff0c\u8be5\u8282\u70b9\u5177\u6709\u672a\u7ed1\u5b9a\u7684\u524d\u7f00\u201c{2}\u201d\u3002"
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5b9e\u4f53\u8282\u70b9\u201c{0}\u201d\u7684\u66ff\u4ee3\u6587\u672c\u4e2d\u5305\u542b\u5c5e\u6027\u8282\u70b9\u201c{1}\u201d\uff0c\u8be5\u8282\u70b9\u5177\u6709\u672a\u7ed1\u5b9a\u7684\u524d\u7f00\u201c{2}\u201d\u3002"
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_CN.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_CN.java
new file mode 100644
index 0000000..e8719ac
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_CN.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_zh_CN.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+
+public class SerializerMessages_zh_CN extends SerializerMessages_zh
+{
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_TW.java b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_TW.java
new file mode 100644
index 0000000..9525b18
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SerializerMessages_zh_TW.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SerializerMessages_zh_TW.java 471981 2006-11-07 04:28:00Z minchau $
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An instance of this class is a ListResourceBundle that
+ * has the required getContents() method that returns
+ * an array of message-key/message associations.
+ * <p>
+ * The message keys are defined in {@link MsgKey}. The
+ * messages that those keys map to are defined here.
+ * <p>
+ * The messages in the English version are intended to be
+ * translated.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer.
+ *
+ * @xsl.usage internal
+ */
+public class SerializerMessages_zh_TW extends ListResourceBundle {
+
+    /*
+     * This file contains error and warning messages related to
+     * Serializer Error Handling.
+     *
+     *  General notes to translators:
+
+     *  1) A stylesheet is a description of how to transform an input XML document
+     *     into a resultant XML document (or HTML document or text).  The
+     *     stylesheet itself is described in the form of an XML document.
+
+     *
+     *  2) An element is a mark-up tag in an XML document; an attribute is a
+     *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+     *     "elem" is an element name, "attr" and "attr2" are attribute names with
+     *     the values "val" and "val2", respectively.
+     *
+     *  3) A namespace declaration is a special attribute that is used to associate
+     *     a prefix with a URI (the namespace).  The meanings of element names and
+     *     attribute names that use that prefix are defined with respect to that
+     *     namespace.
+     *
+     *
+     */
+
+    /** The lookup table for error messages.   */
+    public Object[][] getContents() {
+        Object[][] contents = new Object[][] {
+            {   MsgKey.BAD_MSGKEY,
+                "\u8a0a\u606f\u9375 ''{0}'' \u4e0d\u5728\u8a0a\u606f\u985e\u5225 ''{1}'' \u4e2d" },
+
+            {   MsgKey.BAD_MSGFORMAT,
+                "\u8a0a\u606f\u985e\u5225 ''{1}'' \u4e2d\u7684\u8a0a\u606f ''{0}'' \u683c\u5f0f\u5316\u5931\u6557\u3002" },
+
+            {   MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
+                "Serializer \u985e\u5225 ''{0}'' \u4e0d\u5be6\u4f5c org.xml.sax.ContentHandler\u3002" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_FIND,
+                    "\u627e\u4e0d\u5230\u8cc7\u6e90 [ {0} ]\u3002\n {1}" },
+
+            {   MsgKey.ER_RESOURCE_COULD_NOT_LOAD,
+                    "\u7121\u6cd5\u8f09\u5165\u8cc7\u6e90 [ {0} ]\uff1a{1} \n {2} \t {3}" },
+
+            {   MsgKey.ER_BUFFER_SIZE_LESSTHAN_ZERO,
+                    "\u7de9\u885d\u5340\u5927\u5c0f <=0" },
+
+            {   MsgKey.ER_INVALID_UTF16_SURROGATE,
+                    "\u5075\u6e2c\u5230\u7121\u6548\u7684 UTF-16 \u4ee3\u7406\uff1a{0}?" },
+
+            {   MsgKey.ER_OIERROR,
+                "IO \u932f\u8aa4" },
+
+            {   MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,
+                "\u5728\u7522\u751f\u5b50\u9805\u7bc0\u9ede\u4e4b\u5f8c\uff0c\u6216\u5728\u7522\u751f\u5143\u7d20\u4e4b\u524d\uff0c\u4e0d\u53ef\u65b0\u589e\u5c6c\u6027 {0}\u3002\u5c6c\u6027\u6703\u88ab\u5ffd\u7565\u3002" },
+
+            /*
+             * Note to translators:  The stylesheet contained a reference to a
+             * namespace prefix that was undefined.  The value of the substitution
+             * text is the name of the prefix.
+             */
+            {   MsgKey.ER_NAMESPACE_PREFIX,
+                "\u5b57\u9996 ''{0}'' \u7684\u540d\u7a31\u7a7a\u9593\u5c1a\u672a\u5ba3\u544a\u3002" },
+
+            /*
+             * Note to translators:  This message is reported if the stylesheet
+             * being processed attempted to construct an XML document with an
+             * attribute in a place other than on an element.  The substitution text
+             * specifies the name of the attribute.
+             */
+            {   MsgKey.ER_STRAY_ATTRIBUTE,
+                "\u5c6c\u6027 ''{0}'' \u8d85\u51fa\u5143\u7d20\u5916\u3002" },
+
+            /*
+             * Note to translators:  As with the preceding message, a namespace
+             * declaration has the form of an attribute and is only permitted to
+             * appear on an element.  The substitution text {0} is the namespace
+             * prefix and {1} is the URI that was being used in the erroneous
+             * namespace declaration.
+             */
+            {   MsgKey.ER_STRAY_NAMESPACE,
+                "\u540d\u7a31\u7a7a\u9593\u5ba3\u544a ''{0}''=''{1}'' \u8d85\u51fa\u5143\u7d20\u5916\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
+                "\u7121\u6cd5\u8f09\u5165 ''{0}''\uff08\u6aa2\u67e5 CLASSPATH\uff09\uff0c\u76ee\u524d\u53ea\u4f7f\u7528\u9810\u8a2d\u503c" },
+
+            {   MsgKey.ER_ILLEGAL_CHARACTER,
+                "\u8a66\u5716\u8f38\u51fa\u4e0d\u662f\u4ee5\u6307\u5b9a\u7684\u8f38\u51fa\u7de8\u78bc {1} \u5448\u73fe\u7684\u6574\u6578\u503c {0} \u7684\u5b57\u5143\u3002" },
+
+            {   MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
+                "\u7121\u6cd5\u8f09\u5165\u8f38\u51fa\u65b9\u6cd5 ''{1}''\uff08\u6aa2\u67e5 CLASSPATH\uff09\u7684\u5167\u5bb9\u6a94 ''{0}''" },
+
+            {   MsgKey.ER_INVALID_PORT,
+                "\u7121\u6548\u7684\u57e0\u7de8\u865f" },
+
+            {   MsgKey.ER_PORT_WHEN_HOST_NULL,
+                "\u4e3b\u6a5f\u70ba\u7a7a\u503c\u6642\uff0c\u7121\u6cd5\u8a2d\u5b9a\u57e0" },
+
+            {   MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED,
+                "\u4e3b\u6a5f\u6c92\u6709\u5b8c\u6574\u7684\u4f4d\u5740" },
+
+            {   MsgKey.ER_SCHEME_NOT_CONFORMANT,
+                "\u7db1\u8981\u4e0d\u662f conformant\u3002" },
+
+            {   MsgKey.ER_SCHEME_FROM_NULL_STRING,
+                "\u7121\u6cd5\u5f9e\u7a7a\u5b57\u4e32\u8a2d\u5b9a\u7db1\u8981" },
+
+            {   MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE,
+                "\u8def\u5f91\u5305\u542b\u7121\u6548\u7684\u8df3\u812b\u5b57\u5143" },
+
+            {   MsgKey.ER_PATH_INVALID_CHAR,
+                "\u8def\u5f91\u5305\u542b\u7121\u6548\u7684\u5b57\u5143\uff1a{0}" },
+
+            {   MsgKey.ER_FRAG_INVALID_CHAR,
+                "\u7247\u6bb5\u5305\u542b\u7121\u6548\u7684\u5b57\u5143" },
+
+            {   MsgKey.ER_FRAG_WHEN_PATH_NULL,
+                "\u8def\u5f91\u70ba\u7a7a\u503c\u6642\uff0c\u7121\u6cd5\u8a2d\u5b9a\u7247\u6bb5" },
+
+            {   MsgKey.ER_FRAG_FOR_GENERIC_URI,
+                "\u53ea\u80fd\u5c0d\u901a\u7528\u7684 URI \u8a2d\u5b9a\u7247\u6bb5" },
+
+            {   MsgKey.ER_NO_SCHEME_IN_URI,
+                "\u5728 URI \u627e\u4e0d\u5230\u7db1\u8981" },
+
+            {   MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS,
+                "\u7121\u6cd5\u4ee5\u7a7a\u767d\u53c3\u6578\u8d77\u59cb\u8a2d\u5b9a URI" },
+
+            {   MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH,
+                "\u7247\u6bb5\u7121\u6cd5\u540c\u6642\u5728\u8def\u5f91\u548c\u7247\u6bb5\u4e2d\u6307\u5b9a" },
+
+            {   MsgKey.ER_NO_QUERY_STRING_IN_PATH,
+                "\u5728\u8def\u5f91\u53ca\u67e5\u8a62\u5b57\u4e32\u4e2d\u4e0d\u53ef\u6307\u5b9a\u67e5\u8a62\u5b57\u4e32" },
+
+            {   MsgKey.ER_NO_PORT_IF_NO_HOST,
+                "\u5982\u679c\u6c92\u6709\u6307\u5b9a\u4e3b\u6a5f\uff0c\u4e0d\u53ef\u6307\u5b9a\u57e0" },
+
+            {   MsgKey.ER_NO_USERINFO_IF_NO_HOST,
+                "\u5982\u679c\u6c92\u6709\u6307\u5b9a\u4e3b\u6a5f\uff0c\u4e0d\u53ef\u6307\u5b9a Userinfo" },
+            {   MsgKey.ER_XML_VERSION_NOT_SUPPORTED,
+                "\u8b66\u544a\uff1a\u8f38\u51fa\u6587\u4ef6\u7684\u7248\u672c\u8981\u6c42\u662f ''{0}''\u3002\u672a\u652f\u63f4\u9019\u500b\u7248\u672c\u7684 XML\u3002\u8f38\u51fa\u6587\u4ef6\u7684\u7248\u672c\u6703\u662f ''1.0''\u3002" },
+
+            {   MsgKey.ER_SCHEME_REQUIRED,
+                "\u7db1\u8981\u662f\u5fc5\u9700\u7684\uff01" },
+
+            /*
+             * Note to translators:  The words 'Properties' and
+             * 'SerializerFactory' in this message are Java class names
+             * and should not be translated.
+             */
+            {   MsgKey.ER_FACTORY_PROPERTY_MISSING,
+                "\u50b3\u905e\u5230 SerializerFactory \u7684 Properties \u7269\u4ef6\u6c92\u6709 ''{0}'' \u5167\u5bb9\u3002" },
+
+            {   MsgKey.ER_ENCODING_NOT_SUPPORTED,
+                "\u8b66\u544a\uff1aJava \u57f7\u884c\u6642\u671f\u4e0d\u652f\u63f4\u7de8\u78bc ''{0}''\u3002" },
+
+             {MsgKey.ER_FEATURE_NOT_FOUND,
+             "\u7121\u6cd5\u8fa8\u8b58\u53c3\u6578 ''{0}''\u3002"},
+
+             {MsgKey.ER_FEATURE_NOT_SUPPORTED,
+             "\u53ef\u8fa8\u8b58 ''{0}'' \u53c3\u6578\uff0c\u4f46\u6240\u8981\u6c42\u7684\u503c\u7121\u6cd5\u8a2d\u5b9a\u3002"},
+
+             {MsgKey.ER_STRING_TOO_LONG,
+             "\u7d50\u679c\u5b57\u4e32\u904e\u9577\uff0c\u7121\u6cd5\u7f6e\u5165 DOMString: ''{0}'' \u4e2d\u3002"},
+
+             {MsgKey.ER_TYPE_MISMATCH_ERR,
+             "\u9019\u500b\u53c3\u6578\u540d\u7a31\u7684\u503c\u985e\u578b\u8207\u671f\u671b\u503c\u985e\u578b\u4e0d\u76f8\u5bb9\u3002"},
+
+             {MsgKey.ER_NO_OUTPUT_SPECIFIED,
+             "\u8cc7\u6599\u8981\u5beb\u5165\u7684\u8f38\u51fa\u76ee\u7684\u5730\u70ba\u7a7a\u503c\u3002"},
+
+             {MsgKey.ER_UNSUPPORTED_ENCODING,
+             "\u767c\u73fe\u4e0d\u652f\u63f4\u7684\u7de8\u78bc\u3002"},
+
+             {MsgKey.ER_UNABLE_TO_SERIALIZE_NODE,
+             "\u7bc0\u9ede\u7121\u6cd5\u5e8f\u5217\u5316\u3002"},
+
+             {MsgKey.ER_CDATA_SECTIONS_SPLIT,
+             "CDATA \u5340\u6bb5\u5305\u542b\u4e00\u6216\u591a\u500b\u7d42\u6b62\u6a19\u8a18 ']]>'\u3002"},
+
+             {MsgKey.ER_WARNING_WF_NOT_CHECKED,
+                 "\u7121\u6cd5\u5efa\u7acb\u300c\u5f62\u5f0f\u5b8c\u6574\u300d\u6aa2\u67e5\u7a0b\u5f0f\u7684\u5be6\u4f8b\u3002Well-formed \u53c3\u6578\u96d6\u8a2d\u70ba true\uff0c\u4f46\u7121\u6cd5\u57f7\u884c\u5f62\u5f0f\u5b8c\u6574\u6aa2\u67e5\u3002"
+             },
+
+             {MsgKey.ER_WF_INVALID_CHARACTER,
+                 "\u7bc0\u9ede ''{0}'' \u5305\u542b\u7121\u6548\u7684 XML \u5b57\u5143\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
+                 "\u5728\u8a3b\u89e3\u4e2d\u767c\u73fe\u7121\u6548\u7684 XML \u5b57\u5143 (Unicode: 0x{0})\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
+                 "\u5728\u8655\u7406\u7a0b\u5e8f instructiondata \u4e2d\u767c\u73fe\u7121\u6548\u7684 XML \u5b57\u5143 (Unicode: 0x{0})\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
+                 "\u5728 CDATASection \u7684\u5167\u5bb9\u4e2d\u767c\u73fe\u7121\u6548\u7684 XML \u5b57\u5143 (Unicode: 0x{0})\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
+                 "\u5728\u7bc0\u9ede\u7684\u5b57\u5143\u8cc7\u6599\u5167\u5bb9\u4e2d\u767c\u73fe\u7121\u6548\u7684 XML \u5b57\u5143 (Unicode: 0x{0})\u3002"
+             },
+
+             { MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
+                 "\u5728\u540d\u70ba ''{1}'' \u7684 ''{0}'' \u4e2d\u767c\u73fe\u7121\u6548\u7684 XML \u5b57\u5143\u3002"
+             },
+
+             { MsgKey.ER_WF_DASH_IN_COMMENT,
+                 "\u8a3b\u89e3\u4e2d\u4e0d\u5141\u8a31\u4f7f\u7528\u5b57\u4e32 \"--\"\u3002"
+             },
+
+             {MsgKey.ER_WF_LT_IN_ATTVAL,
+                 "\u8207\u5143\u7d20\u985e\u578b \"{0}\" \u76f8\u95dc\u806f\u7684\u5c6c\u6027 \"{1}\" \u503c\u4e0d\u53ef\u5305\u542b ''<'' \u5b57\u5143\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
+                 "\u4e0d\u5141\u8a31\u4f7f\u7528\u672a\u5256\u6790\u7684\u5be6\u9ad4\u53c3\u7167 \"&{0};\"\u3002"
+             },
+
+             {MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
+                 "\u5c6c\u6027\u503c\u4e2d\u4e0d\u5141\u8a31\u4f7f\u7528\u5916\u90e8\u5be6\u9ad4\u53c3\u7167 \"&{0};\"\u3002"
+             },
+
+             {MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
+                 "\u5b57\u9996 \"{0}\" \u7121\u6cd5\u9023\u7d50\u5230\u540d\u7a31\u7a7a\u9593 \"{1}\"\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
+                 "\u5143\u7d20 \"{0}\" \u7684\u672c\u7aef\u540d\u7a31\u662f\u7a7a\u503c\u3002"
+             },
+
+             {MsgKey.ER_NULL_LOCAL_ATTR_NAME,
+                 "\u5c6c\u6027 \"{0}\" \u7684\u672c\u7aef\u540d\u7a31\u662f\u7a7a\u503c\u3002"
+             },
+
+             { MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5be6\u9ad4\u7bc0\u9ede \"{0}\" \u7684\u53d6\u4ee3\u6587\u5b57\u5305\u542b\u9644\u6709\u5df2\u5207\u65b7\u9023\u7d50\u5b57\u9996 \"{2}\" \u7684\u5143\u7d20\u7bc0\u9ede \"{1}\"\u3002"
+             },
+
+             { MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
+                 "\u5be6\u9ad4\u7bc0\u9ede \"{0}\" \u7684\u53d6\u4ee3\u6587\u5b57\u5305\u542b\u9644\u6709\u5df2\u5207\u65b7\u9023\u7d50\u5b57\u9996 \"{2}\" \u7684\u5c6c\u6027\u7bc0\u9ede \"{1}\"\u3002"
+             },
+
+        };
+
+        return contents;
+    }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/StringToIntTable.java b/src/main/java/org/apache/xml/serializer/utils/StringToIntTable.java
new file mode 100644
index 0000000..13c753b
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/StringToIntTable.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StringToIntTable.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+/**
+ * A very simple lookup table that stores a list of strings, the even
+ * number strings being keys, and the odd number strings being values.
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ * 
+ * This class is not a public API, it is only public so it can be used
+ * in org.apache.xml.serializer.
+ *  
+ * @xsl.usage internal
+ */
+public final class StringToIntTable
+{
+
+  public static final int INVALID_KEY = -10000;
+  
+  /** Block size to allocate          */
+  private int m_blocksize;
+
+  /** Array of strings this table points to. Associated with ints
+   * in m_values         */
+  private String m_map[];
+
+  /** Array of ints this table points. Associated with strings from
+   * m_map.         */
+  private int m_values[];
+
+  /** Number of ints in the table          */
+  private int m_firstFree = 0;
+
+  /** Size of this table         */
+  private int m_mapSize;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public StringToIntTable()
+  {
+
+    m_blocksize = 8;
+    m_mapSize = m_blocksize;
+    m_map = new String[m_blocksize];
+    m_values = new int[m_blocksize];
+  }
+
+  /**
+   * Construct a StringToIntTable, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public StringToIntTable(int blocksize)
+  {
+
+    m_blocksize = blocksize;
+    m_mapSize = blocksize;
+    m_map = new String[blocksize];
+    m_values = new int[m_blocksize];
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return the length of the list 
+   */
+  public final int getLength()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Append a string onto the vector.
+   *
+   * @param key String to append
+   * @param value The int value of the string
+   */
+  public final void put(String key, int value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      String newMap[] = new String[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+
+      int newValues[] = new int[m_mapSize];
+
+      System.arraycopy(m_values, 0, newValues, 0, m_firstFree + 1);
+
+      m_values = newValues;
+    }
+
+    m_map[m_firstFree] = key;
+    m_values[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param key String to look for
+   *
+   * @return The String's int value
+   * 
+   */
+  public final int get(String key)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equals(key))
+        return m_values[i];
+    }
+
+    return INVALID_KEY;
+  }
+
+  /**
+   * Tell if the table contains the given string. Ignore case.
+   *
+   * @param key String to look for
+   *
+   * @return The string's int value
+   */
+  public final int getIgnoreCase(String key)
+  {
+
+    if (null == key)
+        return INVALID_KEY;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equalsIgnoreCase(key))
+        return m_values[i];
+    }
+
+    return INVALID_KEY;
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param key String to look for
+   *
+   * @return True if the string is in the table
+   */
+  public final boolean contains(String key)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equals(key))
+        return true;
+    }
+
+    return false;
+  }
+  
+  /**
+   * Return array of keys in the table.
+   * 
+   * @return Array of strings
+   */
+  public final String[] keys()
+  {
+    String [] keysArr = new String[m_firstFree];
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      keysArr[i] = m_map[i];
+    }
+
+    return keysArr;
+  }  
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/SystemIDResolver.java b/src/main/java/org/apache/xml/serializer/utils/SystemIDResolver.java
new file mode 100644
index 0000000..f10a300
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/SystemIDResolver.java
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SystemIDResolver.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import java.io.File;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.serializer.utils.URI.MalformedURIException;
+
+/**
+ * This class is used to resolve relative URIs and SystemID 
+ * strings into absolute URIs.
+ *
+ * <p>This is a generic utility for resolving URIs, other than the 
+ * fact that it's declared to throw TransformerException.  Please 
+ * see code comments for details on how resolution is performed.</p>
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ *
+ * This class is not a public API, it is only public because it is
+ * used in org.apache.xml.serializer. 
+ * 
+ * @xsl.usage internal
+ */
+public final class SystemIDResolver
+{
+
+  /**
+   * Get an absolute URI from a given relative URI (local path). 
+   * 
+   * <p>The relative URI is a local filesystem path. The path can be
+   * absolute or relative. If it is a relative path, it is resolved relative 
+   * to the system property "user.dir" if it is available; if not (i.e. in an 
+   * Applet perhaps which throws SecurityException) then we just return the
+   * relative path. The space and backslash characters are also replaced to
+   * generate a good absolute URI.</p>
+   *
+   * @param localPath The relative URI to resolve
+   *
+   * @return Resolved absolute URI
+   */
+  public static String getAbsoluteURIFromRelative(String localPath)
+  {
+    if (localPath == null || localPath.length() == 0)
+      return "";
+      
+    // If the local path is a relative path, then it is resolved against
+    // the "user.dir" system property.
+    String absolutePath = localPath;
+    if (!isAbsolutePath(localPath))
+    {
+      try 
+      {
+        absolutePath = getAbsolutePathFromRelativePath(localPath);
+      }
+      // user.dir not accessible from applet
+      catch (SecurityException se) 
+      {
+        return "file:" + localPath;
+      }
+    }
+
+    String urlString;
+    if (null != absolutePath)
+    {
+      if (absolutePath.startsWith(File.separator))
+        urlString = "file://" + absolutePath;
+      else
+        urlString = "file:///" + absolutePath;        
+    }
+    else
+      urlString = "file:" + localPath;
+    
+    return replaceChars(urlString);
+  }
+  
+  /**
+   * Return an absolute path from a relative path.
+   *
+   * @param relativePath A relative path
+   * @return The absolute path
+   */
+  private static String getAbsolutePathFromRelativePath(String relativePath)
+  {
+    return new File(relativePath).getAbsolutePath();
+  }
+  
+  /**
+   * Return true if the systemId denotes an absolute URI .
+   *
+   * @param systemId The systemId string
+   * @return true if the systemId is an an absolute URI
+   */
+  public static boolean isAbsoluteURI(String systemId)
+  {
+     /** http://www.ietf.org/rfc/rfc2396.txt
+      *   Authors should be aware that a path segment which contains a colon
+      * character cannot be used as the first segment of a relative URI path
+      * (e.g., "this:that"), because it would be mistaken for a scheme name.
+     **/
+     /** 
+      * %REVIEW% Can we assume here that systemId is a valid URI?
+      * It looks like we cannot ( See discussion of this common problem in 
+      * Bugzilla Bug 22777 ). 
+     **/
+     //"fix" for Bugzilla Bug 22777
+    if(isWindowsAbsolutePath(systemId)){
+        return false;
+     }
+    
+    final int fragmentIndex = systemId.indexOf('#');
+    final int queryIndex = systemId.indexOf('?');
+    final int slashIndex = systemId.indexOf('/');
+    final int colonIndex = systemId.indexOf(':');
+    
+    //finding substring  before '#', '?', and '/' 
+    int index = systemId.length() -1;
+    if(fragmentIndex > 0) 
+        index = fragmentIndex;
+    if((queryIndex > 0) && (queryIndex <index)) 
+        index = queryIndex;
+    if((slashIndex > 0) && (slashIndex <index))
+        index = slashIndex; 
+    // return true if there is ':' before '#', '?', and '/'
+    return ((colonIndex >0) && (colonIndex<index));
+    
+  }
+  
+  /**
+   * Return true if the local path is an absolute path.
+   *
+   * @param systemId The path string
+   * @return true if the path is absolute
+   */
+  public static boolean isAbsolutePath(String systemId)
+  {
+    if(systemId == null)
+        return false;
+    final File file = new File(systemId);
+    return file.isAbsolute();
+    
+  }
+  
+   /**
+   * Return true if the local path is a Windows absolute path.
+   *
+   * @param systemId The path string
+   * @return true if the path is a Windows absolute path
+   */
+    private static boolean isWindowsAbsolutePath(String systemId)
+  {
+    if(!isAbsolutePath(systemId))
+      return false;
+    // On Windows, an absolute path starts with "[drive_letter]:\".
+    if (systemId.length() > 2 
+        && systemId.charAt(1) == ':'
+        && Character.isLetter(systemId.charAt(0))
+        && (systemId.charAt(2) == '\\' || systemId.charAt(2) == '/'))
+      return true;
+    else
+      return false;
+  }
+  
+  /**
+   * Replace spaces with "%20" and backslashes with forward slashes in 
+   * the input string to generate a well-formed URI string.
+   *
+   * @param str The input string
+   * @return The string after conversion
+   */
+  private static String replaceChars(String str)
+  {
+    StringBuffer buf = new StringBuffer(str);
+    int length = buf.length();
+    for (int i = 0; i < length; i++)
+    {
+      char currentChar = buf.charAt(i);
+      // Replace space with "%20"
+      if (currentChar == ' ')
+      {
+        buf.setCharAt(i, '%');
+        buf.insert(i+1, "20");
+        length = length + 2;
+        i = i + 2;
+      }
+      // Replace backslash with forward slash
+      else if (currentChar == '\\')
+      {
+        buf.setCharAt(i, '/');
+      }
+    }
+    
+    return buf.toString();
+  }
+  
+  /**
+   * Take a SystemID string and try to turn it into a good absolute URI.
+   *
+   * @param systemId A URI string, which may be absolute or relative.
+   *
+   * @return The resolved absolute URI
+   */
+  public static String getAbsoluteURI(String systemId)
+  {
+    String absoluteURI = systemId;
+    if (isAbsoluteURI(systemId))
+    {
+      // Only process the systemId if it starts with "file:".
+      if (systemId.startsWith("file:"))
+      {
+        String str = systemId.substring(5);
+        
+        // Resolve the absolute path if the systemId starts with "file:///"
+        // or "file:/". Don't do anything if it only starts with "file://".
+        if (str != null && str.startsWith("/"))
+        {
+          if (str.startsWith("///") || !str.startsWith("//"))
+          {
+            // A Windows path containing a drive letter can be relative.
+            // A Unix path starting with "file:/" is always absolute.
+            int secondColonIndex = systemId.indexOf(':', 5);
+            if (secondColonIndex > 0)
+            {
+              String localPath = systemId.substring(secondColonIndex-1);
+              try {
+                if (!isAbsolutePath(localPath))
+                  absoluteURI = systemId.substring(0, secondColonIndex-1) + 
+                                getAbsolutePathFromRelativePath(localPath);
+              }
+              catch (SecurityException se) {
+                return systemId;
+              }
+            }
+          }          
+        }
+        else
+        {
+          return getAbsoluteURIFromRelative(systemId.substring(5));
+        }
+                
+        return replaceChars(absoluteURI);
+      }
+      else
+        return systemId;
+    }
+    else
+      return getAbsoluteURIFromRelative(systemId);
+    
+  }
+
+
+  /**
+   * Take a SystemID string and try to turn it into a good absolute URI.
+   *
+   * @param urlString SystemID string
+   * @param base The URI string used as the base for resolving the systemID
+   *
+   * @return The resolved absolute URI
+   * @throws TransformerException thrown if the string can't be turned into a URI.
+   */
+  public static String getAbsoluteURI(String urlString, String base)
+          throws TransformerException
+  {    
+    if (base == null)
+      return getAbsoluteURI(urlString);
+    
+    String absoluteBase = getAbsoluteURI(base);
+    URI uri = null;
+    try 
+    {
+      URI baseURI = new URI(absoluteBase);
+      uri = new URI(baseURI, urlString);
+    }
+    catch (MalformedURIException mue)
+    {
+      throw new TransformerException(mue);
+    }
+    
+    return replaceChars(uri.toString());
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/URI.java b/src/main/java/org/apache/xml/serializer/utils/URI.java
new file mode 100644
index 0000000..b77518b
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/URI.java
@@ -0,0 +1,1653 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: URI.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+
+/**
+ * A class to represent a Uniform Resource Identifier (URI). This class
+ * is designed to handle the parsing of URIs and provide access to
+ * the various components (scheme, host, port, userinfo, path, query
+ * string and fragment) that may constitute a URI.
+ * <p>
+ * Parsing of a URI specification is done according to the URI
+ * syntax described in RFC 2396
+ * <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists
+ * of a scheme, followed by a colon (':'), followed by a scheme-specific
+ * part. For URIs that follow the "generic URI" syntax, the scheme-
+ * specific part begins with two slashes ("//") and may be followed
+ * by an authority segment (comprised of user information, host, and
+ * port), path segment, query segment and fragment. Note that RFC 2396
+ * no longer specifies the use of the parameters segment and excludes
+ * the "user:password" syntax as part of the authority segment. If
+ * "user:password" appears in a URI, the entire user/password string
+ * is stored as userinfo.
+ * <p>
+ * For URIs that do not follow the "generic URI" syntax (e.g. mailto),
+ * the entire scheme-specific part is treated as the "path" portion
+ * of the URI.
+ * <p>
+ * Note that, unlike the java.net.URL class, this class does not provide
+ * any built-in network access functionality nor does it provide any
+ * scheme-specific functionality (for example, it does not know a
+ * default port for a specific scheme). Rather, it only knows the
+ * grammar and basic set of operations that can be applied to a URI.
+ *
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ * 
+ * A minor change from the original is that this class no longer implements
+ * Serializable, and the serialVersionUID magic field is dropped, and
+ * the class is no longer "public".
+ *  
+ * @xsl.usage internal
+ */
+final class URI
+{
+  /**
+   * MalformedURIExceptions are thrown in the process of building a URI
+   * or setting fields on a URI when an operation would result in an
+   * invalid URI specification.
+   *
+   */
+  public static class MalformedURIException extends IOException
+  {
+
+    /**
+     * Constructs a <code>MalformedURIException</code> with no specified
+     * detail message.
+     */
+    public MalformedURIException()
+    {
+      super();
+    }
+
+    /**
+     * Constructs a <code>MalformedURIException</code> with the
+     * specified detail message.
+     *
+     * @param p_msg the detail message.
+     */
+    public MalformedURIException(String p_msg)
+    {
+      super(p_msg);
+    }
+  }
+
+  /** reserved characters */
+  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";
+
+  /**
+   * URI punctuation mark characters - these, combined with
+   *   alphanumerics, constitute the "unreserved" characters 
+   */
+  private static final String MARK_CHARACTERS = "-_.!~*'() ";
+
+  /** scheme can be composed of alphanumerics and these characters */
+  private static final String SCHEME_CHARACTERS = "+-.";
+
+  /**
+   * userinfo can be composed of unreserved, escaped and these
+   *   characters 
+   */
+  private static final String USERINFO_CHARACTERS = ";:&=+$,";
+
+  /** Stores the scheme (usually the protocol) for this URI.
+   *  @serial */
+  private String m_scheme = null;
+
+  /** If specified, stores the userinfo for this URI; otherwise null.
+   *  @serial */
+  private String m_userinfo = null;
+
+  /** If specified, stores the host for this URI; otherwise null.
+   *  @serial */
+  private String m_host = null;
+
+  /** If specified, stores the port for this URI; otherwise -1.
+   *  @serial */
+  private int m_port = -1;
+
+  /** If specified, stores the path for this URI; otherwise null.
+   *  @serial */
+  private String m_path = null;
+
+  /**
+   * If specified, stores the query string for this URI; otherwise
+   *   null. 
+   * @serial 
+   */
+  private String m_queryString = null;
+
+  /** If specified, stores the fragment for this URI; otherwise null.
+   *  @serial */
+  private String m_fragment = null;
+
+  /** Indicate whether in DEBUG mode          */
+  private static boolean DEBUG = false;
+
+  /**
+   * Construct a new and uninitialized URI.
+   */
+  public URI(){}
+
+  /**
+   * Construct a new URI from another URI. All fields for this URI are
+   * set equal to the fields of the URI passed in.
+   *
+   * @param p_other the URI to copy (cannot be null)
+   */
+  public URI(URI p_other)
+  {
+    initialize(p_other);
+  }
+
+  /**
+   * Construct a new URI from a URI specification string. If the
+   * specification follows the "generic URI" syntax, (two slashes
+   * following the first colon), the specification will be parsed
+   * accordingly - setting the scheme, userinfo, host,port, path, query
+   * string and fragment fields as necessary. If the specification does
+   * not follow the "generic URI" syntax, the specification is parsed
+   * into a scheme and scheme-specific part (stored as the path) only.
+   *
+   * @param p_uriSpec the URI specification string (cannot be null or
+   *                  empty)
+   *
+   * @throws MalformedURIException if p_uriSpec violates any syntax
+   *                                   rules
+   */
+  public URI(String p_uriSpec) throws MalformedURIException
+  {
+    this((URI) null, p_uriSpec);
+  }
+
+  /**
+   * Construct a new URI from a base URI and a URI specification string.
+   * The URI specification string may be a relative URI.
+   *
+   * @param p_base the base URI (cannot be null if p_uriSpec is null or
+   *               empty)
+   * @param p_uriSpec the URI specification string (cannot be null or
+   *                  empty if p_base is null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates any syntax
+   *                                  rules
+   */
+  public URI(URI p_base, String p_uriSpec) throws MalformedURIException
+  {
+    initialize(p_base, p_uriSpec);
+  }
+
+  /**
+   * Construct a new URI that does not follow the generic URI syntax.
+   * Only the scheme and scheme-specific part (stored as the path) are
+   * initialized.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_schemeSpecificPart the scheme-specific part (cannot be
+   *                             null or empty)
+   *
+   * @throws MalformedURIException if p_scheme violates any
+   *                                  syntax rules
+   */
+  public URI(String p_scheme, String p_schemeSpecificPart)
+          throws MalformedURIException
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      throw new MalformedURIException(
+        "Cannot construct URI with null/empty scheme!");
+    }
+
+    if (p_schemeSpecificPart == null
+            || p_schemeSpecificPart.trim().length() == 0)
+    {
+      throw new MalformedURIException(
+        "Cannot construct URI with null/empty scheme-specific part!");
+    }
+
+    setScheme(p_scheme);
+    setPath(p_schemeSpecificPart);
+  }
+
+  /**
+   * Construct a new URI that follows the generic URI syntax from its
+   * component parts. Each component is validated for syntax and some
+   * basic semantic checks are performed as well.  See the individual
+   * setter methods for specifics.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_host the hostname or IPv4 address for the URI
+   * @param p_path the URI path - if the path contains '?' or '#',
+   *               then the query string and/or fragment will be
+   *               set from the path; however, if the query and
+   *               fragment are specified both in the path and as
+   *               separate parameters, an exception is thrown
+   * @param p_queryString the URI query string (cannot be specified
+   *                      if path is null)
+   * @param p_fragment the URI fragment (cannot be specified if path
+   *                   is null)
+   *
+   * @throws MalformedURIException if any of the parameters violates
+   *                                  syntax rules or semantic rules
+   */
+  public URI(String p_scheme, String p_host, String p_path, String p_queryString, String p_fragment)
+          throws MalformedURIException
+  {
+    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
+  }
+
+  /**
+   * Construct a new URI that follows the generic URI syntax from its
+   * component parts. Each component is validated for syntax and some
+   * basic semantic checks are performed as well.  See the individual
+   * setter methods for specifics.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_userinfo the URI userinfo (cannot be specified if host
+   *                   is null)
+   * @param p_host the hostname or IPv4 address for the URI
+   * @param p_port the URI port (may be -1 for "unspecified"; cannot
+   *               be specified if host is null)
+   * @param p_path the URI path - if the path contains '?' or '#',
+   *               then the query string and/or fragment will be
+   *               set from the path; however, if the query and
+   *               fragment are specified both in the path and as
+   *               separate parameters, an exception is thrown
+   * @param p_queryString the URI query string (cannot be specified
+   *                      if path is null)
+   * @param p_fragment the URI fragment (cannot be specified if path
+   *                   is null)
+   *
+   * @throws MalformedURIException if any of the parameters violates
+   *                                  syntax rules or semantic rules
+   */
+  public URI(String p_scheme, String p_userinfo, String p_host, int p_port, String p_path, String p_queryString, String p_fragment)
+          throws MalformedURIException
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_SCHEME_REQUIRED, null)); //"Scheme is required!");
+    }
+
+    if (p_host == null)
+    {
+      if (p_userinfo != null)
+      {
+        throw new MalformedURIException(
+          Utils.messages.createMessage(MsgKey.ER_NO_USERINFO_IF_NO_HOST, null)); //"Userinfo may not be specified if host is not specified!");
+      }
+
+      if (p_port != -1)
+      {
+        throw new MalformedURIException(
+          Utils.messages.createMessage(MsgKey.ER_NO_PORT_IF_NO_HOST, null)); //"Port may not be specified if host is not specified!");
+      }
+    }
+
+    if (p_path != null)
+    {
+      if (p_path.indexOf('?') != -1 && p_queryString != null)
+      {
+        throw new MalformedURIException(
+          Utils.messages.createMessage(MsgKey.ER_NO_QUERY_STRING_IN_PATH, null)); //"Query string cannot be specified in path and query string!");
+      }
+
+      if (p_path.indexOf('#') != -1 && p_fragment != null)
+      {
+        throw new MalformedURIException(
+          Utils.messages.createMessage(MsgKey.ER_NO_FRAGMENT_STRING_IN_PATH, null)); //"Fragment cannot be specified in both the path and fragment!");
+      }
+    }
+
+    setScheme(p_scheme);
+    setHost(p_host);
+    setPort(p_port);
+    setUserinfo(p_userinfo);
+    setPath(p_path);
+    setQueryString(p_queryString);
+    setFragment(p_fragment);
+  }
+
+  /**
+   * Initialize all fields of this URI from another URI.
+   *
+   * @param p_other the URI to copy (cannot be null)
+   */
+  private void initialize(URI p_other)
+  {
+
+    m_scheme = p_other.getScheme();
+    m_userinfo = p_other.getUserinfo();
+    m_host = p_other.getHost();
+    m_port = p_other.getPort();
+    m_path = p_other.getPath();
+    m_queryString = p_other.getQueryString();
+    m_fragment = p_other.getFragment();
+  }
+
+  /**
+   * Initializes this URI from a base URI and a URI specification string.
+   * See RFC 2396 Section 4 and Appendix B for specifications on parsing
+   * the URI and Section 5 for specifications on resolving relative URIs
+   * and relative paths.
+   *
+   * @param p_base the base URI (may be null if p_uriSpec is an absolute
+   *               URI)
+   * @param p_uriSpec the URI spec string which may be an absolute or
+   *                  relative URI (can only be null/empty if p_base
+   *                  is not null)
+   *
+   * @throws MalformedURIException if p_base is null and p_uriSpec
+   *                                  is not an absolute URI or if
+   *                                  p_uriSpec violates syntax rules
+   */
+  private void initialize(URI p_base, String p_uriSpec)
+          throws MalformedURIException
+  {
+
+    if (p_base == null
+            && (p_uriSpec == null || p_uriSpec.trim().length() == 0))
+    {
+      throw new MalformedURIException(
+        Utils.messages.createMessage(MsgKey.ER_CANNOT_INIT_URI_EMPTY_PARMS, null)); //"Cannot initialize URI with empty parameters.");
+    }
+
+    // just make a copy of the base if spec is empty
+    if (p_uriSpec == null || p_uriSpec.trim().length() == 0)
+    {
+      initialize(p_base);
+
+      return;
+    }
+
+    String uriSpec = p_uriSpec.trim();
+    int uriSpecLen = uriSpec.length();
+    int index = 0;
+
+    // check for scheme
+    int colonIndex = uriSpec.indexOf(':');
+    if (colonIndex < 0)
+    {
+      if (p_base == null)
+      {
+        throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_NO_SCHEME_IN_URI, new Object[]{uriSpec})); //"No scheme found in URI: "+uriSpec);
+      }
+    }
+    else
+    {
+      initializeScheme(uriSpec);
+      uriSpec = uriSpec.substring(colonIndex+1);
+      uriSpecLen = uriSpec.length();
+    }
+
+    // two slashes means generic URI syntax, so we get the authority
+    if (uriSpec.startsWith("//"))
+    {
+      index += 2;
+
+      int startPos = index;
+
+      // get authority - everything up to path, query or fragment
+      char testChar = '\0';
+
+      while (index < uriSpecLen)
+      {
+        testChar = uriSpec.charAt(index);
+
+        if (testChar == '/' || testChar == '?' || testChar == '#')
+        {
+          break;
+        }
+
+        index++;
+      }
+
+      // if we found authority, parse it out, otherwise we set the
+      // host to empty string
+      if (index > startPos)
+      {
+        initializeAuthority(uriSpec.substring(startPos, index));
+      }
+      else
+      {
+        m_host = "";
+      }
+    }
+
+    initializePath(uriSpec.substring(index));
+
+    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
+    // In some cases, it might make more sense to throw an exception
+    // (when scheme is specified is the string spec and the base URI
+    // is also specified, for example), but we're just following the
+    // RFC specifications 
+    if (p_base != null)
+    {
+
+      // check to see if this is the current doc - RFC 2396 5.2 #2
+      // note that this is slightly different from the RFC spec in that
+      // we don't include the check for query string being null
+      // - this handles cases where the urispec is just a query
+      // string or a fragment (e.g. "?y" or "#s") - 
+      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
+      // identified this as a bug in the RFC
+      if (m_path.length() == 0 && m_scheme == null && m_host == null)
+      {
+        m_scheme = p_base.getScheme();
+        m_userinfo = p_base.getUserinfo();
+        m_host = p_base.getHost();
+        m_port = p_base.getPort();
+        m_path = p_base.getPath();
+
+        if (m_queryString == null)
+        {
+          m_queryString = p_base.getQueryString();
+        }
+
+        return;
+      }
+
+      // check for scheme - RFC 2396 5.2 #3
+      // if we found a scheme, it means absolute URI, so we're done
+      if (m_scheme == null)
+      {
+        m_scheme = p_base.getScheme();
+      }
+
+      // check for authority - RFC 2396 5.2 #4
+      // if we found a host, then we've got a network path, so we're done
+      if (m_host == null)
+      {
+        m_userinfo = p_base.getUserinfo();
+        m_host = p_base.getHost();
+        m_port = p_base.getPort();
+      }
+      else
+      {
+        return;
+      }
+
+      // check for absolute path - RFC 2396 5.2 #5
+      if (m_path.length() > 0 && m_path.startsWith("/"))
+      {
+        return;
+      }
+
+      // if we get to this point, we need to resolve relative path
+      // RFC 2396 5.2 #6
+      String path = new String();
+      String basePath = p_base.getPath();
+
+      // 6a - get all but the last segment of the base URI path
+      if (basePath != null)
+      {
+        int lastSlash = basePath.lastIndexOf('/');
+
+        if (lastSlash != -1)
+        {
+          path = basePath.substring(0, lastSlash + 1);
+        }
+      }
+
+      // 6b - append the relative URI path
+      path = path.concat(m_path);
+
+      // 6c - remove all "./" where "." is a complete path segment
+      index = -1;
+
+      while ((index = path.indexOf("/./")) != -1)
+      {
+        path = path.substring(0, index + 1).concat(path.substring(index + 3));
+      }
+
+      // 6d - remove "." if path ends with "." as a complete path segment
+      if (path.endsWith("/."))
+      {
+        path = path.substring(0, path.length() - 1);
+      }
+
+      // 6e - remove all "<segment>/../" where "<segment>" is a complete 
+      // path segment not equal to ".."
+      index = -1;
+
+      int segIndex = -1;
+      String tempString = null;
+
+      while ((index = path.indexOf("/../")) > 0)
+      {
+        tempString = path.substring(0, path.indexOf("/../"));
+        segIndex = tempString.lastIndexOf('/');
+
+        if (segIndex != -1)
+        {
+          if (!tempString.substring(segIndex++).equals(".."))
+          {
+            path = path.substring(0, segIndex).concat(path.substring(index
+                    + 4));
+          }
+        }
+      }
+
+      // 6f - remove ending "<segment>/.." where "<segment>" is a 
+      // complete path segment
+      if (path.endsWith("/.."))
+      {
+        tempString = path.substring(0, path.length() - 3);
+        segIndex = tempString.lastIndexOf('/');
+
+        if (segIndex != -1)
+        {
+          path = path.substring(0, segIndex + 1);
+        }
+      }
+
+      m_path = path;
+    }
+  }
+
+  /**
+   * Initialize the scheme for this URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if URI does not have a conformant
+   *                                  scheme
+   */
+  private void initializeScheme(String p_uriSpec) throws MalformedURIException
+  {
+
+    int uriSpecLen = p_uriSpec.length();
+    int index = 0;
+    String scheme = null;
+    char testChar = '\0';
+
+    while (index < uriSpecLen)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == ':' || testChar == '/' || testChar == '?'
+              || testChar == '#')
+      {
+        break;
+      }
+
+      index++;
+    }
+
+    scheme = p_uriSpec.substring(0, index);
+
+    if (scheme.length() == 0)
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_NO_SCHEME_INURI, null)); //"No scheme found in URI.");
+    }
+    else
+    {
+      setScheme(scheme);
+    }
+  }
+
+  /**
+   * Initialize the authority (userinfo, host and port) for this
+   * URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates syntax rules
+   */
+  private void initializeAuthority(String p_uriSpec)
+          throws MalformedURIException
+  {
+
+    int index = 0;
+    int start = 0;
+    int end = p_uriSpec.length();
+    char testChar = '\0';
+    String userinfo = null;
+
+    // userinfo is everything up @
+    if (p_uriSpec.indexOf('@', start) != -1)
+    {
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '@')
+        {
+          break;
+        }
+
+        index++;
+      }
+
+      userinfo = p_uriSpec.substring(start, index);
+
+      index++;
+    }
+
+    // host is everything up to ':'
+    String host = null;
+
+    start = index;
+
+    while (index < end)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == ':')
+      {
+        break;
+      }
+
+      index++;
+    }
+
+    host = p_uriSpec.substring(start, index);
+
+    int port = -1;
+
+    if (host.length() > 0)
+    {
+
+      // port
+      if (testChar == ':')
+      {
+        index++;
+
+        start = index;
+
+        while (index < end)
+        {
+          index++;
+        }
+
+        String portStr = p_uriSpec.substring(start, index);
+
+        if (portStr.length() > 0)
+        {
+          for (int i = 0; i < portStr.length(); i++)
+          {
+            if (!isDigit(portStr.charAt(i)))
+            {
+              throw new MalformedURIException(
+                portStr + " is invalid. Port should only contain digits!");
+            }
+          }
+
+          try
+          {
+            port = Integer.parseInt(portStr);
+          }
+          catch (NumberFormatException nfe)
+          {
+
+            // can't happen
+          }
+        }
+      }
+    }
+
+    setHost(host);
+    setPort(port);
+    setUserinfo(userinfo);
+  }
+
+  /**
+   * Initialize the path for this URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates syntax rules
+   */
+  private void initializePath(String p_uriSpec) throws MalformedURIException
+  {
+
+    if (p_uriSpec == null)
+    {
+      throw new MalformedURIException(
+        "Cannot initialize path from null string!");
+    }
+
+    int index = 0;
+    int start = 0;
+    int end = p_uriSpec.length();
+    char testChar = '\0';
+
+    // path - everything up to query string or fragment
+    while (index < end)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == '?' || testChar == '#')
+      {
+        break;
+      }
+
+      // check for valid escape sequence
+      if (testChar == '%')
+      {
+        if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                ||!isHex(p_uriSpec.charAt(index + 2)))
+        {
+          throw new MalformedURIException(
+            Utils.messages.createMessage(MsgKey.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE, null)); //"Path contains invalid escape sequence!");
+        }
+      }
+      else if (!isReservedCharacter(testChar)
+               &&!isUnreservedCharacter(testChar))
+      {
+        if ('\\' != testChar)
+          throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_PATH_INVALID_CHAR, new Object[]{String.valueOf(testChar)})); //"Path contains invalid character: "
+                                          //+ testChar);
+      }
+
+      index++;
+    }
+
+    m_path = p_uriSpec.substring(start, index);
+
+    // query - starts with ? and up to fragment or end
+    if (testChar == '?')
+    {
+      index++;
+
+      start = index;
+
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '#')
+        {
+          break;
+        }
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                  ||!isHex(p_uriSpec.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Query string contains invalid escape sequence!");
+          }
+        }
+        else if (!isReservedCharacter(testChar)
+                 &&!isUnreservedCharacter(testChar))
+        {
+          throw new MalformedURIException(
+            "Query string contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+
+      m_queryString = p_uriSpec.substring(start, index);
+    }
+
+    // fragment - starts with #
+    if (testChar == '#')
+    {
+      index++;
+
+      start = index;
+
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                  ||!isHex(p_uriSpec.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Fragment contains invalid escape sequence!");
+          }
+        }
+        else if (!isReservedCharacter(testChar)
+                 &&!isUnreservedCharacter(testChar))
+        {
+          throw new MalformedURIException(
+            "Fragment contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+
+      m_fragment = p_uriSpec.substring(start, index);
+    }
+  }
+
+  /**
+   * Get the scheme for this URI.
+   *
+   * @return the scheme for this URI
+   */
+  public String getScheme()
+  {
+    return m_scheme;
+  }
+
+  /**
+   * Get the scheme-specific part for this URI (everything following the
+   * scheme and the first colon). See RFC 2396 Section 5.2 for spec.
+   *
+   * @return the scheme-specific part for this URI
+   */
+  public String getSchemeSpecificPart()
+  {
+
+    StringBuffer schemespec = new StringBuffer();
+
+    if (m_userinfo != null || m_host != null || m_port != -1)
+    {
+      schemespec.append("//");
+    }
+
+    if (m_userinfo != null)
+    {
+      schemespec.append(m_userinfo);
+      schemespec.append('@');
+    }
+
+    if (m_host != null)
+    {
+      schemespec.append(m_host);
+    }
+
+    if (m_port != -1)
+    {
+      schemespec.append(':');
+      schemespec.append(m_port);
+    }
+
+    if (m_path != null)
+    {
+      schemespec.append((m_path));
+    }
+
+    if (m_queryString != null)
+    {
+      schemespec.append('?');
+      schemespec.append(m_queryString);
+    }
+
+    if (m_fragment != null)
+    {
+      schemespec.append('#');
+      schemespec.append(m_fragment);
+    }
+
+    return schemespec.toString();
+  }
+
+  /**
+   * Get the userinfo for this URI.
+   *
+   * @return the userinfo for this URI (null if not specified).
+   */
+  public String getUserinfo()
+  {
+    return m_userinfo;
+  }
+
+  /**
+   * Get the host for this URI.
+   *
+   * @return the host for this URI (null if not specified).
+   */
+  public String getHost()
+  {
+    return m_host;
+  }
+
+  /**
+   * Get the port for this URI.
+   *
+   * @return the port for this URI (-1 if not specified).
+   */
+  public int getPort()
+  {
+    return m_port;
+  }
+
+  /**
+   * Get the path for this URI (optionally with the query string and
+   * fragment).
+   *
+   * @param p_includeQueryString if true (and query string is not null),
+   *                             then a "?" followed by the query string
+   *                             will be appended
+   * @param p_includeFragment if true (and fragment is not null),
+   *                             then a "#" followed by the fragment
+   *                             will be appended
+   *
+   * @return the path for this URI possibly including the query string
+   *         and fragment
+   */
+  public String getPath(boolean p_includeQueryString,
+                        boolean p_includeFragment)
+  {
+
+    StringBuffer pathString = new StringBuffer(m_path);
+
+    if (p_includeQueryString && m_queryString != null)
+    {
+      pathString.append('?');
+      pathString.append(m_queryString);
+    }
+
+    if (p_includeFragment && m_fragment != null)
+    {
+      pathString.append('#');
+      pathString.append(m_fragment);
+    }
+
+    return pathString.toString();
+  }
+
+  /**
+   * Get the path for this URI. Note that the value returned is the path
+   * only and does not include the query string or fragment.
+   *
+   * @return the path for this URI.
+   */
+  public String getPath()
+  {
+    return m_path;
+  }
+
+  /**
+   * Get the query string for this URI.
+   *
+   * @return the query string for this URI. Null is returned if there
+   *         was no "?" in the URI spec, empty string if there was a
+   *         "?" but no query string following it.
+   */
+  public String getQueryString()
+  {
+    return m_queryString;
+  }
+
+  /**
+   * Get the fragment for this URI.
+   *
+   * @return the fragment for this URI. Null is returned if there
+   *         was no "#" in the URI spec, empty string if there was a
+   *         "#" but no fragment following it.
+   */
+  public String getFragment()
+  {
+    return m_fragment;
+  }
+
+  /**
+   * Set the scheme for this URI. The scheme is converted to lowercase
+   * before it is set.
+   *
+   * @param p_scheme the scheme for this URI (cannot be null)
+   *
+   * @throws MalformedURIException if p_scheme is not a conformant
+   *                                  scheme name
+   */
+  public void setScheme(String p_scheme) throws MalformedURIException
+  {
+
+    if (p_scheme == null)
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_SCHEME_FROM_NULL_STRING, null)); //"Cannot set scheme from null string!");
+    }
+
+    if (!isConformantSchemeName(p_scheme))
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_SCHEME_NOT_CONFORMANT, null)); //"The scheme is not conformant.");
+    }
+
+    m_scheme = p_scheme.toLowerCase();
+  }
+
+  /**
+   * Set the userinfo for this URI. If a non-null value is passed in and
+   * the host value is null, then an exception is thrown.
+   *
+   * @param p_userinfo the userinfo for this URI
+   *
+   * @throws MalformedURIException if p_userinfo contains invalid
+   *                                  characters
+   */
+  public void setUserinfo(String p_userinfo) throws MalformedURIException
+  {
+
+    if (p_userinfo == null)
+    {
+      m_userinfo = null;
+    }
+    else
+    {
+      if (m_host == null)
+      {
+        throw new MalformedURIException(
+          "Userinfo cannot be set when host is null!");
+      }
+
+      // userinfo can contain alphanumerics, mark characters, escaped
+      // and ';',':','&','=','+','$',','
+      int index = 0;
+      int end = p_userinfo.length();
+      char testChar = '\0';
+
+      while (index < end)
+      {
+        testChar = p_userinfo.charAt(index);
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_userinfo.charAt(index + 1))
+                  ||!isHex(p_userinfo.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Userinfo contains invalid escape sequence!");
+          }
+        }
+        else if (!isUnreservedCharacter(testChar)
+                 && USERINFO_CHARACTERS.indexOf(testChar) == -1)
+        {
+          throw new MalformedURIException(
+            "Userinfo contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+    }
+
+    m_userinfo = p_userinfo;
+  }
+
+  /**
+   * Set the host for this URI. If null is passed in, the userinfo
+   * field is also set to null and the port is set to -1.
+   *
+   * @param p_host the host for this URI
+   *
+   * @throws MalformedURIException if p_host is not a valid IP
+   *                                  address or DNS hostname.
+   */
+  public void setHost(String p_host) throws MalformedURIException
+  {
+
+    if (p_host == null || p_host.trim().length() == 0)
+    {
+      m_host = p_host;
+      m_userinfo = null;
+      m_port = -1;
+    }
+    else if (!isWellFormedAddress(p_host))
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_HOST_ADDRESS_NOT_WELLFORMED, null)); //"Host is not a well formed address!");
+    }
+
+    m_host = p_host;
+  }
+
+  /**
+   * Set the port for this URI. -1 is used to indicate that the port is
+   * not specified, otherwise valid port numbers are  between 0 and 65535.
+   * If a valid port number is passed in and the host field is null,
+   * an exception is thrown.
+   *
+   * @param p_port the port number for this URI
+   *
+   * @throws MalformedURIException if p_port is not -1 and not a
+   *                                  valid port number
+   */
+  public void setPort(int p_port) throws MalformedURIException
+  {
+
+    if (p_port >= 0 && p_port <= 65535)
+    {
+      if (m_host == null)
+      {
+        throw new MalformedURIException(
+          Utils.messages.createMessage(MsgKey.ER_PORT_WHEN_HOST_NULL, null)); //"Port cannot be set when host is null!");
+      }
+    }
+    else if (p_port != -1)
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_INVALID_PORT, null)); //"Invalid port number!");
+    }
+
+    m_port = p_port;
+  }
+
+  /**
+   * Set the path for this URI. If the supplied path is null, then the
+   * query string and fragment are set to null as well. If the supplied
+   * path includes a query string and/or fragment, these fields will be
+   * parsed and set as well. Note that, for URIs following the "generic
+   * URI" syntax, the path specified should start with a slash.
+   * For URIs that do not follow the generic URI syntax, this method
+   * sets the scheme-specific part.
+   *
+   * @param p_path the path for this URI (may be null)
+   *
+   * @throws MalformedURIException if p_path contains invalid
+   *                                  characters
+   */
+  public void setPath(String p_path) throws MalformedURIException
+  {
+
+    if (p_path == null)
+    {
+      m_path = null;
+      m_queryString = null;
+      m_fragment = null;
+    }
+    else
+    {
+      initializePath(p_path);
+    }
+  }
+
+  /**
+   * Append to the end of the path of this URI. If the current path does
+   * not end in a slash and the path to be appended does not begin with
+   * a slash, a slash will be appended to the current path before the
+   * new segment is added. Also, if the current path ends in a slash
+   * and the new segment begins with a slash, the extra slash will be
+   * removed before the new segment is appended.
+   *
+   * @param p_addToPath the new segment to be added to the current path
+   *
+   * @throws MalformedURIException if p_addToPath contains syntax
+   *                                  errors
+   */
+  public void appendPath(String p_addToPath) throws MalformedURIException
+  {
+
+    if (p_addToPath == null || p_addToPath.trim().length() == 0)
+    {
+      return;
+    }
+
+    if (!isURIString(p_addToPath))
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_PATH_INVALID_CHAR, new Object[]{p_addToPath})); //"Path contains invalid character!");
+    }
+
+    if (m_path == null || m_path.trim().length() == 0)
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = p_addToPath;
+      }
+      else
+      {
+        m_path = "/" + p_addToPath;
+      }
+    }
+    else if (m_path.endsWith("/"))
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = m_path.concat(p_addToPath.substring(1));
+      }
+      else
+      {
+        m_path = m_path.concat(p_addToPath);
+      }
+    }
+    else
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = m_path.concat(p_addToPath);
+      }
+      else
+      {
+        m_path = m_path.concat("/" + p_addToPath);
+      }
+    }
+  }
+
+  /**
+   * Set the query string for this URI. A non-null value is valid only
+   * if this is an URI conforming to the generic URI syntax and
+   * the path value is not null.
+   *
+   * @param p_queryString the query string for this URI
+   *
+   * @throws MalformedURIException if p_queryString is not null and this
+   *                                  URI does not conform to the generic
+   *                                  URI syntax or if the path is null
+   */
+  public void setQueryString(String p_queryString)
+          throws MalformedURIException
+  {
+
+    if (p_queryString == null)
+    {
+      m_queryString = null;
+    }
+    else if (!isGenericURI())
+    {
+      throw new MalformedURIException(
+        "Query string can only be set for a generic URI!");
+    }
+    else if (getPath() == null)
+    {
+      throw new MalformedURIException(
+        "Query string cannot be set when path is null!");
+    }
+    else if (!isURIString(p_queryString))
+    {
+      throw new MalformedURIException(
+        "Query string contains invalid character!");
+    }
+    else
+    {
+      m_queryString = p_queryString;
+    }
+  }
+
+  /**
+   * Set the fragment for this URI. A non-null value is valid only
+   * if this is a URI conforming to the generic URI syntax and
+   * the path value is not null.
+   *
+   * @param p_fragment the fragment for this URI
+   *
+   * @throws MalformedURIException if p_fragment is not null and this
+   *                                  URI does not conform to the generic
+   *                                  URI syntax or if the path is null
+   */
+  public void setFragment(String p_fragment) throws MalformedURIException
+  {
+
+    if (p_fragment == null)
+    {
+      m_fragment = null;
+    }
+    else if (!isGenericURI())
+    {
+      throw new MalformedURIException(
+        Utils.messages.createMessage(MsgKey.ER_FRAG_FOR_GENERIC_URI, null)); //"Fragment can only be set for a generic URI!");
+    }
+    else if (getPath() == null)
+    {
+      throw new MalformedURIException(
+        Utils.messages.createMessage(MsgKey.ER_FRAG_WHEN_PATH_NULL, null)); //"Fragment cannot be set when path is null!");
+    }
+    else if (!isURIString(p_fragment))
+    {
+      throw new MalformedURIException(Utils.messages.createMessage(MsgKey.ER_FRAG_INVALID_CHAR, null)); //"Fragment contains invalid character!");
+    }
+    else
+    {
+      m_fragment = p_fragment;
+    }
+  }
+
+  /**
+   * Determines if the passed-in Object is equivalent to this URI.
+   *
+   * @param p_test the Object to test for equality.
+   *
+   * @return true if p_test is a URI with all values equal to this
+   *         URI, false otherwise
+   */
+  public boolean equals(Object p_test)
+  {
+
+    if (p_test instanceof URI)
+    {
+      URI testURI = (URI) p_test;
+
+      if (((m_scheme == null && testURI.m_scheme == null) || (m_scheme != null && testURI.m_scheme != null && m_scheme.equals(
+              testURI.m_scheme))) && ((m_userinfo == null && testURI.m_userinfo == null) || (m_userinfo != null && testURI.m_userinfo != null && m_userinfo.equals(
+              testURI.m_userinfo))) && ((m_host == null && testURI.m_host == null) || (m_host != null && testURI.m_host != null && m_host.equals(
+              testURI.m_host))) && m_port == testURI.m_port && ((m_path == null && testURI.m_path == null) || (m_path != null && testURI.m_path != null && m_path.equals(
+              testURI.m_path))) && ((m_queryString == null && testURI.m_queryString == null) || (m_queryString != null && testURI.m_queryString != null && m_queryString.equals(
+              testURI.m_queryString))) && ((m_fragment == null && testURI.m_fragment == null) || (m_fragment != null && testURI.m_fragment != null && m_fragment.equals(
+              testURI.m_fragment))))
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Get the URI as a string specification. See RFC 2396 Section 5.2.
+   *
+   * @return the URI string specification
+   */
+  public String toString()
+  {
+
+    StringBuffer uriSpecString = new StringBuffer();
+
+    if (m_scheme != null)
+    {
+      uriSpecString.append(m_scheme);
+      uriSpecString.append(':');
+    }
+
+    uriSpecString.append(getSchemeSpecificPart());
+
+    return uriSpecString.toString();
+  }
+
+  /**
+   * Get the indicator as to whether this URI uses the "generic URI"
+   * syntax.
+   *
+   * @return true if this URI uses the "generic URI" syntax, false
+   *         otherwise
+   */
+  public boolean isGenericURI()
+  {
+
+    // presence of the host (whether valid or empty) means 
+    // double-slashes which means generic uri
+    return (m_host != null);
+  }
+
+  /**
+   * Determine whether a scheme conforms to the rules for a scheme name.
+   * A scheme is conformant if it starts with an alphanumeric, and
+   * contains only alphanumerics, '+','-' and '.'.
+   *
+   *
+   * @param p_scheme The sheme name to check
+   * @return true if the scheme is conformant, false otherwise
+   */
+  public static boolean isConformantSchemeName(String p_scheme)
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      return false;
+    }
+
+    if (!isAlpha(p_scheme.charAt(0)))
+    {
+      return false;
+    }
+
+    char testChar;
+
+    for (int i = 1; i < p_scheme.length(); i++)
+    {
+      testChar = p_scheme.charAt(i);
+
+      if (!isAlphanum(testChar) && SCHEME_CHARACTERS.indexOf(testChar) == -1)
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Determine whether a string is syntactically capable of representing
+   * a valid IPv4 address or the domain name of a network host. A valid
+   * IPv4 address consists of four decimal digit groups separated by a
+   * '.'. A hostname consists of domain labels (each of which must
+   * begin and end with an alphanumeric but may contain '-') separated
+   * & by a '.'. See RFC 2396 Section 3.2.2.
+   *
+   *
+   * @param p_address The address string to check
+   * @return true if the string is a syntactically valid IPv4 address
+   *              or hostname
+   */
+  public static boolean isWellFormedAddress(String p_address)
+  {
+
+    if (p_address == null)
+    {
+      return false;
+    }
+
+    String address = p_address.trim();
+    int addrLength = address.length();
+
+    if (addrLength == 0 || addrLength > 255)
+    {
+      return false;
+    }
+
+    if (address.startsWith(".") || address.startsWith("-"))
+    {
+      return false;
+    }
+
+    // rightmost domain label starting with digit indicates IP address
+    // since top level domain label can only start with an alpha
+    // see RFC 2396 Section 3.2.2
+    int index = address.lastIndexOf('.');
+
+    if (address.endsWith("."))
+    {
+      index = address.substring(0, index).lastIndexOf('.');
+    }
+
+    if (index + 1 < addrLength && isDigit(p_address.charAt(index + 1)))
+    {
+      char testChar;
+      int numDots = 0;
+
+      // make sure that 1) we see only digits and dot separators, 2) that
+      // any dot separator is preceded and followed by a digit and 
+      // 3) that we find 3 dots
+      for (int i = 0; i < addrLength; i++)
+      {
+        testChar = address.charAt(i);
+
+        if (testChar == '.')
+        {
+          if (!isDigit(address.charAt(i - 1))
+                  || (i + 1 < addrLength &&!isDigit(address.charAt(i + 1))))
+          {
+            return false;
+          }
+
+          numDots++;
+        }
+        else if (!isDigit(testChar))
+        {
+          return false;
+        }
+      }
+
+      if (numDots != 3)
+      {
+        return false;
+      }
+    }
+    else
+    {
+
+      // domain labels can contain alphanumerics and '-"
+      // but must start and end with an alphanumeric
+      char testChar;
+
+      for (int i = 0; i < addrLength; i++)
+      {
+        testChar = address.charAt(i);
+
+        if (testChar == '.')
+        {
+          if (!isAlphanum(address.charAt(i - 1)))
+          {
+            return false;
+          }
+
+          if (i + 1 < addrLength &&!isAlphanum(address.charAt(i + 1)))
+          {
+            return false;
+          }
+        }
+        else if (!isAlphanum(testChar) && testChar != '-')
+        {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Determine whether a char is a digit.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is betweeen '0' and '9', false otherwise
+   */
+  private static boolean isDigit(char p_char)
+  {
+    return p_char >= '0' && p_char <= '9';
+  }
+
+  /**
+   * Determine whether a character is a hexadecimal character.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is betweeen '0' and '9', 'a' and 'f'
+   *         or 'A' and 'F', false otherwise
+   */
+  private static boolean isHex(char p_char)
+  {
+    return (isDigit(p_char) || (p_char >= 'a' && p_char <= 'f')
+            || (p_char >= 'A' && p_char <= 'F'));
+  }
+
+  /**
+   * Determine whether a char is an alphabetic character: a-z or A-Z
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is alphabetic, false otherwise
+   */
+  private static boolean isAlpha(char p_char)
+  {
+    return ((p_char >= 'a' && p_char <= 'z')
+            || (p_char >= 'A' && p_char <= 'Z'));
+  }
+
+  /**
+   * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is alphanumeric, false otherwise
+   */
+  private static boolean isAlphanum(char p_char)
+  {
+    return (isAlpha(p_char) || isDigit(p_char));
+  }
+
+  /**
+   * Determine whether a character is a reserved character:
+   * ';', '/', '?', ':', '@', '&', '=', '+', '$' or ','
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the string contains any reserved characters
+   */
+  private static boolean isReservedCharacter(char p_char)
+  {
+    return RESERVED_CHARACTERS.indexOf(p_char) != -1;
+  }
+
+  /**
+   * Determine whether a char is an unreserved character.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is unreserved, false otherwise
+   */
+  private static boolean isUnreservedCharacter(char p_char)
+  {
+    return (isAlphanum(p_char) || MARK_CHARACTERS.indexOf(p_char) != -1);
+  }
+
+  /**
+   * Determine whether a given string contains only URI characters (also
+   * called "uric" in RFC 2396). uric consist of all reserved
+   * characters, unreserved characters and escaped characters.
+   *
+   *
+   * @param p_uric URI string
+   * @return true if the string is comprised of uric, false otherwise
+   */
+  private static boolean isURIString(String p_uric)
+  {
+
+    if (p_uric == null)
+    {
+      return false;
+    }
+
+    int end = p_uric.length();
+    char testChar = '\0';
+
+    for (int i = 0; i < end; i++)
+    {
+      testChar = p_uric.charAt(i);
+
+      if (testChar == '%')
+      {
+        if (i + 2 >= end ||!isHex(p_uric.charAt(i + 1))
+                ||!isHex(p_uric.charAt(i + 2)))
+        {
+          return false;
+        }
+        else
+        {
+          i += 2;
+
+          continue;
+        }
+      }
+
+      if (isReservedCharacter(testChar) || isUnreservedCharacter(testChar))
+      {
+        continue;
+      }
+      else
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/Utils.java b/src/main/java/org/apache/xml/serializer/utils/Utils.java
new file mode 100644
index 0000000..8990143
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/Utils.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Utils.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+/**
+ * This class contains utilities used by the serializer.
+ * 
+ * This class is not a public API, it is only public because it is
+ * used by the serializer.
+ * 
+ * @xsl.usage internal
+ */
+public final class Utils
+{
+    /**
+     * A singleton Messages object is used to load the 
+     * given resource bundle just once, it is
+     * used by multiple transformations as long as the JVM stays up.
+     */
+    public static final Messages messages= 
+        new Messages(SerializerMessages.class.getName());
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/WrappedRuntimeException.java b/src/main/java/org/apache/xml/serializer/utils/WrappedRuntimeException.java
new file mode 100644
index 0000000..e26eb3f
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/WrappedRuntimeException.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WrappedRuntimeException.java 468654 2006-10-28 07:09:23Z minchau $
+ */
+package org.apache.xml.serializer.utils;
+
+/**
+ * This class is for throwing important checked exceptions
+ * over non-checked methods.  It should be used with care,
+ * and in limited circumstances.
+ * 
+ * This class is a copy of the one in org.apache.xml.utils. 
+ * It exists to cut the serializers dependancy on that package.
+ * 
+ * This class is not a public API, it is only public because it is
+ * used by org.apache.xml.serializer.
+ * @xsl.usage internal
+ */
+public final class WrappedRuntimeException extends RuntimeException
+{
+    static final long serialVersionUID = 7140414456714658073L;
+
+  /** Primary checked exception.
+   *  @serial          */
+  private Exception m_exception;
+
+  /**
+   * Construct a WrappedRuntimeException from a
+   * checked exception.
+   *
+   * @param e Primary checked exception
+   */
+  public WrappedRuntimeException(Exception e)
+  {
+
+    super(e.getMessage());
+
+    m_exception = e;
+  }
+
+  /**
+   * Constructor WrappedRuntimeException
+   *
+   *
+   * @param msg Exception information.
+   * @param e Primary checked exception
+   */
+  public WrappedRuntimeException(String msg, Exception e)
+  {
+
+    super(msg);
+
+    m_exception = e;
+  }
+  
+  /**
+   * Get the checked exception that this runtime exception wraps.
+   *
+   * @return The primary checked exception
+   */
+  public Exception getException()
+  {
+    return m_exception;
+  }
+}
diff --git a/src/main/java/org/apache/xml/serializer/utils/XML11Char.java b/src/main/java/org/apache/xml/serializer/utils/XML11Char.java
new file mode 100644
index 0000000..2cbd522
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/XML11Char.java
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.Arrays;
+
+/**
+ * THIS IS A COPY OF THE XERCES-2J CLASS org.apache.xerces.utls.XMLChar
+ *  
+ * This class defines the basic properties of characters in XML 1.1. The data
+ * in this class can be used to verify that a character is a valid
+ * XML 1.1 character or if the character is a space, name start, or name
+ * character.
+ * <p>
+ * A series of convenience methods are supplied to ease the burden
+ * of the developer.  Using the character as an index into the <code>XML11CHARS</code>
+ * array and applying the appropriate mask flag (e.g.
+ * <code>MASK_VALID</code>), yields the same results as calling the
+ * convenience methods. There is one exception: check the comments
+ * for the <code>isValid</code> method for details.
+ *
+ * @author Glenn Marcy, IBM
+ * @author Andy Clark, IBM
+ * @author Arnaud  Le Hors, IBM
+ * @author Neil Graham, IBM
+ * @author Michael Glavassevich, IBM
+ *
+ * @version $Id: $
+ */
+public class XML11Char {
+
+    //
+    // Constants
+    //
+
+    /** Character flags for XML 1.1. */
+    private static final byte XML11CHARS [] = new byte [1 << 16];
+
+    /** XML 1.1 Valid character mask. */
+    public static final int MASK_XML11_VALID = 0x01;
+
+    /** XML 1.1 Space character mask. */
+    public static final int MASK_XML11_SPACE = 0x02;
+
+    /** XML 1.1 Name start character mask. */
+    public static final int MASK_XML11_NAME_START = 0x04;
+
+    /** XML 1.1 Name character mask. */
+    public static final int MASK_XML11_NAME = 0x08;
+
+    /** XML 1.1 control character mask */
+    public static final int MASK_XML11_CONTROL = 0x10;
+
+    /** XML 1.1 content for external entities (valid - "special" chars - control chars) */
+    public static final int MASK_XML11_CONTENT = 0x20;
+
+    /** XML namespaces 1.1 NCNameStart */
+    public static final int MASK_XML11_NCNAME_START = 0x40;
+
+    /** XML namespaces 1.1 NCName */
+    public static final int MASK_XML11_NCNAME = 0x80;
+    
+    /** XML 1.1 content for internal entities (valid - "special" chars) */
+    public static final int MASK_XML11_CONTENT_INTERNAL = MASK_XML11_CONTROL | MASK_XML11_CONTENT; 
+
+    //
+    // Static initialization
+    //
+
+    static {
+    	
+        // Initializing the Character Flag Array
+        // Code generated by: XML11CharGenerator.
+        
+        Arrays.fill(XML11CHARS, 1, 9, (byte) 17 ); // Fill 8 of value (byte) 17
+        XML11CHARS[9] = 35;
+        XML11CHARS[10] = 3;
+        Arrays.fill(XML11CHARS, 11, 13, (byte) 17 ); // Fill 2 of value (byte) 17
+        XML11CHARS[13] = 3;
+        Arrays.fill(XML11CHARS, 14, 32, (byte) 17 ); // Fill 18 of value (byte) 17
+        XML11CHARS[32] = 35;
+        Arrays.fill(XML11CHARS, 33, 38, (byte) 33 ); // Fill 5 of value (byte) 33
+        XML11CHARS[38] = 1;
+        Arrays.fill(XML11CHARS, 39, 45, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(XML11CHARS, 45, 47, (byte) -87 ); // Fill 2 of value (byte) -87
+        XML11CHARS[47] = 33;
+        Arrays.fill(XML11CHARS, 48, 58, (byte) -87 ); // Fill 10 of value (byte) -87
+        XML11CHARS[58] = 45;
+        XML11CHARS[59] = 33;
+        XML11CHARS[60] = 1;
+        Arrays.fill(XML11CHARS, 61, 65, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(XML11CHARS, 65, 91, (byte) -19 ); // Fill 26 of value (byte) -19
+        Arrays.fill(XML11CHARS, 91, 93, (byte) 33 ); // Fill 2 of value (byte) 33
+        XML11CHARS[93] = 1;
+        XML11CHARS[94] = 33;
+        XML11CHARS[95] = -19;
+        XML11CHARS[96] = 33;
+        Arrays.fill(XML11CHARS, 97, 123, (byte) -19 ); // Fill 26 of value (byte) -19
+        Arrays.fill(XML11CHARS, 123, 127, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(XML11CHARS, 127, 133, (byte) 17 ); // Fill 6 of value (byte) 17
+        XML11CHARS[133] = 35;
+        Arrays.fill(XML11CHARS, 134, 160, (byte) 17 ); // Fill 26 of value (byte) 17
+        Arrays.fill(XML11CHARS, 160, 183, (byte) 33 ); // Fill 23 of value (byte) 33
+        XML11CHARS[183] = -87;
+        Arrays.fill(XML11CHARS, 184, 192, (byte) 33 ); // Fill 8 of value (byte) 33
+        Arrays.fill(XML11CHARS, 192, 215, (byte) -19 ); // Fill 23 of value (byte) -19
+        XML11CHARS[215] = 33;
+        Arrays.fill(XML11CHARS, 216, 247, (byte) -19 ); // Fill 31 of value (byte) -19
+        XML11CHARS[247] = 33;
+        Arrays.fill(XML11CHARS, 248, 768, (byte) -19 ); // Fill 520 of value (byte) -19
+        Arrays.fill(XML11CHARS, 768, 880, (byte) -87 ); // Fill 112 of value (byte) -87
+        Arrays.fill(XML11CHARS, 880, 894, (byte) -19 ); // Fill 14 of value (byte) -19
+        XML11CHARS[894] = 33;
+        Arrays.fill(XML11CHARS, 895, 8192, (byte) -19 ); // Fill 7297 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8192, 8204, (byte) 33 ); // Fill 12 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8204, 8206, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8206, 8232, (byte) 33 ); // Fill 26 of value (byte) 33
+        XML11CHARS[8232] = 35;
+        Arrays.fill(XML11CHARS, 8233, 8255, (byte) 33 ); // Fill 22 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8255, 8257, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(XML11CHARS, 8257, 8304, (byte) 33 ); // Fill 47 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8304, 8592, (byte) -19 ); // Fill 288 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8592, 11264, (byte) 33 ); // Fill 2672 of value (byte) 33
+        Arrays.fill(XML11CHARS, 11264, 12272, (byte) -19 ); // Fill 1008 of value (byte) -19
+        Arrays.fill(XML11CHARS, 12272, 12289, (byte) 33 ); // Fill 17 of value (byte) 33
+        Arrays.fill(XML11CHARS, 12289, 55296, (byte) -19 ); // Fill 43007 of value (byte) -19
+        Arrays.fill(XML11CHARS, 57344, 63744, (byte) 33 ); // Fill 6400 of value (byte) 33
+        Arrays.fill(XML11CHARS, 63744, 64976, (byte) -19 ); // Fill 1232 of value (byte) -19
+        Arrays.fill(XML11CHARS, 64976, 65008, (byte) 33 ); // Fill 32 of value (byte) 33
+        Arrays.fill(XML11CHARS, 65008, 65534, (byte) -19 ); // Fill 526 of value (byte) -19
+
+    } // <clinit>()
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Returns true if the specified character is a space character
+     * as amdended in the XML 1.1 specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Space(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_SPACE) != 0);
+    } // isXML11Space(int):boolean
+
+    /**
+     * Returns true if the specified character is valid. This method
+     * also checks the surrogate character range from 0x10000 to 0x10FFFF.
+     * <p>
+     * If the program chooses to apply the mask directly to the
+     * <code>XML11CHARS</code> array, then they are responsible for checking
+     * the surrogate character range.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Valid(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_VALID) != 0) 
+                || (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11Valid(int):boolean
+
+    /**
+     * Returns true if the specified character is invalid.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Invalid(int c) {
+        return !isXML11Valid(c);
+    } // isXML11Invalid(int):boolean
+
+    /**
+     * Returns true if the specified character is valid and permitted outside
+     * of a character reference.  
+     * That is, this method will return false for the same set as
+     * isXML11Valid, except it also reports false for "control characters".
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11ValidLiteral(int c) {
+        return ((c < 0x10000 && ((XML11CHARS[c] & MASK_XML11_VALID) != 0 && (XML11CHARS[c] & MASK_XML11_CONTROL) == 0))
+            || (0x10000 <= c && c <= 0x10FFFF)); 
+    } // isXML11ValidLiteral(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered 
+     * content in an external parsed entity.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Content(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_CONTENT) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11Content(int):boolean
+    
+    /**
+     * Returns true if the specified character can be considered 
+     * content in an internal parsed entity.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11InternalEntityContent(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_CONTENT_INTERNAL) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11InternalEntityContent(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name start
+     * character as defined by production [4] in the XML 1.1
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NameStart(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NAME_START) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name
+     * character as defined by production [4a] in the XML 1.1
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Name(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NAME) != 0) 
+            || (c >= 0x10000 && c < 0xF0000);
+    } // isXML11Name(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName start
+     * character as defined by production [4] in Namespaces in XML
+     * 1.1 recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NCNameStart(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NCNAME_START) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NCNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName
+     * character as defined by production [5] in Namespaces in XML
+     * 1.1 recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NCName(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NCNAME) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NCName(int):boolean
+    
+    /**
+     * Returns whether the given character is a valid 
+     * high surrogate for a name character. This includes
+     * all high surrogates for characters [0x10000-0xEFFFF].
+     * In other words everything excluding planes 15 and 16.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NameHighSurrogate(int c) {
+        return (0xD800 <= c && c <= 0xDB7F);
+    }
+
+    /*
+     * [5] Name ::= NameStartChar NameChar*
+     */
+    /**
+     * Check to see if a string is a valid Name according to [5]
+     * in the XML 1.1 Recommendation
+     *
+     * @param name string to check
+     * @return true if name is a valid Name
+     */
+    public static boolean isXML11ValidName(String name) {
+        int length = name.length();
+        if (length == 0)
+            return false;
+        int i = 1;
+        char ch = name.charAt(0);
+        if( !isXML11NameStart(ch) ) {
+            if ( length > 1 && isXML11NameHighSurrogate(ch) ) {
+                char ch2 = name.charAt(1);
+                if ( !XMLChar.isLowSurrogate(ch2) || 
+                     !isXML11NameStart(XMLChar.supplemental(ch, ch2)) ) {
+                    return false;
+                }
+                i = 2;
+            }
+            else {
+                return false;
+            }
+        }
+        while (i < length) {
+            ch = name.charAt(i);
+            if ( !isXML11Name(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = name.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+            ++i;
+        }
+        return true;
+    } // isXML11ValidName(String):boolean
+    
+
+    /*
+     * from the namespace 1.1 rec
+     * [4] NCName ::= NCNameStartChar NCNameChar*
+     */
+    /**
+     * Check to see if a string is a valid NCName according to [4]
+     * from the XML Namespaces 1.1 Recommendation
+     *
+     * @param ncName string to check
+     * @return true if name is a valid NCName
+     */
+    public static boolean isXML11ValidNCName(String ncName) {
+        int length = ncName.length();
+        if (length == 0)
+            return false;
+        int i = 1;
+        char ch = ncName.charAt(0);
+        if( !isXML11NCNameStart(ch) ) {
+            if ( length > 1 && isXML11NameHighSurrogate(ch) ) {
+                char ch2 = ncName.charAt(1);
+                if ( !XMLChar.isLowSurrogate(ch2) || 
+                     !isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) {
+                    return false;
+                }
+                i = 2;
+            }
+            else {
+                return false;
+            }
+        }
+        while (i < length) {
+            ch = ncName.charAt(i);
+            if ( !isXML11NCName(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = ncName.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11NCName(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+            ++i;
+        }
+        return true;
+    } // isXML11ValidNCName(String):boolean
+
+    /*
+     * [7] Nmtoken ::= (NameChar)+
+     */
+    /**
+     * Check to see if a string is a valid Nmtoken according to [7]
+     * in the XML 1.1 Recommendation
+     *
+     * @param nmtoken string to check
+     * @return true if nmtoken is a valid Nmtoken 
+     */
+    public static boolean isXML11ValidNmtoken(String nmtoken) {
+        int length = nmtoken.length();
+        if (length == 0)
+            return false;
+        for (int i = 0; i < length; ++i ) {
+            char ch = nmtoken.charAt(i);
+            if( !isXML11Name(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = nmtoken.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+        }
+        return true;
+    } // isXML11ValidName(String):boolean
+
+} // class XML11Char
+
diff --git a/src/main/java/org/apache/xml/serializer/utils/XMLChar.java b/src/main/java/org/apache/xml/serializer/utils/XMLChar.java
new file mode 100644
index 0000000..313dd10
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/utils/XMLChar.java
@@ -0,0 +1,1026 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xml.serializer.utils;
+
+import java.util.Arrays;
+
+/**
+ * THIS IS A COPY OF THE XERCES-2J CLASS org.apache.xerces.utls.XMLChar
+ * 
+ * This class defines the basic XML character properties. The data
+ * in this class can be used to verify that a character is a valid
+ * XML character or if the character is a space, name start, or name
+ * character.
+ * <p>
+ * A series of convenience methods are supplied to ease the burden
+ * of the developer. Because inlining the checks can improve per
+ * character performance, the tables of character properties are
+ * public. Using the character as an index into the <code>CHARS</code>
+ * array and applying the appropriate mask flag (e.g.
+ * <code>MASK_VALID</code>), yields the same results as calling the
+ * convenience methods. There is one exception: check the comments
+ * for the <code>isValid</code> method for details.
+ *
+ * @author Glenn Marcy, IBM
+ * @author Andy Clark, IBM
+ * @author Eric Ye, IBM
+ * @author Arnaud  Le Hors, IBM
+ * @author Michael Glavassevich, IBM
+ * @author Rahul Srivastava, Sun Microsystems Inc.
+ *
+ * @version $Id: $
+ */
+public class XMLChar {
+
+    //
+    // Constants
+    //
+
+    /** Character flags. */
+    private static final byte[] CHARS = new byte[1 << 16];
+
+    /** Valid character mask. */
+    public static final int MASK_VALID = 0x01;
+
+    /** Space character mask. */
+    public static final int MASK_SPACE = 0x02;
+
+    /** Name start character mask. */
+    public static final int MASK_NAME_START = 0x04;
+
+    /** Name character mask. */
+    public static final int MASK_NAME = 0x08;
+
+    /** Pubid character mask. */
+    public static final int MASK_PUBID = 0x10;
+    
+    /** 
+     * Content character mask. Special characters are those that can
+     * be considered the start of markup, such as '&lt;' and '&amp;'. 
+     * The various newline characters are considered special as well.
+     * All other valid XML characters can be considered content.
+     * <p>
+     * This is an optimization for the inner loop of character scanning.
+     */
+    public static final int MASK_CONTENT = 0x20;
+
+    /** NCName start character mask. */
+    public static final int MASK_NCNAME_START = 0x40;
+
+    /** NCName character mask. */
+    public static final int MASK_NCNAME = 0x80;
+
+    //
+    // Static initialization
+    //
+
+    static {
+        
+        // Initializing the Character Flag Array
+        // Code generated by: XMLCharGenerator.
+        
+        CHARS[9] = 35;
+        CHARS[10] = 19;
+        CHARS[13] = 19;
+        CHARS[32] = 51;
+        CHARS[33] = 49;
+        CHARS[34] = 33;
+        Arrays.fill(CHARS, 35, 38, (byte) 49 ); // Fill 3 of value (byte) 49
+        CHARS[38] = 1;
+        Arrays.fill(CHARS, 39, 45, (byte) 49 ); // Fill 6 of value (byte) 49
+        Arrays.fill(CHARS, 45, 47, (byte) -71 ); // Fill 2 of value (byte) -71
+        CHARS[47] = 49;
+        Arrays.fill(CHARS, 48, 58, (byte) -71 ); // Fill 10 of value (byte) -71
+        CHARS[58] = 61;
+        CHARS[59] = 49;
+        CHARS[60] = 1;
+        CHARS[61] = 49;
+        CHARS[62] = 33;
+        Arrays.fill(CHARS, 63, 65, (byte) 49 ); // Fill 2 of value (byte) 49
+        Arrays.fill(CHARS, 65, 91, (byte) -3 ); // Fill 26 of value (byte) -3
+        Arrays.fill(CHARS, 91, 93, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[93] = 1;
+        CHARS[94] = 33;
+        CHARS[95] = -3;
+        CHARS[96] = 33;
+        Arrays.fill(CHARS, 97, 123, (byte) -3 ); // Fill 26 of value (byte) -3
+        Arrays.fill(CHARS, 123, 183, (byte) 33 ); // Fill 60 of value (byte) 33
+        CHARS[183] = -87;
+        Arrays.fill(CHARS, 184, 192, (byte) 33 ); // Fill 8 of value (byte) 33
+        Arrays.fill(CHARS, 192, 215, (byte) -19 ); // Fill 23 of value (byte) -19
+        CHARS[215] = 33;
+        Arrays.fill(CHARS, 216, 247, (byte) -19 ); // Fill 31 of value (byte) -19
+        CHARS[247] = 33;
+        Arrays.fill(CHARS, 248, 306, (byte) -19 ); // Fill 58 of value (byte) -19
+        Arrays.fill(CHARS, 306, 308, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 308, 319, (byte) -19 ); // Fill 11 of value (byte) -19
+        Arrays.fill(CHARS, 319, 321, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 321, 329, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[329] = 33;
+        Arrays.fill(CHARS, 330, 383, (byte) -19 ); // Fill 53 of value (byte) -19
+        CHARS[383] = 33;
+        Arrays.fill(CHARS, 384, 452, (byte) -19 ); // Fill 68 of value (byte) -19
+        Arrays.fill(CHARS, 452, 461, (byte) 33 ); // Fill 9 of value (byte) 33
+        Arrays.fill(CHARS, 461, 497, (byte) -19 ); // Fill 36 of value (byte) -19
+        Arrays.fill(CHARS, 497, 500, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 500, 502, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 502, 506, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 506, 536, (byte) -19 ); // Fill 30 of value (byte) -19
+        Arrays.fill(CHARS, 536, 592, (byte) 33 ); // Fill 56 of value (byte) 33
+        Arrays.fill(CHARS, 592, 681, (byte) -19 ); // Fill 89 of value (byte) -19
+        Arrays.fill(CHARS, 681, 699, (byte) 33 ); // Fill 18 of value (byte) 33
+        Arrays.fill(CHARS, 699, 706, (byte) -19 ); // Fill 7 of value (byte) -19
+        Arrays.fill(CHARS, 706, 720, (byte) 33 ); // Fill 14 of value (byte) 33
+        Arrays.fill(CHARS, 720, 722, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 722, 768, (byte) 33 ); // Fill 46 of value (byte) 33
+        Arrays.fill(CHARS, 768, 838, (byte) -87 ); // Fill 70 of value (byte) -87
+        Arrays.fill(CHARS, 838, 864, (byte) 33 ); // Fill 26 of value (byte) 33
+        Arrays.fill(CHARS, 864, 866, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 866, 902, (byte) 33 ); // Fill 36 of value (byte) 33
+        CHARS[902] = -19;
+        CHARS[903] = -87;
+        Arrays.fill(CHARS, 904, 907, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[907] = 33;
+        CHARS[908] = -19;
+        CHARS[909] = 33;
+        Arrays.fill(CHARS, 910, 930, (byte) -19 ); // Fill 20 of value (byte) -19
+        CHARS[930] = 33;
+        Arrays.fill(CHARS, 931, 975, (byte) -19 ); // Fill 44 of value (byte) -19
+        CHARS[975] = 33;
+        Arrays.fill(CHARS, 976, 983, (byte) -19 ); // Fill 7 of value (byte) -19
+        Arrays.fill(CHARS, 983, 986, (byte) 33 ); // Fill 3 of value (byte) 33
+        CHARS[986] = -19;
+        CHARS[987] = 33;
+        CHARS[988] = -19;
+        CHARS[989] = 33;
+        CHARS[990] = -19;
+        CHARS[991] = 33;
+        CHARS[992] = -19;
+        CHARS[993] = 33;
+        Arrays.fill(CHARS, 994, 1012, (byte) -19 ); // Fill 18 of value (byte) -19
+        Arrays.fill(CHARS, 1012, 1025, (byte) 33 ); // Fill 13 of value (byte) 33
+        Arrays.fill(CHARS, 1025, 1037, (byte) -19 ); // Fill 12 of value (byte) -19
+        CHARS[1037] = 33;
+        Arrays.fill(CHARS, 1038, 1104, (byte) -19 ); // Fill 66 of value (byte) -19
+        CHARS[1104] = 33;
+        Arrays.fill(CHARS, 1105, 1117, (byte) -19 ); // Fill 12 of value (byte) -19
+        CHARS[1117] = 33;
+        Arrays.fill(CHARS, 1118, 1154, (byte) -19 ); // Fill 36 of value (byte) -19
+        CHARS[1154] = 33;
+        Arrays.fill(CHARS, 1155, 1159, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 1159, 1168, (byte) 33 ); // Fill 9 of value (byte) 33
+        Arrays.fill(CHARS, 1168, 1221, (byte) -19 ); // Fill 53 of value (byte) -19
+        Arrays.fill(CHARS, 1221, 1223, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1223, 1225, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 1225, 1227, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1227, 1229, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 1229, 1232, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 1232, 1260, (byte) -19 ); // Fill 28 of value (byte) -19
+        Arrays.fill(CHARS, 1260, 1262, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1262, 1270, (byte) -19 ); // Fill 8 of value (byte) -19
+        Arrays.fill(CHARS, 1270, 1272, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1272, 1274, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 1274, 1329, (byte) 33 ); // Fill 55 of value (byte) 33
+        Arrays.fill(CHARS, 1329, 1367, (byte) -19 ); // Fill 38 of value (byte) -19
+        Arrays.fill(CHARS, 1367, 1369, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[1369] = -19;
+        Arrays.fill(CHARS, 1370, 1377, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 1377, 1415, (byte) -19 ); // Fill 38 of value (byte) -19
+        Arrays.fill(CHARS, 1415, 1425, (byte) 33 ); // Fill 10 of value (byte) 33
+        Arrays.fill(CHARS, 1425, 1442, (byte) -87 ); // Fill 17 of value (byte) -87
+        CHARS[1442] = 33;
+        Arrays.fill(CHARS, 1443, 1466, (byte) -87 ); // Fill 23 of value (byte) -87
+        CHARS[1466] = 33;
+        Arrays.fill(CHARS, 1467, 1470, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[1470] = 33;
+        CHARS[1471] = -87;
+        CHARS[1472] = 33;
+        Arrays.fill(CHARS, 1473, 1475, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[1475] = 33;
+        CHARS[1476] = -87;
+        Arrays.fill(CHARS, 1477, 1488, (byte) 33 ); // Fill 11 of value (byte) 33
+        Arrays.fill(CHARS, 1488, 1515, (byte) -19 ); // Fill 27 of value (byte) -19
+        Arrays.fill(CHARS, 1515, 1520, (byte) 33 ); // Fill 5 of value (byte) 33
+        Arrays.fill(CHARS, 1520, 1523, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 1523, 1569, (byte) 33 ); // Fill 46 of value (byte) 33
+        Arrays.fill(CHARS, 1569, 1595, (byte) -19 ); // Fill 26 of value (byte) -19
+        Arrays.fill(CHARS, 1595, 1600, (byte) 33 ); // Fill 5 of value (byte) 33
+        CHARS[1600] = -87;
+        Arrays.fill(CHARS, 1601, 1611, (byte) -19 ); // Fill 10 of value (byte) -19
+        Arrays.fill(CHARS, 1611, 1619, (byte) -87 ); // Fill 8 of value (byte) -87
+        Arrays.fill(CHARS, 1619, 1632, (byte) 33 ); // Fill 13 of value (byte) 33
+        Arrays.fill(CHARS, 1632, 1642, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 1642, 1648, (byte) 33 ); // Fill 6 of value (byte) 33
+        CHARS[1648] = -87;
+        Arrays.fill(CHARS, 1649, 1720, (byte) -19 ); // Fill 71 of value (byte) -19
+        Arrays.fill(CHARS, 1720, 1722, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1722, 1727, (byte) -19 ); // Fill 5 of value (byte) -19
+        CHARS[1727] = 33;
+        Arrays.fill(CHARS, 1728, 1743, (byte) -19 ); // Fill 15 of value (byte) -19
+        CHARS[1743] = 33;
+        Arrays.fill(CHARS, 1744, 1748, (byte) -19 ); // Fill 4 of value (byte) -19
+        CHARS[1748] = 33;
+        CHARS[1749] = -19;
+        Arrays.fill(CHARS, 1750, 1765, (byte) -87 ); // Fill 15 of value (byte) -87
+        Arrays.fill(CHARS, 1765, 1767, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 1767, 1769, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[1769] = 33;
+        Arrays.fill(CHARS, 1770, 1774, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 1774, 1776, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 1776, 1786, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 1786, 2305, (byte) 33 ); // Fill 519 of value (byte) 33
+        Arrays.fill(CHARS, 2305, 2308, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[2308] = 33;
+        Arrays.fill(CHARS, 2309, 2362, (byte) -19 ); // Fill 53 of value (byte) -19
+        Arrays.fill(CHARS, 2362, 2364, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[2364] = -87;
+        CHARS[2365] = -19;
+        Arrays.fill(CHARS, 2366, 2382, (byte) -87 ); // Fill 16 of value (byte) -87
+        Arrays.fill(CHARS, 2382, 2385, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2385, 2389, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 2389, 2392, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2392, 2402, (byte) -19 ); // Fill 10 of value (byte) -19
+        Arrays.fill(CHARS, 2402, 2404, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2404, 2406, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2406, 2416, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 2416, 2433, (byte) 33 ); // Fill 17 of value (byte) 33
+        Arrays.fill(CHARS, 2433, 2436, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[2436] = 33;
+        Arrays.fill(CHARS, 2437, 2445, (byte) -19 ); // Fill 8 of value (byte) -19
+        Arrays.fill(CHARS, 2445, 2447, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2447, 2449, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2449, 2451, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2451, 2473, (byte) -19 ); // Fill 22 of value (byte) -19
+        CHARS[2473] = 33;
+        Arrays.fill(CHARS, 2474, 2481, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[2481] = 33;
+        CHARS[2482] = -19;
+        Arrays.fill(CHARS, 2483, 2486, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2486, 2490, (byte) -19 ); // Fill 4 of value (byte) -19
+        Arrays.fill(CHARS, 2490, 2492, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[2492] = -87;
+        CHARS[2493] = 33;
+        Arrays.fill(CHARS, 2494, 2501, (byte) -87 ); // Fill 7 of value (byte) -87
+        Arrays.fill(CHARS, 2501, 2503, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2503, 2505, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2505, 2507, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2507, 2510, (byte) -87 ); // Fill 3 of value (byte) -87
+        Arrays.fill(CHARS, 2510, 2519, (byte) 33 ); // Fill 9 of value (byte) 33
+        CHARS[2519] = -87;
+        Arrays.fill(CHARS, 2520, 2524, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 2524, 2526, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2526] = 33;
+        Arrays.fill(CHARS, 2527, 2530, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 2530, 2532, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2532, 2534, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2534, 2544, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 2544, 2546, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2546, 2562, (byte) 33 ); // Fill 16 of value (byte) 33
+        CHARS[2562] = -87;
+        Arrays.fill(CHARS, 2563, 2565, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2565, 2571, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 2571, 2575, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 2575, 2577, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2577, 2579, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2579, 2601, (byte) -19 ); // Fill 22 of value (byte) -19
+        CHARS[2601] = 33;
+        Arrays.fill(CHARS, 2602, 2609, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[2609] = 33;
+        Arrays.fill(CHARS, 2610, 2612, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2612] = 33;
+        Arrays.fill(CHARS, 2613, 2615, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2615] = 33;
+        Arrays.fill(CHARS, 2616, 2618, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2618, 2620, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[2620] = -87;
+        CHARS[2621] = 33;
+        Arrays.fill(CHARS, 2622, 2627, (byte) -87 ); // Fill 5 of value (byte) -87
+        Arrays.fill(CHARS, 2627, 2631, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 2631, 2633, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2633, 2635, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2635, 2638, (byte) -87 ); // Fill 3 of value (byte) -87
+        Arrays.fill(CHARS, 2638, 2649, (byte) 33 ); // Fill 11 of value (byte) 33
+        Arrays.fill(CHARS, 2649, 2653, (byte) -19 ); // Fill 4 of value (byte) -19
+        CHARS[2653] = 33;
+        CHARS[2654] = -19;
+        Arrays.fill(CHARS, 2655, 2662, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 2662, 2674, (byte) -87 ); // Fill 12 of value (byte) -87
+        Arrays.fill(CHARS, 2674, 2677, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 2677, 2689, (byte) 33 ); // Fill 12 of value (byte) 33
+        Arrays.fill(CHARS, 2689, 2692, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[2692] = 33;
+        Arrays.fill(CHARS, 2693, 2700, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[2700] = 33;
+        CHARS[2701] = -19;
+        CHARS[2702] = 33;
+        Arrays.fill(CHARS, 2703, 2706, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[2706] = 33;
+        Arrays.fill(CHARS, 2707, 2729, (byte) -19 ); // Fill 22 of value (byte) -19
+        CHARS[2729] = 33;
+        Arrays.fill(CHARS, 2730, 2737, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[2737] = 33;
+        Arrays.fill(CHARS, 2738, 2740, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2740] = 33;
+        Arrays.fill(CHARS, 2741, 2746, (byte) -19 ); // Fill 5 of value (byte) -19
+        Arrays.fill(CHARS, 2746, 2748, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[2748] = -87;
+        CHARS[2749] = -19;
+        Arrays.fill(CHARS, 2750, 2758, (byte) -87 ); // Fill 8 of value (byte) -87
+        CHARS[2758] = 33;
+        Arrays.fill(CHARS, 2759, 2762, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[2762] = 33;
+        Arrays.fill(CHARS, 2763, 2766, (byte) -87 ); // Fill 3 of value (byte) -87
+        Arrays.fill(CHARS, 2766, 2784, (byte) 33 ); // Fill 18 of value (byte) 33
+        CHARS[2784] = -19;
+        Arrays.fill(CHARS, 2785, 2790, (byte) 33 ); // Fill 5 of value (byte) 33
+        Arrays.fill(CHARS, 2790, 2800, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 2800, 2817, (byte) 33 ); // Fill 17 of value (byte) 33
+        Arrays.fill(CHARS, 2817, 2820, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[2820] = 33;
+        Arrays.fill(CHARS, 2821, 2829, (byte) -19 ); // Fill 8 of value (byte) -19
+        Arrays.fill(CHARS, 2829, 2831, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2831, 2833, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2833, 2835, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2835, 2857, (byte) -19 ); // Fill 22 of value (byte) -19
+        CHARS[2857] = 33;
+        Arrays.fill(CHARS, 2858, 2865, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[2865] = 33;
+        Arrays.fill(CHARS, 2866, 2868, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2868, 2870, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2870, 2874, (byte) -19 ); // Fill 4 of value (byte) -19
+        Arrays.fill(CHARS, 2874, 2876, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[2876] = -87;
+        CHARS[2877] = -19;
+        Arrays.fill(CHARS, 2878, 2884, (byte) -87 ); // Fill 6 of value (byte) -87
+        Arrays.fill(CHARS, 2884, 2887, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2887, 2889, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2889, 2891, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 2891, 2894, (byte) -87 ); // Fill 3 of value (byte) -87
+        Arrays.fill(CHARS, 2894, 2902, (byte) 33 ); // Fill 8 of value (byte) 33
+        Arrays.fill(CHARS, 2902, 2904, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 2904, 2908, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 2908, 2910, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2910] = 33;
+        Arrays.fill(CHARS, 2911, 2914, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 2914, 2918, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 2918, 2928, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 2928, 2946, (byte) 33 ); // Fill 18 of value (byte) 33
+        Arrays.fill(CHARS, 2946, 2948, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[2948] = 33;
+        Arrays.fill(CHARS, 2949, 2955, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 2955, 2958, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2958, 2961, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[2961] = 33;
+        Arrays.fill(CHARS, 2962, 2966, (byte) -19 ); // Fill 4 of value (byte) -19
+        Arrays.fill(CHARS, 2966, 2969, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2969, 2971, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[2971] = 33;
+        CHARS[2972] = -19;
+        CHARS[2973] = 33;
+        Arrays.fill(CHARS, 2974, 2976, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2976, 2979, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2979, 2981, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 2981, 2984, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2984, 2987, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 2987, 2990, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 2990, 2998, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[2998] = 33;
+        Arrays.fill(CHARS, 2999, 3002, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 3002, 3006, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3006, 3011, (byte) -87 ); // Fill 5 of value (byte) -87
+        Arrays.fill(CHARS, 3011, 3014, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 3014, 3017, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[3017] = 33;
+        Arrays.fill(CHARS, 3018, 3022, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 3022, 3031, (byte) 33 ); // Fill 9 of value (byte) 33
+        CHARS[3031] = -87;
+        Arrays.fill(CHARS, 3032, 3047, (byte) 33 ); // Fill 15 of value (byte) 33
+        Arrays.fill(CHARS, 3047, 3056, (byte) -87 ); // Fill 9 of value (byte) -87
+        Arrays.fill(CHARS, 3056, 3073, (byte) 33 ); // Fill 17 of value (byte) 33
+        Arrays.fill(CHARS, 3073, 3076, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[3076] = 33;
+        Arrays.fill(CHARS, 3077, 3085, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[3085] = 33;
+        Arrays.fill(CHARS, 3086, 3089, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[3089] = 33;
+        Arrays.fill(CHARS, 3090, 3113, (byte) -19 ); // Fill 23 of value (byte) -19
+        CHARS[3113] = 33;
+        Arrays.fill(CHARS, 3114, 3124, (byte) -19 ); // Fill 10 of value (byte) -19
+        CHARS[3124] = 33;
+        Arrays.fill(CHARS, 3125, 3130, (byte) -19 ); // Fill 5 of value (byte) -19
+        Arrays.fill(CHARS, 3130, 3134, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3134, 3141, (byte) -87 ); // Fill 7 of value (byte) -87
+        CHARS[3141] = 33;
+        Arrays.fill(CHARS, 3142, 3145, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[3145] = 33;
+        Arrays.fill(CHARS, 3146, 3150, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 3150, 3157, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 3157, 3159, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 3159, 3168, (byte) 33 ); // Fill 9 of value (byte) 33
+        Arrays.fill(CHARS, 3168, 3170, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 3170, 3174, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3174, 3184, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3184, 3202, (byte) 33 ); // Fill 18 of value (byte) 33
+        Arrays.fill(CHARS, 3202, 3204, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[3204] = 33;
+        Arrays.fill(CHARS, 3205, 3213, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[3213] = 33;
+        Arrays.fill(CHARS, 3214, 3217, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[3217] = 33;
+        Arrays.fill(CHARS, 3218, 3241, (byte) -19 ); // Fill 23 of value (byte) -19
+        CHARS[3241] = 33;
+        Arrays.fill(CHARS, 3242, 3252, (byte) -19 ); // Fill 10 of value (byte) -19
+        CHARS[3252] = 33;
+        Arrays.fill(CHARS, 3253, 3258, (byte) -19 ); // Fill 5 of value (byte) -19
+        Arrays.fill(CHARS, 3258, 3262, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3262, 3269, (byte) -87 ); // Fill 7 of value (byte) -87
+        CHARS[3269] = 33;
+        Arrays.fill(CHARS, 3270, 3273, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[3273] = 33;
+        Arrays.fill(CHARS, 3274, 3278, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 3278, 3285, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 3285, 3287, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 3287, 3294, (byte) 33 ); // Fill 7 of value (byte) 33
+        CHARS[3294] = -19;
+        CHARS[3295] = 33;
+        Arrays.fill(CHARS, 3296, 3298, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 3298, 3302, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3302, 3312, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3312, 3330, (byte) 33 ); // Fill 18 of value (byte) 33
+        Arrays.fill(CHARS, 3330, 3332, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[3332] = 33;
+        Arrays.fill(CHARS, 3333, 3341, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[3341] = 33;
+        Arrays.fill(CHARS, 3342, 3345, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[3345] = 33;
+        Arrays.fill(CHARS, 3346, 3369, (byte) -19 ); // Fill 23 of value (byte) -19
+        CHARS[3369] = 33;
+        Arrays.fill(CHARS, 3370, 3386, (byte) -19 ); // Fill 16 of value (byte) -19
+        Arrays.fill(CHARS, 3386, 3390, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3390, 3396, (byte) -87 ); // Fill 6 of value (byte) -87
+        Arrays.fill(CHARS, 3396, 3398, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 3398, 3401, (byte) -87 ); // Fill 3 of value (byte) -87
+        CHARS[3401] = 33;
+        Arrays.fill(CHARS, 3402, 3406, (byte) -87 ); // Fill 4 of value (byte) -87
+        Arrays.fill(CHARS, 3406, 3415, (byte) 33 ); // Fill 9 of value (byte) 33
+        CHARS[3415] = -87;
+        Arrays.fill(CHARS, 3416, 3424, (byte) 33 ); // Fill 8 of value (byte) 33
+        Arrays.fill(CHARS, 3424, 3426, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 3426, 3430, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3430, 3440, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3440, 3585, (byte) 33 ); // Fill 145 of value (byte) 33
+        Arrays.fill(CHARS, 3585, 3631, (byte) -19 ); // Fill 46 of value (byte) -19
+        CHARS[3631] = 33;
+        CHARS[3632] = -19;
+        CHARS[3633] = -87;
+        Arrays.fill(CHARS, 3634, 3636, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 3636, 3643, (byte) -87 ); // Fill 7 of value (byte) -87
+        Arrays.fill(CHARS, 3643, 3648, (byte) 33 ); // Fill 5 of value (byte) 33
+        Arrays.fill(CHARS, 3648, 3654, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 3654, 3663, (byte) -87 ); // Fill 9 of value (byte) -87
+        CHARS[3663] = 33;
+        Arrays.fill(CHARS, 3664, 3674, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3674, 3713, (byte) 33 ); // Fill 39 of value (byte) 33
+        Arrays.fill(CHARS, 3713, 3715, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[3715] = 33;
+        CHARS[3716] = -19;
+        Arrays.fill(CHARS, 3717, 3719, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 3719, 3721, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[3721] = 33;
+        CHARS[3722] = -19;
+        Arrays.fill(CHARS, 3723, 3725, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[3725] = -19;
+        Arrays.fill(CHARS, 3726, 3732, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(CHARS, 3732, 3736, (byte) -19 ); // Fill 4 of value (byte) -19
+        CHARS[3736] = 33;
+        Arrays.fill(CHARS, 3737, 3744, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[3744] = 33;
+        Arrays.fill(CHARS, 3745, 3748, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[3748] = 33;
+        CHARS[3749] = -19;
+        CHARS[3750] = 33;
+        CHARS[3751] = -19;
+        Arrays.fill(CHARS, 3752, 3754, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 3754, 3756, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[3756] = 33;
+        Arrays.fill(CHARS, 3757, 3759, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[3759] = 33;
+        CHARS[3760] = -19;
+        CHARS[3761] = -87;
+        Arrays.fill(CHARS, 3762, 3764, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 3764, 3770, (byte) -87 ); // Fill 6 of value (byte) -87
+        CHARS[3770] = 33;
+        Arrays.fill(CHARS, 3771, 3773, (byte) -87 ); // Fill 2 of value (byte) -87
+        CHARS[3773] = -19;
+        Arrays.fill(CHARS, 3774, 3776, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 3776, 3781, (byte) -19 ); // Fill 5 of value (byte) -19
+        CHARS[3781] = 33;
+        CHARS[3782] = -87;
+        CHARS[3783] = 33;
+        Arrays.fill(CHARS, 3784, 3790, (byte) -87 ); // Fill 6 of value (byte) -87
+        Arrays.fill(CHARS, 3790, 3792, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 3792, 3802, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3802, 3864, (byte) 33 ); // Fill 62 of value (byte) 33
+        Arrays.fill(CHARS, 3864, 3866, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 3866, 3872, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(CHARS, 3872, 3882, (byte) -87 ); // Fill 10 of value (byte) -87
+        Arrays.fill(CHARS, 3882, 3893, (byte) 33 ); // Fill 11 of value (byte) 33
+        CHARS[3893] = -87;
+        CHARS[3894] = 33;
+        CHARS[3895] = -87;
+        CHARS[3896] = 33;
+        CHARS[3897] = -87;
+        Arrays.fill(CHARS, 3898, 3902, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3902, 3904, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 3904, 3912, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[3912] = 33;
+        Arrays.fill(CHARS, 3913, 3946, (byte) -19 ); // Fill 33 of value (byte) -19
+        Arrays.fill(CHARS, 3946, 3953, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 3953, 3973, (byte) -87 ); // Fill 20 of value (byte) -87
+        CHARS[3973] = 33;
+        Arrays.fill(CHARS, 3974, 3980, (byte) -87 ); // Fill 6 of value (byte) -87
+        Arrays.fill(CHARS, 3980, 3984, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 3984, 3990, (byte) -87 ); // Fill 6 of value (byte) -87
+        CHARS[3990] = 33;
+        CHARS[3991] = -87;
+        CHARS[3992] = 33;
+        Arrays.fill(CHARS, 3993, 4014, (byte) -87 ); // Fill 21 of value (byte) -87
+        Arrays.fill(CHARS, 4014, 4017, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 4017, 4024, (byte) -87 ); // Fill 7 of value (byte) -87
+        CHARS[4024] = 33;
+        CHARS[4025] = -87;
+        Arrays.fill(CHARS, 4026, 4256, (byte) 33 ); // Fill 230 of value (byte) 33
+        Arrays.fill(CHARS, 4256, 4294, (byte) -19 ); // Fill 38 of value (byte) -19
+        Arrays.fill(CHARS, 4294, 4304, (byte) 33 ); // Fill 10 of value (byte) 33
+        Arrays.fill(CHARS, 4304, 4343, (byte) -19 ); // Fill 39 of value (byte) -19
+        Arrays.fill(CHARS, 4343, 4352, (byte) 33 ); // Fill 9 of value (byte) 33
+        CHARS[4352] = -19;
+        CHARS[4353] = 33;
+        Arrays.fill(CHARS, 4354, 4356, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[4356] = 33;
+        Arrays.fill(CHARS, 4357, 4360, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[4360] = 33;
+        CHARS[4361] = -19;
+        CHARS[4362] = 33;
+        Arrays.fill(CHARS, 4363, 4365, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[4365] = 33;
+        Arrays.fill(CHARS, 4366, 4371, (byte) -19 ); // Fill 5 of value (byte) -19
+        Arrays.fill(CHARS, 4371, 4412, (byte) 33 ); // Fill 41 of value (byte) 33
+        CHARS[4412] = -19;
+        CHARS[4413] = 33;
+        CHARS[4414] = -19;
+        CHARS[4415] = 33;
+        CHARS[4416] = -19;
+        Arrays.fill(CHARS, 4417, 4428, (byte) 33 ); // Fill 11 of value (byte) 33
+        CHARS[4428] = -19;
+        CHARS[4429] = 33;
+        CHARS[4430] = -19;
+        CHARS[4431] = 33;
+        CHARS[4432] = -19;
+        Arrays.fill(CHARS, 4433, 4436, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 4436, 4438, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 4438, 4441, (byte) 33 ); // Fill 3 of value (byte) 33
+        CHARS[4441] = -19;
+        Arrays.fill(CHARS, 4442, 4447, (byte) 33 ); // Fill 5 of value (byte) 33
+        Arrays.fill(CHARS, 4447, 4450, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[4450] = 33;
+        CHARS[4451] = -19;
+        CHARS[4452] = 33;
+        CHARS[4453] = -19;
+        CHARS[4454] = 33;
+        CHARS[4455] = -19;
+        CHARS[4456] = 33;
+        CHARS[4457] = -19;
+        Arrays.fill(CHARS, 4458, 4461, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 4461, 4463, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 4463, 4466, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 4466, 4468, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[4468] = 33;
+        CHARS[4469] = -19;
+        Arrays.fill(CHARS, 4470, 4510, (byte) 33 ); // Fill 40 of value (byte) 33
+        CHARS[4510] = -19;
+        Arrays.fill(CHARS, 4511, 4520, (byte) 33 ); // Fill 9 of value (byte) 33
+        CHARS[4520] = -19;
+        Arrays.fill(CHARS, 4521, 4523, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[4523] = -19;
+        Arrays.fill(CHARS, 4524, 4526, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 4526, 4528, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 4528, 4535, (byte) 33 ); // Fill 7 of value (byte) 33
+        Arrays.fill(CHARS, 4535, 4537, (byte) -19 ); // Fill 2 of value (byte) -19
+        CHARS[4537] = 33;
+        CHARS[4538] = -19;
+        CHARS[4539] = 33;
+        Arrays.fill(CHARS, 4540, 4547, (byte) -19 ); // Fill 7 of value (byte) -19
+        Arrays.fill(CHARS, 4547, 4587, (byte) 33 ); // Fill 40 of value (byte) 33
+        CHARS[4587] = -19;
+        Arrays.fill(CHARS, 4588, 4592, (byte) 33 ); // Fill 4 of value (byte) 33
+        CHARS[4592] = -19;
+        Arrays.fill(CHARS, 4593, 4601, (byte) 33 ); // Fill 8 of value (byte) 33
+        CHARS[4601] = -19;
+        Arrays.fill(CHARS, 4602, 7680, (byte) 33 ); // Fill 3078 of value (byte) 33
+        Arrays.fill(CHARS, 7680, 7836, (byte) -19 ); // Fill 156 of value (byte) -19
+        Arrays.fill(CHARS, 7836, 7840, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 7840, 7930, (byte) -19 ); // Fill 90 of value (byte) -19
+        Arrays.fill(CHARS, 7930, 7936, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(CHARS, 7936, 7958, (byte) -19 ); // Fill 22 of value (byte) -19
+        Arrays.fill(CHARS, 7958, 7960, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 7960, 7966, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 7966, 7968, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 7968, 8006, (byte) -19 ); // Fill 38 of value (byte) -19
+        Arrays.fill(CHARS, 8006, 8008, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 8008, 8014, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 8014, 8016, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 8016, 8024, (byte) -19 ); // Fill 8 of value (byte) -19
+        CHARS[8024] = 33;
+        CHARS[8025] = -19;
+        CHARS[8026] = 33;
+        CHARS[8027] = -19;
+        CHARS[8028] = 33;
+        CHARS[8029] = -19;
+        CHARS[8030] = 33;
+        Arrays.fill(CHARS, 8031, 8062, (byte) -19 ); // Fill 31 of value (byte) -19
+        Arrays.fill(CHARS, 8062, 8064, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 8064, 8117, (byte) -19 ); // Fill 53 of value (byte) -19
+        CHARS[8117] = 33;
+        Arrays.fill(CHARS, 8118, 8125, (byte) -19 ); // Fill 7 of value (byte) -19
+        CHARS[8125] = 33;
+        CHARS[8126] = -19;
+        Arrays.fill(CHARS, 8127, 8130, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 8130, 8133, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[8133] = 33;
+        Arrays.fill(CHARS, 8134, 8141, (byte) -19 ); // Fill 7 of value (byte) -19
+        Arrays.fill(CHARS, 8141, 8144, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 8144, 8148, (byte) -19 ); // Fill 4 of value (byte) -19
+        Arrays.fill(CHARS, 8148, 8150, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 8150, 8156, (byte) -19 ); // Fill 6 of value (byte) -19
+        Arrays.fill(CHARS, 8156, 8160, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 8160, 8173, (byte) -19 ); // Fill 13 of value (byte) -19
+        Arrays.fill(CHARS, 8173, 8178, (byte) 33 ); // Fill 5 of value (byte) 33
+        Arrays.fill(CHARS, 8178, 8181, (byte) -19 ); // Fill 3 of value (byte) -19
+        CHARS[8181] = 33;
+        Arrays.fill(CHARS, 8182, 8189, (byte) -19 ); // Fill 7 of value (byte) -19
+        Arrays.fill(CHARS, 8189, 8400, (byte) 33 ); // Fill 211 of value (byte) 33
+        Arrays.fill(CHARS, 8400, 8413, (byte) -87 ); // Fill 13 of value (byte) -87
+        Arrays.fill(CHARS, 8413, 8417, (byte) 33 ); // Fill 4 of value (byte) 33
+        CHARS[8417] = -87;
+        Arrays.fill(CHARS, 8418, 8486, (byte) 33 ); // Fill 68 of value (byte) 33
+        CHARS[8486] = -19;
+        Arrays.fill(CHARS, 8487, 8490, (byte) 33 ); // Fill 3 of value (byte) 33
+        Arrays.fill(CHARS, 8490, 8492, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(CHARS, 8492, 8494, (byte) 33 ); // Fill 2 of value (byte) 33
+        CHARS[8494] = -19;
+        Arrays.fill(CHARS, 8495, 8576, (byte) 33 ); // Fill 81 of value (byte) 33
+        Arrays.fill(CHARS, 8576, 8579, (byte) -19 ); // Fill 3 of value (byte) -19
+        Arrays.fill(CHARS, 8579, 12293, (byte) 33 ); // Fill 3714 of value (byte) 33
+        CHARS[12293] = -87;
+        CHARS[12294] = 33;
+        CHARS[12295] = -19;
+        Arrays.fill(CHARS, 12296, 12321, (byte) 33 ); // Fill 25 of value (byte) 33
+        Arrays.fill(CHARS, 12321, 12330, (byte) -19 ); // Fill 9 of value (byte) -19
+        Arrays.fill(CHARS, 12330, 12336, (byte) -87 ); // Fill 6 of value (byte) -87
+        CHARS[12336] = 33;
+        Arrays.fill(CHARS, 12337, 12342, (byte) -87 ); // Fill 5 of value (byte) -87
+        Arrays.fill(CHARS, 12342, 12353, (byte) 33 ); // Fill 11 of value (byte) 33
+        Arrays.fill(CHARS, 12353, 12437, (byte) -19 ); // Fill 84 of value (byte) -19
+        Arrays.fill(CHARS, 12437, 12441, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(CHARS, 12441, 12443, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 12443, 12445, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 12445, 12447, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(CHARS, 12447, 12449, (byte) 33 ); // Fill 2 of value (byte) 33
+        Arrays.fill(CHARS, 12449, 12539, (byte) -19 ); // Fill 90 of value (byte) -19
+        CHARS[12539] = 33;
+        Arrays.fill(CHARS, 12540, 12543, (byte) -87 ); // Fill 3 of value (byte) -87
+        Arrays.fill(CHARS, 12543, 12549, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(CHARS, 12549, 12589, (byte) -19 ); // Fill 40 of value (byte) -19
+        Arrays.fill(CHARS, 12589, 19968, (byte) 33 ); // Fill 7379 of value (byte) 33
+        Arrays.fill(CHARS, 19968, 40870, (byte) -19 ); // Fill 20902 of value (byte) -19
+        Arrays.fill(CHARS, 40870, 44032, (byte) 33 ); // Fill 3162 of value (byte) 33
+        Arrays.fill(CHARS, 44032, 55204, (byte) -19 ); // Fill 11172 of value (byte) -19
+        Arrays.fill(CHARS, 55204, 55296, (byte) 33 ); // Fill 92 of value (byte) 33
+        Arrays.fill(CHARS, 57344, 65534, (byte) 33 ); // Fill 8190 of value (byte) 33
+
+    } // <clinit>()
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Returns true if the specified character is a supplemental character.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isSupplemental(int c) {
+        return (c >= 0x10000 && c <= 0x10FFFF);
+    }
+
+    /**
+     * Returns true the supplemental character corresponding to the given
+     * surrogates.
+     *
+     * @param h The high surrogate.
+     * @param l The low surrogate.
+     */
+    public static int supplemental(char h, char l) {
+        return (h - 0xD800) * 0x400 + (l - 0xDC00) + 0x10000;
+    }
+
+    /**
+     * Returns the high surrogate of a supplemental character
+     *
+     * @param c The supplemental character to "split".
+     */
+    public static char highSurrogate(int c) {
+        return (char) (((c - 0x00010000) >> 10) + 0xD800);
+    }
+
+    /**
+     * Returns the low surrogate of a supplemental character
+     *
+     * @param c The supplemental character to "split".
+     */
+    public static char lowSurrogate(int c) {
+        return (char) (((c - 0x00010000) & 0x3FF) + 0xDC00);
+    }
+
+    /**
+     * Returns whether the given character is a high surrogate
+     *
+     * @param c The character to check.
+     */
+    public static boolean isHighSurrogate(int c) {
+        return (0xD800 <= c && c <= 0xDBFF);
+    }
+
+    /**
+     * Returns whether the given character is a low surrogate
+     *
+     * @param c The character to check.
+     */
+    public static boolean isLowSurrogate(int c) {
+        return (0xDC00 <= c && c <= 0xDFFF);
+    }
+
+
+    /**
+     * Returns true if the specified character is valid. This method
+     * also checks the surrogate character range from 0x10000 to 0x10FFFF.
+     * <p>
+     * If the program chooses to apply the mask directly to the
+     * <code>CHARS</code> array, then they are responsible for checking
+     * the surrogate character range.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isValid(int c) {
+        return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isValid(int):boolean
+
+    /**
+     * Returns true if the specified character is invalid.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isInvalid(int c) {
+        return !isValid(c);
+    } // isInvalid(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered content.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isContent(int c) {
+        return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isContent(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered markup.
+     * Markup characters include '&lt;', '&amp;', and '%'.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isMarkup(int c) {
+        return c == '<' || c == '&' || c == '%';
+    } // isMarkup(int):boolean
+
+    /**
+     * Returns true if the specified character is a space character
+     * as defined by production [3] in the XML 1.0 specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isSpace(int c) {
+        return c <= 0x20 && (CHARS[c] & MASK_SPACE) != 0;
+    } // isSpace(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name start
+     * character as defined by production [5] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNameStart(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NAME_START) != 0;
+    } // isNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name
+     * character as defined by production [4] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isName(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NAME) != 0;
+    } // isName(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName start
+     * character as defined by production [4] in Namespaces in XML
+     * recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNCNameStart(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NCNAME_START) != 0;
+    } // isNCNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName
+     * character as defined by production [5] in Namespaces in XML
+     * recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNCName(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NCNAME) != 0;
+    } // isNCName(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid Pubid
+     * character as defined by production [13] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isPubid(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_PUBID) != 0;
+    } // isPubid(int):boolean
+
+    /*
+     * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+     */
+    /**
+     * Check to see if a string is a valid Name according to [5]
+     * in the XML 1.0 Recommendation
+     *
+     * @param name string to check
+     * @return true if name is a valid Name
+     */
+    public static boolean isValidName(String name) {
+        if (name.length() == 0)
+            return false;
+        char ch = name.charAt(0);
+        if( isNameStart(ch) == false)
+           return false;
+        for (int i = 1; i < name.length(); i++ ) {
+           ch = name.charAt(i);
+           if( isName( ch ) == false ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidName(String):boolean
+    
+
+    /*
+     * from the namespace rec
+     * [4] NCName ::= (Letter | '_') (NCNameChar)*
+     */
+    /**
+     * Check to see if a string is a valid NCName according to [4]
+     * from the XML Namespaces 1.0 Recommendation
+     *
+     * @param ncName string to check
+     * @return true if name is a valid NCName
+     */
+    public static boolean isValidNCName(String ncName) {
+        if (ncName.length() == 0)
+            return false;
+        char ch = ncName.charAt(0);
+        if( isNCNameStart(ch) == false)
+           return false;
+        for (int i = 1; i < ncName.length(); i++ ) {
+           ch = ncName.charAt(i);
+           if( isNCName( ch ) == false ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidNCName(String):boolean
+
+    /*
+     * [7] Nmtoken ::= (NameChar)+
+     */
+    /**
+     * Check to see if a string is a valid Nmtoken according to [7]
+     * in the XML 1.0 Recommendation
+     *
+     * @param nmtoken string to check
+     * @return true if nmtoken is a valid Nmtoken 
+     */
+    public static boolean isValidNmtoken(String nmtoken) {
+        if (nmtoken.length() == 0)
+            return false;
+        for (int i = 0; i < nmtoken.length(); i++ ) {
+           char ch = nmtoken.charAt(i);
+           if(  ! isName( ch ) ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidName(String):boolean
+
+
+
+
+
+    // encodings
+
+    /**
+     * Returns true if the encoding name is a valid IANA encoding.
+     * This method does not verify that there is a decoder available
+     * for this encoding, only that the characters are valid for an
+     * IANA encoding name.
+     *
+     * @param ianaEncoding The IANA encoding name.
+     */
+    public static boolean isValidIANAEncoding(String ianaEncoding) {
+        if (ianaEncoding != null) {
+            int length = ianaEncoding.length();
+            if (length > 0) {
+                char c = ianaEncoding.charAt(0);
+                if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+                    for (int i = 1; i < length; i++) {
+                        c = ianaEncoding.charAt(i);
+                        if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+                            (c < '0' || c > '9') && c != '.' && c != '_' &&
+                            c != '-') {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    } // isValidIANAEncoding(String):boolean
+
+    /**
+     * Returns true if the encoding name is a valid Java encoding.
+     * This method does not verify that there is a decoder available
+     * for this encoding, only that the characters are valid for an
+     * Java encoding name.
+     *
+     * @param javaEncoding The Java encoding name.
+     */
+    public static boolean isValidJavaEncoding(String javaEncoding) {
+        if (javaEncoding != null) {
+            int length = javaEncoding.length();
+            if (length > 0) {
+                for (int i = 1; i < length; i++) {
+                    char c = javaEncoding.charAt(i);
+                    if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+                        (c < '0' || c > '9') && c != '.' && c != '_' &&
+                        c != '-') {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    } // isValidIANAEncoding(String):boolean
+
+
+} // class XMLChar
diff --git a/src/main/java/org/apache/xml/utils/AttList.java b/src/main/java/org/apache/xml/utils/AttList.java
new file mode 100644
index 0000000..7d40f0d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/AttList.java
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AttList.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import org.xml.sax.Attributes;
+
+/**
+ * Wraps a DOM attribute list in a SAX Attributes.
+ * @xsl.usage internal
+ */
+public class AttList implements Attributes
+{
+
+  /** List of attribute nodes          */
+  NamedNodeMap m_attrs;
+
+  /** Index of last attribute node          */
+  int m_lastIndex;
+
+  // ARGHH!!  JAXP Uses Xerces without setting the namespace processing to ON!
+  // DOM2Helper m_dh = new DOM2Helper();
+
+  /** Local reference to DOMHelper          */
+  DOMHelper m_dh;
+
+//  /**
+//   * Constructor AttList
+//   *
+//   *
+//   * @param attrs List of attributes this will contain
+//   */
+//  public AttList(NamedNodeMap attrs)
+//  {
+//
+//    m_attrs = attrs;
+//    m_lastIndex = m_attrs.getLength() - 1;
+//    m_dh = new DOM2Helper();
+//  }
+
+  /**
+   * Constructor AttList
+   *
+   *
+   * @param attrs List of attributes this will contain
+   * @param dh DOMHelper 
+   */
+  public AttList(NamedNodeMap attrs, DOMHelper dh)
+  {
+
+    m_attrs = attrs;
+    m_lastIndex = m_attrs.getLength() - 1;
+    m_dh = dh;
+  }
+
+  /**
+   * Get the number of attribute nodes in the list 
+   *
+   *
+   * @return number of attribute nodes
+   */
+  public int getLength()
+  {
+    return m_attrs.getLength();
+  }
+
+  /**
+   * Look up an attribute's Namespace URI by index.
+   *
+   * @param index The attribute index (zero-based).
+   * @return The Namespace URI, or the empty string if none
+   *         is available, or null if the index is out of
+   *         range.
+   */
+  public String getURI(int index)
+  {
+    String ns = m_dh.getNamespaceOfNode(((Attr) m_attrs.item(index)));
+    if(null == ns)
+      ns = "";
+    return ns;
+  }
+
+  /**
+   * Look up an attribute's local name by index.
+   *
+   * @param index The attribute index (zero-based).
+   * @return The local name, or the empty string if Namespace
+   *         processing is not being performed, or null
+   *         if the index is out of range.
+   */
+  public String getLocalName(int index)
+  {
+    return m_dh.getLocalNameOfNode(((Attr) m_attrs.item(index)));
+  }
+
+  /**
+   * Look up an attribute's qualified name by index.
+   *
+   *
+   * @param i The attribute index (zero-based).
+   *
+   * @return The attribute's qualified name
+   */
+  public String getQName(int i)
+  {
+    return ((Attr) m_attrs.item(i)).getName();
+  }
+
+  /**
+   * Get the attribute's node type by index
+   *
+   *
+   * @param i The attribute index (zero-based)
+   *
+   * @return the attribute's node type
+   */
+  public String getType(int i)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Get the attribute's node value by index
+   *
+   *
+   * @param i The attribute index (zero-based)
+   *
+   * @return the attribute's node value
+   */
+  public String getValue(int i)
+  {
+    return ((Attr) m_attrs.item(i)).getValue();
+  }
+
+  /**
+   * Get the attribute's node type by name
+   *
+   *
+   * @param name Attribute name
+   *
+   * @return the attribute's node type
+   */
+  public String getType(String name)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Look up an attribute's type by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty String if the
+   *        name has no Namespace URI.
+   * @param localName The local name of the attribute.
+   * @return The attribute type as a string, or null if the
+   *         attribute is not in the list or if Namespace
+   *         processing is not being performed.
+   */
+  public String getType(String uri, String localName)
+  {
+    return "CDATA";  // for the moment
+  }
+
+  /**
+   * Look up an attribute's value by name.
+   *
+   *
+   * @param name The attribute node's name
+   *
+   * @return The attribute node's value
+   */
+  public String getValue(String name)
+  {
+    Attr attr = ((Attr) m_attrs.getNamedItem(name));
+    return (null != attr) 
+          ? attr.getValue() : null;
+  }
+
+  /**
+   * Look up an attribute's value by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty String if the
+   *        name has no Namespace URI.
+   * @param localName The local name of the attribute.
+   * @return The attribute value as a string, or null if the
+   *         attribute is not in the list.
+   */
+  public String getValue(String uri, String localName)
+  {
+		Node a=m_attrs.getNamedItemNS(uri,localName);
+		return (a==null) ? null : a.getNodeValue();
+  }
+
+  /**
+   * Look up the index of an attribute by Namespace name.
+   *
+   * @param uri The Namespace URI, or the empty string if
+   *        the name has no Namespace URI.
+   * @param localPart The attribute's local name.
+   * @return The index of the attribute, or -1 if it does not
+   *         appear in the list.
+   */
+  public int getIndex(String uri, String localPart)
+  {
+    for(int i=m_attrs.getLength()-1;i>=0;--i)
+    {
+      Node a=m_attrs.item(i);
+      String u=a.getNamespaceURI();
+      if( (u==null ? uri==null : u.equals(uri))
+	  &&
+	  a.getLocalName().equals(localPart) )
+	return i;
+    }
+    return -1;
+  }
+
+  /**
+   * Look up the index of an attribute by raw XML 1.0 name.
+   *
+   * @param qName The qualified (prefixed) name.
+   * @return The index of the attribute, or -1 if it does not
+   *         appear in the list.
+   */
+  public int getIndex(String qName)
+  {
+    for(int i=m_attrs.getLength()-1;i>=0;--i)
+    {
+      Node a=m_attrs.item(i);
+      if(a.getNodeName().equals(qName) )
+	return i;
+    }
+    return -1;
+  }
+}
+
diff --git a/src/main/java/org/apache/xml/utils/BoolStack.java b/src/main/java/org/apache/xml/utils/BoolStack.java
new file mode 100644
index 0000000..aadb10d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/BoolStack.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: BoolStack.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+
+/**
+ * Simple stack for boolean values.
+ * @xsl.usage internal
+ */
+public final class BoolStack implements Cloneable
+{
+
+  /** Array of boolean values          */
+  private boolean m_values[];
+
+  /** Array size allocated           */
+  private int m_allocatedSize;
+
+  /** Index into the array of booleans          */
+  private int m_index;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public BoolStack()
+  {
+    this(32);
+  }
+
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param size array size to allocate
+   */
+  public BoolStack(int size)
+  {
+
+    m_allocatedSize = size;
+    m_values = new boolean[size];
+    m_index = -1;
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return Current length of the list
+   */
+  public final int size()
+  {
+    return m_index + 1;
+  }
+
+  /**
+   * Clears the stack.
+   *
+   */
+  public final void clear()
+  {
+  	m_index = -1;
+  }
+
+  /**
+   * Pushes an item onto the top of this stack.
+   *
+   *
+   * @param val the boolean to be pushed onto this stack.
+   * @return  the <code>item</code> argument.
+   */
+  public final boolean push(boolean val)
+  {
+
+    if (m_index == m_allocatedSize - 1)
+      grow();
+
+    return (m_values[++m_index] = val);
+  }
+
+  /**
+   * Removes the object at the top of this stack and returns that
+   * object as the value of this function.
+   *
+   * @return     The object at the top of this stack.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public final boolean pop()
+  {
+    return m_values[m_index--];
+  }
+
+  /**
+   * Removes the object at the top of this stack and returns the
+   * next object at the top as the value of this function.
+   *
+   *
+   * @return Next object to the top or false if none there
+   */
+  public final boolean popAndTop()
+  {
+
+    m_index--;
+
+    return (m_index >= 0) ? m_values[m_index] : false;
+  }
+
+  /**
+   * Set the item at the top of this stack  
+   *
+   *
+   * @param b Object to set at the top of this stack
+   */
+  public final void setTop(boolean b)
+  {
+    m_values[m_index] = b;
+  }
+
+  /**
+   * Looks at the object at the top of this stack without removing it
+   * from the stack.
+   *
+   * @return     the object at the top of this stack.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public final boolean peek()
+  {
+    return m_values[m_index];
+  }
+
+  /**
+   * Looks at the object at the top of this stack without removing it
+   * from the stack.  If the stack is empty, it returns false.
+   *
+   * @return     the object at the top of this stack.
+   */
+  public final boolean peekOrFalse()
+  {
+    return (m_index > -1) ? m_values[m_index] : false;
+  }
+
+  /**
+   * Looks at the object at the top of this stack without removing it
+   * from the stack.  If the stack is empty, it returns true.
+   *
+   * @return     the object at the top of this stack.
+   */
+  public final boolean peekOrTrue()
+  {
+    return (m_index > -1) ? m_values[m_index] : true;
+  }
+
+  /**
+   * Tests if this stack is empty.
+   *
+   * @return  <code>true</code> if this stack is empty;
+   *          <code>false</code> otherwise.
+   */
+  public boolean isEmpty()
+  {
+    return (m_index == -1);
+  }
+
+  /**
+   * Grows the size of the stack
+   *
+   */
+  private void grow()
+  {
+
+    m_allocatedSize *= 2;
+
+    boolean newVector[] = new boolean[m_allocatedSize];
+
+    System.arraycopy(m_values, 0, newVector, 0, m_index + 1);
+
+    m_values = newVector;
+  }
+  
+  public Object clone() 
+    throws CloneNotSupportedException
+  {
+    return super.clone();
+  }
+
+}
diff --git a/src/main/java/org/apache/xml/utils/Constants.java b/src/main/java/org/apache/xml/utils/Constants.java
new file mode 100644
index 0000000..435f9ab
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/Constants.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Constants.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * Primary constants used by the XSLT Processor
+ * @xsl.usage advanced
+ */
+public class Constants
+{
+
+  /** 
+   * Mnemonics for standard XML Namespace URIs, as Java Strings:
+   * <ul>
+   * <li>S_XMLNAMESPACEURI (http://www.w3.org/XML/1998/namespace) is the
+   * URI permanantly assigned to the "xml:" prefix. This is used for some
+   * features built into the XML specification itself, such as xml:space 
+   * and xml:lang. It was defined by the W3C's XML Namespaces spec.</li>
+   * <li>S_XSLNAMESPACEURL (http://www.w3.org/1999/XSL/Transform) is the
+   * URI which indicates that a name may be an XSLT directive. In most
+   * XSLT stylesheets, this is bound to the "xsl:" prefix. It's defined
+   * by the W3C's XSLT Recommendation.</li>
+   * <li>S_OLDXSLNAMESPACEURL (http://www.w3.org/XSL/Transform/1.0) was
+   * used in early prototypes of XSLT processors for much the same purpose
+   * as S_XSLNAMESPACEURL. It is now considered obsolete, and the version
+   * of XSLT which it signified is not fully compatable with the final
+   * XSLT Recommendation, so what it really signifies is a badly obsolete
+   * stylesheet.</li>
+   * </ul> */
+  public static final String 
+	S_XMLNAMESPACEURI = "http://www.w3.org/XML/1998/namespace", 
+	S_XSLNAMESPACEURL = "http://www.w3.org/1999/XSL/Transform", 
+	S_OLDXSLNAMESPACEURL = "http://www.w3.org/XSL/Transform/1.0";
+
+  /** Authorship mnemonics, as Java Strings. Not standardized, 
+   * as far as I know.
+   * <ul>
+   * <li>S_VENDOR -- the name of the organization/individual who published
+   * this XSLT processor. </li>
+   * <li>S_VENDORURL -- URL where one can attempt to retrieve more
+   * information about this publisher and product.</li>
+   * </ul>
+   */
+  public static final String 
+	S_VENDOR = "Apache Software Foundation", 
+	S_VENDORURL = "http://xml.apache.org";
+
+  /** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace 
+   *(http://xml.apache.org/xalan) predefined to signify Xalan's
+   * built-in XSLT Extensions. When used in stylesheets, this is often 
+   * bound to the "xalan:" prefix.
+   */
+  public static final String 
+    S_BUILTIN_EXTENSIONS_URL = "http://xml.apache.org/xalan"; 
+
+  /**
+   * The old built-in extension url. It is still supported for
+   * backward compatibility.
+   */
+  public static final String 
+    S_BUILTIN_OLD_EXTENSIONS_URL = "http://xml.apache.org/xslt"; 
+  
+  /**
+   * Xalan extension namespaces.
+   */
+  public static final String 
+    // The old namespace for Java extension
+    S_EXTENSIONS_OLD_JAVA_URL = "http://xml.apache.org/xslt/java",
+    // The new namespace for Java extension
+    S_EXTENSIONS_JAVA_URL = "http://xml.apache.org/xalan/java",
+    S_EXTENSIONS_LOTUSXSL_JAVA_URL = "http://xsl.lotus.com/java",
+    S_EXTENSIONS_XALANLIB_URL = "http://xml.apache.org/xalan",
+    S_EXTENSIONS_REDIRECT_URL = "http://xml.apache.org/xalan/redirect",
+    S_EXTENSIONS_PIPE_URL = "http://xml.apache.org/xalan/PipeDocument",
+    S_EXTENSIONS_SQL_URL = "http://xml.apache.org/xalan/sql";
+  
+  /**
+   * EXSLT extension namespaces.
+   */
+  public static final String
+    S_EXSLT_COMMON_URL = "http://exslt.org/common",
+    S_EXSLT_MATH_URL = "http://exslt.org/math",
+    S_EXSLT_SETS_URL = "http://exslt.org/sets",
+    S_EXSLT_DATETIME_URL = "http://exslt.org/dates-and-times",
+    S_EXSLT_FUNCTIONS_URL = "http://exslt.org/functions",
+    S_EXSLT_DYNAMIC_URL = "http://exslt.org/dynamic",
+    S_EXSLT_STRINGS_URL = "http://exslt.org/strings";
+    
+    
+  /**
+   * The minimum version of XSLT supported by this processor.
+   */
+  public static final double XSLTVERSUPPORTED = 1.0;
+}
diff --git a/src/main/java/org/apache/xml/utils/DOM2Helper.java b/src/main/java/org/apache/xml/utils/DOM2Helper.java
new file mode 100644
index 0000000..98198e6
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/DOM2Helper.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOM2Helper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.xml.sax.InputSource;
+
+/**
+ * @deprecated Since the introduction of the DTM, this class will be removed.
+ * This class provides a DOM level 2 "helper", which provides services currently 
+ * not provided be the DOM standard.
+ */
+public class DOM2Helper extends DOMHelper
+{
+
+  /**
+   * Construct an instance.
+   */
+  public DOM2Helper(){}
+
+  /**
+   * Check node to see if it was created by a DOM implementation
+   * that this helper is intended to support. This is currently
+   * disabled, and assumes all nodes are acceptable rather than checking
+   * that they implement org.apache.xerces.dom.NodeImpl.
+   *
+   * @param node The node to be tested.
+   *
+   * @throws TransformerException if the node is not one which this
+   * DOM2Helper can support. If we return without throwing the exception,
+   * the node is compatable.
+   * @xsl.usage internal
+   */
+  public void checkNode(Node node) throws TransformerException
+  {
+
+    // if(!(node instanceof org.apache.xerces.dom.NodeImpl))
+    //  throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XERCES_CANNOT_HANDLE_NODES, new Object[]{((Object)node).getClass()})); //"DOM2Helper can not handle nodes of type"
+    //+((Object)node).getClass());
+  }
+
+  /**
+   * Returns true if the DOM implementation handled by this helper
+   * supports the SAX ContentHandler interface.
+   *
+   * @return true (since Xerces does).
+   */
+  public boolean supportsSAX()
+  {
+    return true;
+  }
+
+  /** Field m_doc: Document Node for the document this helper is currently
+   * accessing or building
+   * @see #setDocument
+   * @see #getDocument
+   *  */
+  private Document m_doc;
+
+  /**
+   * Specify which document this helper is currently operating on.
+   * 	
+   * @param doc The DOM Document node for this document.
+   * @see #getDocument
+   */
+  public void setDocument(Document doc)
+  {
+    m_doc = doc;
+  }
+
+  /**
+   * Query which document this helper is currently operating on.
+   * 	
+   * @return The DOM Document node for this document.
+   * @see #setDocument
+   */
+  public Document getDocument()
+  {
+    return m_doc;
+  }
+
+  /**
+   * Parse an XML document.
+   *
+   * <p>Right now the Xerces DOMParser class is used.  This needs
+   * fixing, either via jaxp, or via some other, standard method.</p>
+   *
+   * <p>The application can use this method to instruct the SAX parser
+   * to begin parsing an XML document from any valid input
+   * source (a character stream, a byte stream, or a URI).</p>
+   *
+   * <p>Applications may not invoke this method while a parse is in
+   * progress (they should create a new Parser instead for each
+   * additional XML document).  Once a parse is complete, an
+   * application may reuse the same Parser object, possibly with a
+   * different input source.</p>
+   *
+   * @param source The input source for the top-level of the
+   *        XML document.
+   *
+   * @throws TransformerException if any checked exception is thrown.
+   * @xsl.usage internal
+   */
+  public void parse(InputSource source) throws TransformerException
+  {
+
+    try
+    {
+
+      // I guess I should use JAXP factory here... when it's legal.
+      // org.apache.xerces.parsers.DOMParser parser 
+      //  = new org.apache.xerces.parsers.DOMParser();
+      DocumentBuilderFactory builderFactory =
+        DocumentBuilderFactory.newInstance();
+
+      builderFactory.setNamespaceAware(true);
+      builderFactory.setValidating(true);
+
+      DocumentBuilder parser = builderFactory.newDocumentBuilder();
+
+      /*
+      // domParser.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", getShouldExpandEntityRefs()? false : true);
+      if(m_useDOM2getNamespaceURI)
+      {
+      parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
+      parser.setFeature("http://xml.org/sax/features/namespaces", true);
+      }
+      else
+      {
+      parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
+      }
+
+      parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
+      */
+
+      parser.setErrorHandler(
+        new org.apache.xml.utils.DefaultErrorHandler());
+
+      // if(null != m_entityResolver)
+      // {
+      // System.out.println("Setting the entity resolver.");
+      //  parser.setEntityResolver(m_entityResolver);
+      // }
+      setDocument(parser.parse(source));
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se);
+    }
+    catch (ParserConfigurationException pce)
+    {
+      throw new TransformerException(pce);
+    }
+    catch (IOException ioe)
+    {
+      throw new TransformerException(ioe);
+    }
+
+    // setDocument(((org.apache.xerces.parsers.DOMParser)parser).getDocument());
+  }
+
+  /**
+   * Given an XML ID, return the element. This requires assistance from the
+   * DOM and parser, and is meaningful only in the context of a DTD 
+   * or schema which declares attributes as being of type ID. This
+   * information may or may not be available in all parsers, may or
+   * may not be available for specific documents, and may or may not
+   * be available when validation is not turned on.
+   *
+   * @param id The ID to search for, as a String.
+   * @param doc The document to search within, as a DOM Document node.
+   * @return DOM Element node with an attribute of type ID whose value
+   * uniquely matches the requested id string, or null if there isn't
+   * such an element or if the DOM can't answer the question for other
+   * reasons.
+   */
+  public Element getElementByID(String id, Document doc)
+  {
+    return doc.getElementById(id);
+  }
+
+  /**
+   * Figure out whether node2 should be considered as being later
+   * in the document than node1, in Document Order as defined
+   * by the XPath model. This may not agree with the ordering defined
+   * by other XML applications.
+   * <p>
+   * There are some cases where ordering isn't defined, and neither are
+   * the results of this function -- though we'll generally return true.
+   * <p>
+   * TODO: Make sure this does the right thing with attribute nodes!!!
+   *
+   * @param node1 DOM Node to perform position comparison on.
+   * @param node2 DOM Node to perform position comparison on .
+   * 
+   * @return false if node2 comes before node1, otherwise return true.
+   * You can think of this as 
+   * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
+   */
+  public static boolean isNodeAfter(Node node1, Node node2)
+  {
+
+    // Assume first that the nodes are DTM nodes, since discovering node 
+    // order is massivly faster for the DTM.
+    if(node1 instanceof DOMOrder && node2 instanceof DOMOrder)
+    {
+      int index1 = ((DOMOrder) node1).getUid();
+      int index2 = ((DOMOrder) node2).getUid();
+
+      return index1 <= index2;
+    }
+    else
+    {
+
+      // isNodeAfter will return true if node is after countedNode 
+      // in document order. The base isNodeAfter is sloooow (relatively).
+      return DOMHelper.isNodeAfter(node1, node2);
+    }
+  }
+
+  /**
+   * Get the XPath-model parent of a node.  This version takes advantage
+   * of the DOM Level 2 Attr.ownerElement() method; the base version we
+   * would otherwise inherit is prepared to fall back on exhaustively
+   * walking the document to find an Attr's parent.
+   *
+   * @param node Node to be examined
+   *
+   * @return the DOM parent of the input node, if there is one, or the
+   * ownerElement if the input node is an Attr, or null if the node is
+   * a Document, a DocumentFragment, or an orphan.
+   */
+  public static Node getParentOfNode(Node node)
+  {
+          Node parent=node.getParentNode();
+          if(parent==null && (Node.ATTRIBUTE_NODE == node.getNodeType()) )
+           parent=((Attr) node).getOwnerElement();
+          return parent;
+  }
+
+  /**
+   * Returns the local name of the given node, as defined by the
+   * XML Namespaces specification. This is prepared to handle documents
+   * built using DOM Level 1 methods by falling back upon explicitly
+   * parsing the node name.
+   *
+   * @param n Node to be examined
+   *
+   * @return String containing the local name, or null if the node
+   * was not assigned a Namespace.
+   */
+  public String getLocalNameOfNode(Node n)
+  {
+
+    String name = n.getLocalName();
+
+    return (null == name) ? super.getLocalNameOfNode(n) : name;
+  }
+
+  /**
+   * Returns the Namespace Name (Namespace URI) for the given node.
+   * In a Level 2 DOM, you can ask the node itself. Note, however, that
+   * doing so conflicts with our decision in getLocalNameOfNode not
+   * to trust the that the DOM was indeed created using the Level 2
+   * methods. If Level 1 methods were used, these two functions will
+   * disagree with each other.
+   * <p>
+   * TODO: Reconcile with getLocalNameOfNode.
+   *
+   * @param n Node to be examined
+   *
+   * @return String containing the Namespace URI bound to this DOM node
+   * at the time the Node was created.
+   */
+  public String getNamespaceOfNode(Node n)
+  {
+    return n.getNamespaceURI();
+  }
+
+  /** Field m_useDOM2getNamespaceURI is a compile-time flag which
+   *  gates some of the parser options used to build a DOM -- but 
+   * that code is commented out at this time and nobody else
+   * references it, so I've commented this out as well. */
+  //private boolean m_useDOM2getNamespaceURI = false;
+}
diff --git a/src/main/java/org/apache/xml/utils/DOMBuilder.java b/src/main/java/org/apache/xml/utils/DOMBuilder.java
new file mode 100644
index 0000000..3475ca1
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/DOMBuilder.java
@@ -0,0 +1,795 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOMBuilder.java 472634 2006-11-08 20:43:55Z jycli $
+ */
+package org.apache.xml.utils;
+
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.w3c.dom.CDATASection;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.ext.LexicalHandler;
+/**
+ * This class takes SAX events (in addition to some extra events
+ * that SAX doesn't handle yet) and adds the result to a document
+ * or document fragment.
+ * @xsl.usage general
+ */
+public class DOMBuilder
+        implements ContentHandler, LexicalHandler
+{
+
+  /** Root document          */
+  public Document m_doc;
+
+  /** Current node           */
+  protected Node m_currentNode = null;
+  
+  /** The root node          */
+  protected Node m_root = null;
+  
+  /** The next sibling node  */
+  protected Node m_nextSibling = null;
+
+  /** First node of document fragment or null if not a DocumentFragment     */
+  public DocumentFragment m_docFrag = null;
+
+  /** Vector of element nodes          */
+  protected Stack m_elemStack = new Stack();
+  
+  /** Namespace support */
+  protected Vector m_prefixMappings = new Vector();
+  
+  /**
+   * DOMBuilder instance constructor... it will add the DOM nodes
+   * to the document fragment.
+   *
+   * @param doc Root document
+   * @param node Current node
+   */
+  public DOMBuilder(Document doc, Node node)
+  {
+    m_doc = doc;
+    m_currentNode = m_root = node;
+    
+    if (node instanceof Element)
+      m_elemStack.push(node);
+  }
+
+  /**
+   * DOMBuilder instance constructor... it will add the DOM nodes
+   * to the document fragment.
+   *
+   * @param doc Root document
+   * @param docFrag Document fragment
+   */
+  public DOMBuilder(Document doc, DocumentFragment docFrag)
+  {
+    m_doc = doc;
+    m_docFrag = docFrag;
+  }
+
+  /**
+   * DOMBuilder instance constructor... it will add the DOM nodes
+   * to the document.
+   *
+   * @param doc Root document
+   */
+  public DOMBuilder(Document doc)
+  {
+    m_doc = doc;
+  }
+
+  /**
+   * Get the root document or DocumentFragment of the DOM being created.
+   *
+   * @return The root document or document fragment if not null
+   */
+  public Node getRootDocument()
+  {
+    return (null != m_docFrag) ? (Node) m_docFrag : (Node) m_doc;
+  }
+  
+  /**
+   * Get the root node of the DOM tree.
+   */
+  public Node getRootNode()
+  {
+    return m_root;
+  }
+  
+  /**
+   * Get the node currently being processed.
+   *
+   * @return the current node being processed
+   */
+  public Node getCurrentNode()
+  {
+    return m_currentNode;
+  }
+  
+  /**
+   * Set the next sibling node, which is where the result nodes 
+   * should be inserted before.
+   * 
+   * @param nextSibling the next sibling node.
+   */
+  public void setNextSibling(Node nextSibling)
+  {
+    m_nextSibling = nextSibling;
+  }
+  
+  /**
+   * Return the next sibling node.
+   * 
+   * @return the next sibling node.
+   */
+  public Node getNextSibling()
+  {
+    return m_nextSibling;
+  }
+
+  /**
+   * Return null since there is no Writer for this class.
+   *
+   * @return null
+   */
+  public java.io.Writer getWriter()
+  {
+    return null;
+  }
+
+  /**
+   * Append a node to the current container.
+   *
+   * @param newNode New node to append
+   */
+  protected void append(Node newNode) throws org.xml.sax.SAXException
+  {
+
+    Node currentNode = m_currentNode;
+
+    if (null != currentNode)
+    {
+      if (currentNode == m_root && m_nextSibling != null)
+        currentNode.insertBefore(newNode, m_nextSibling);
+      else
+        currentNode.appendChild(newNode);
+
+      // System.out.println(newNode.getNodeName());
+    }
+    else if (null != m_docFrag)
+    {
+      if (m_nextSibling != null)
+        m_docFrag.insertBefore(newNode, m_nextSibling);
+      else
+        m_docFrag.appendChild(newNode);
+    }
+    else
+    {
+      boolean ok = true;
+      short type = newNode.getNodeType();
+
+      if (type == Node.TEXT_NODE)
+      {
+        String data = newNode.getNodeValue();
+
+        if ((null != data) && (data.trim().length() > 0))
+        {
+          throw new org.xml.sax.SAXException(
+            XMLMessages.createXMLMessage(
+              XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null));  //"Warning: can't output text before document element!  Ignoring...");
+        }
+
+        ok = false;
+      }
+      else if (type == Node.ELEMENT_NODE)
+      {
+        if (m_doc.getDocumentElement() != null)
+        {
+          ok = false;
+          
+          throw new org.xml.sax.SAXException(
+            XMLMessages.createXMLMessage(
+              XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null));  //"Can't have more than one root on a DOM!");
+        }
+      }
+
+      if (ok)
+      {
+        if (m_nextSibling != null)
+          m_doc.insertBefore(newNode, m_nextSibling);
+        else
+          m_doc.appendChild(newNode);
+      }
+    }
+  }
+
+  /**
+   * Receive an object for locating the origin of SAX document events.
+   *
+   * <p>SAX parsers are strongly encouraged (though not absolutely
+   * required) to supply a locator: if it does so, it must supply
+   * the locator to the application by invoking this method before
+   * invoking any of the other methods in the ContentHandler
+   * interface.</p>
+   *
+   * <p>The locator allows the application to determine the end
+   * position of any document-related event, even if the parser is
+   * not reporting an error.  Typically, the application will
+   * use this information for reporting its own errors (such as
+   * character content that does not match an application's
+   * business rules).  The information returned by the locator
+   * is probably not sufficient for use with a search engine.</p>
+   *
+   * <p>Note that the locator will return correct information only
+   * during the invocation of the events in this interface.  The
+   * application should not attempt to use it at any other time.</p>
+   *
+   * @param locator An object that can return the location of
+   *                any SAX document event.
+   * @see org.xml.sax.Locator
+   */
+  public void setDocumentLocator(Locator locator)
+  {
+
+    // No action for the moment.
+  }
+
+  /**
+   * Receive notification of the beginning of a document.
+   *
+   * <p>The SAX parser will invoke this method only once, before any
+   * other methods in this interface or in DTDHandler (except for
+   * setDocumentLocator).</p>
+   */
+  public void startDocument() throws org.xml.sax.SAXException
+  {
+
+    // No action for the moment.
+  }
+
+  /**
+   * Receive notification of the end of a document.
+   *
+   * <p>The SAX parser will invoke this method only once, and it will
+   * be the last method invoked during the parse.  The parser shall
+   * not invoke this method until it has either abandoned parsing
+   * (because of an unrecoverable error) or reached the end of
+   * input.</p>
+   */
+  public void endDocument() throws org.xml.sax.SAXException
+  {
+
+    // No action for the moment.
+  }
+
+  /**
+   * Receive notification of the beginning of an element.
+   *
+   * <p>The Parser will invoke this method at the beginning of every
+   * element in the XML document; there will be a corresponding
+   * endElement() event for every startElement() event (even when the
+   * element is empty). All of the element's content will be
+   * reported, in order, before the corresponding endElement()
+   * event.</p>
+   *
+   * <p>If the element name has a namespace prefix, the prefix will
+   * still be attached.  Note that the attribute list provided will
+   * contain only attributes with explicit values (specified or
+   * defaulted): #IMPLIED attributes will be omitted.</p>
+   *
+   *
+   * @param ns The namespace of the node
+   * @param localName The local part of the qualified name
+   * @param name The element name.
+   * @param atts The attributes attached to the element, if any.
+   * @see #endElement
+   * @see org.xml.sax.Attributes
+   */
+  public void startElement(
+          String ns, String localName, String name, Attributes atts)
+            throws org.xml.sax.SAXException
+  {
+
+    Element elem;
+
+	// Note that the namespace-aware call must be used to correctly
+	// construct a Level 2 DOM, even for non-namespaced nodes.
+    if ((null == ns) || (ns.length() == 0))
+      elem = m_doc.createElementNS(null,name);
+    else
+      elem = m_doc.createElementNS(ns, name);
+
+    append(elem);
+
+    try
+    {
+      int nAtts = atts.getLength();
+
+      if (0 != nAtts)
+      {
+        for (int i = 0; i < nAtts; i++)
+        {
+
+          //System.out.println("type " + atts.getType(i) + " name " + atts.getLocalName(i) );
+          // First handle a possible ID attribute
+          if (atts.getType(i).equalsIgnoreCase("ID"))
+            setIDAttribute(atts.getValue(i), elem);
+
+          String attrNS = atts.getURI(i);
+
+          if("".equals(attrNS))
+            attrNS = null; // DOM represents no-namespace as null
+
+          // System.out.println("attrNS: "+attrNS+", localName: "+atts.getQName(i)
+          //                   +", qname: "+atts.getQName(i)+", value: "+atts.getValue(i));
+          // Crimson won't let us set an xmlns: attribute on the DOM.
+          String attrQName = atts.getQName(i);
+
+          // In SAX, xmlns[:] attributes have an empty namespace, while in DOM they 
+          // should have the xmlns namespace
+          if (attrQName.startsWith("xmlns:") || attrQName.equals("xmlns")) {
+            attrNS = "http://www.w3.org/2000/xmlns/";
+          }
+
+          // ALWAYS use the DOM Level 2 call!
+          elem.setAttributeNS(attrNS,attrQName, atts.getValue(i));
+        }
+      }
+      
+      /*
+       * Adding namespace nodes to the DOM tree;
+       */
+      int nDecls = m_prefixMappings.size();
+      
+      String prefix, declURL;
+      
+      for (int i = 0; i < nDecls; i += 2)
+      {
+        prefix = (String) m_prefixMappings.elementAt(i);
+
+        if (prefix == null)
+          continue;
+
+        declURL = (String) m_prefixMappings.elementAt(i + 1);
+
+        elem.setAttributeNS("http://www.w3.org/2000/xmlns/", prefix, declURL);
+      }
+      
+      m_prefixMappings.clear();
+    
+      // append(elem);
+
+      m_elemStack.push(elem);
+
+      m_currentNode = elem;
+
+      // append(elem);
+    }
+    catch(java.lang.Exception de)
+    {
+      // de.printStackTrace();
+      throw new org.xml.sax.SAXException(de);
+    }
+
+  }
+
+  /**
+
+
+
+   * Receive notification of the end of an element.
+   *
+   * <p>The SAX parser will invoke this method at the end of every
+   * element in the XML document; there will be a corresponding
+   * startElement() event for every endElement() event (even when the
+   * element is empty).</p>
+   *
+   * <p>If the element name has a namespace prefix, the prefix will
+   * still be attached to the name.</p>
+   *
+   *
+   * @param ns the namespace of the element
+   * @param localName The local part of the qualified name of the element
+   * @param name The element name
+   */
+  public void endElement(String ns, String localName, String name)
+          throws org.xml.sax.SAXException
+  {
+    m_elemStack.pop();
+    m_currentNode = m_elemStack.isEmpty() ? null : (Node)m_elemStack.peek();
+  }
+
+  /**
+   * Set an ID string to node association in the ID table.
+   *
+   * @param id The ID string.
+   * @param elem The associated ID.
+   */
+  public void setIDAttribute(String id, Element elem)
+  {
+
+    // Do nothing. This method is meant to be overiden.
+  }
+
+  /**
+   * Receive notification of character data.
+   *
+   * <p>The Parser will call this method to report each chunk of
+   * character data.  SAX parsers may return all contiguous character
+   * data in a single chunk, or they may split it into several
+   * chunks; however, all of the characters in any single event
+   * must come from the same external entity, so that the Locator
+   * provides useful information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * <p>Note that some parsers will report whitespace using the
+   * ignorableWhitespace() method rather than this one (validating
+   * parsers must do so).</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @see #ignorableWhitespace
+   * @see org.xml.sax.Locator
+   */
+  public void characters(char ch[], int start, int length) throws org.xml.sax.SAXException
+  {
+    if(isOutsideDocElem()
+       && org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+      return;  // avoid DOM006 Hierarchy request error
+
+    if (m_inCData)
+    {
+      cdata(ch, start, length);
+
+      return;
+    }
+
+    String s = new String(ch, start, length);
+    Node childNode;
+    childNode =  m_currentNode != null ? m_currentNode.getLastChild(): null;
+    if( childNode != null && childNode.getNodeType() == Node.TEXT_NODE ){
+       ((Text)childNode).appendData(s);
+    }
+    else{
+       Text text = m_doc.createTextNode(s);
+       append(text);
+    }
+  }
+
+  /**
+   * If available, when the disable-output-escaping attribute is used,
+   * output raw text without escaping.  A PI will be inserted in front
+   * of the node with the name "lotusxsl-next-is-raw" and a value of
+   * "formatter-to-dom".
+   *
+   * @param ch Array containing the characters
+   * @param start Index to start of characters in the array
+   * @param length Number of characters in the array
+   */
+  public void charactersRaw(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+    if(isOutsideDocElem()
+       && org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+      return;  // avoid DOM006 Hierarchy request error
+
+
+    String s = new String(ch, start, length);
+
+    append(m_doc.createProcessingInstruction("xslt-next-is-raw",
+                                             "formatter-to-dom"));
+    append(m_doc.createTextNode(s));
+  }
+
+  /**
+   * Report the beginning of an entity.
+   *
+   * The start and end of the document entity are not reported.
+   * The start and end of the external DTD subset are reported
+   * using the pseudo-name "[dtd]".  All other events must be
+   * properly nested within start/end entity events.
+   *
+   * @param name The name of the entity.  If it is a parameter
+   *        entity, the name will begin with '%'.
+   * @see #endEntity
+   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+   */
+  public void startEntity(String name) throws org.xml.sax.SAXException
+  {
+
+    // Almost certainly the wrong behavior...
+    // entityReference(name);
+  }
+
+  /**
+   * Report the end of an entity.
+   *
+   * @param name The name of the entity that is ending.
+   * @see #startEntity
+   */
+  public void endEntity(String name) throws org.xml.sax.SAXException{}
+
+  /**
+   * Receive notivication of a entityReference.
+   *
+   * @param name name of the entity reference
+   */
+  public void entityReference(String name) throws org.xml.sax.SAXException
+  {
+    append(m_doc.createEntityReference(name));
+  }
+
+  /**
+   * Receive notification of ignorable whitespace in element content.
+   *
+   * <p>Validating Parsers must use this method to report each chunk
+   * of ignorable whitespace (see the W3C XML 1.0 recommendation,
+   * section 2.10): non-validating parsers may also use this method
+   * if they are capable of parsing and using content models.</p>
+   *
+   * <p>SAX parsers may return all contiguous whitespace in a single
+   * chunk, or they may split it into several chunks; however, all of
+   * the characters in any single event must come from the same
+   * external entity, so that the Locator provides useful
+   * information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @see #characters
+   */
+  public void ignorableWhitespace(char ch[], int start, int length)
+          throws org.xml.sax.SAXException
+  {
+    if(isOutsideDocElem())
+      return;  // avoid DOM006 Hierarchy request error
+
+    String s = new String(ch, start, length);
+
+    append(m_doc.createTextNode(s));
+  }
+
+  /**
+   * Tell if the current node is outside the document element.
+   *
+   * @return true if the current node is outside the document element.
+   */
+   private boolean isOutsideDocElem()
+   {
+      return (null == m_docFrag) && m_elemStack.size() == 0 && (null == m_currentNode || m_currentNode.getNodeType() == Node.DOCUMENT_NODE);
+   }
+
+  /**
+   * Receive notification of a processing instruction.
+   *
+   * <p>The Parser will invoke this method once for each processing
+   * instruction found: note that processing instructions may occur
+   * before or after the main document element.</p>
+   *
+   * <p>A SAX parser should never report an XML declaration (XML 1.0,
+   * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+   * using this method.</p>
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *        none was supplied.
+   */
+  public void processingInstruction(String target, String data)
+          throws org.xml.sax.SAXException
+  {
+    append(m_doc.createProcessingInstruction(target, data));
+  }
+
+  /**
+   * Report an XML comment anywhere in the document.
+   *
+   * This callback will be used for comments inside or outside the
+   * document element, including comments in the external DTD
+   * subset (if read).
+   *
+   * @param ch An array holding the characters in the comment.
+   * @param start The starting position in the array.
+   * @param length The number of characters to use from the array.
+   */
+  public void comment(char ch[], int start, int length) throws org.xml.sax.SAXException
+  {
+    append(m_doc.createComment(new String(ch, start, length)));
+  }
+
+  /** Flag indicating that we are processing a CData section          */
+  protected boolean m_inCData = false;
+
+  /**
+   * Report the start of a CDATA section.
+   *
+   * @see #endCDATA
+   */
+  public void startCDATA() throws org.xml.sax.SAXException
+  {
+    m_inCData = true;
+    append(m_doc.createCDATASection(""));
+  }
+
+  /**
+   * Report the end of a CDATA section.
+   *
+   * @see #startCDATA
+   */
+  public void endCDATA() throws org.xml.sax.SAXException
+  {
+    m_inCData = false;
+  }
+
+  /**
+   * Receive notification of cdata.
+   *
+   * <p>The Parser will call this method to report each chunk of
+   * character data.  SAX parsers may return all contiguous character
+   * data in a single chunk, or they may split it into several
+   * chunks; however, all of the characters in any single event
+   * must come from the same external entity, so that the Locator
+   * provides useful information.</p>
+   *
+   * <p>The application must not attempt to read from the array
+   * outside of the specified range.</p>
+   *
+   * <p>Note that some parsers will report whitespace using the
+   * ignorableWhitespace() method rather than this one (validating
+   * parsers must do so).</p>
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @see #ignorableWhitespace
+   * @see org.xml.sax.Locator
+   */
+  public void cdata(char ch[], int start, int length) throws org.xml.sax.SAXException
+  {
+    if(isOutsideDocElem()
+       && org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+      return;  // avoid DOM006 Hierarchy request error
+
+    String s = new String(ch, start, length);
+
+    CDATASection section  =(CDATASection) m_currentNode.getLastChild();
+    section.appendData(s);
+  }
+
+  /**
+   * Report the start of DTD declarations, if any.
+   *
+   * Any declarations are assumed to be in the internal subset
+   * unless otherwise indicated.
+   *
+   * @param name The document type name.
+   * @param publicId The declared public identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @param systemId The declared system identifier for the
+   *        external DTD subset, or null if none was declared.
+   * @see #endDTD
+   * @see #startEntity
+   */
+  public void startDTD(String name, String publicId, String systemId)
+          throws org.xml.sax.SAXException
+  {
+
+    // Do nothing for now.
+  }
+
+  /**
+   * Report the end of DTD declarations.
+   *
+   * @see #startDTD
+   */
+  public void endDTD() throws org.xml.sax.SAXException
+  {
+
+    // Do nothing for now.
+  }
+
+  /**
+   * Begin the scope of a prefix-URI Namespace mapping.
+   *
+   * <p>The information from this event is not necessary for
+   * normal Namespace processing: the SAX XML reader will
+   * automatically replace prefixes for element and attribute
+   * names when the http://xml.org/sax/features/namespaces
+   * feature is true (the default).</p>
+   *
+   * <p>There are cases, however, when applications need to
+   * use prefixes in character data or in attribute values,
+   * where they cannot safely be expanded automatically; the
+   * start/endPrefixMapping event supplies the information
+   * to the application to expand prefixes in those contexts
+   * itself, if necessary.</p>
+   *
+   * <p>Note that start/endPrefixMapping events are not
+   * guaranteed to be properly nested relative to each-other:
+   * all startPrefixMapping events will occur before the
+   * corresponding startElement event, and all endPrefixMapping
+   * events will occur after the corresponding endElement event,
+   * but their order is not guaranteed.</p>
+   *
+   * @param prefix The Namespace prefix being declared.
+   * @param uri The Namespace URI the prefix is mapped to.
+   * @see #endPrefixMapping
+   * @see #startElement
+   */
+  public void startPrefixMapping(String prefix, String uri)
+          throws org.xml.sax.SAXException
+  {
+	      if(null == prefix || prefix.equals(""))
+	        prefix = "xmlns";
+	      else prefix = "xmlns:"+prefix;
+	      m_prefixMappings.addElement(prefix);
+	      m_prefixMappings.addElement(uri); 
+  }
+
+  /**
+   * End the scope of a prefix-URI mapping.
+   *
+   * <p>See startPrefixMapping for details.  This event will
+   * always occur after the corresponding endElement event,
+   * but the order of endPrefixMapping events is not otherwise
+   * guaranteed.</p>
+   *
+   * @param prefix The prefix that was being mapping.
+   * @see #startPrefixMapping
+   * @see #endElement
+   */
+  public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException{}
+
+  /**
+   * Receive notification of a skipped entity.
+   *
+   * <p>The Parser will invoke this method once for each entity
+   * skipped.  Non-validating processors may skip entities if they
+   * have not seen the declarations (because, for example, the
+   * entity was declared in an external DTD subset).  All processors
+   * may skip external entities, depending on the values of the
+   * http://xml.org/sax/features/external-general-entities and the
+   * http://xml.org/sax/features/external-parameter-entities
+   * properties.</p>
+   *
+   * @param name The name of the skipped entity.  If it is a
+   *        parameter entity, the name will begin with '%'.
+   */
+  public void skippedEntity(String name) throws org.xml.sax.SAXException{}
+}
diff --git a/src/main/java/org/apache/xml/utils/DOMHelper.java b/src/main/java/org/apache/xml/utils/DOMHelper.java
new file mode 100644
index 0000000..53d0adc
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/DOMHelper.java
@@ -0,0 +1,1341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOMHelper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xml.dtm.ref.DTMNodeProxy;
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Entity;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @deprecated Since the introduction of the DTM, this class will be removed.
+ * This class provides a front-end to DOM implementations, providing
+ * a number of utility functions that either aren't yet standardized
+ * by the DOM spec or that are defined in optional DOM modules and
+ * hence may not be present in all DOMs.
+ */
+public class DOMHelper
+{
+
+  /**
+   * DOM Level 1 did not have a standard mechanism for creating a new
+   * Document object. This function provides a DOM-implementation-independent
+   * abstraction for that for that concept. It's typically used when 
+   * outputting a new DOM as the result of an operation.
+   * <p>
+   * TODO: This isn't directly compatable with DOM Level 2. 
+   * The Level 2 createDocument call also creates the root 
+   * element, and thus requires that you know what that element will be
+   * before creating the Document. We should think about whether we want
+   * to change this code, and the callers, so we can use the DOM's own 
+   * method. (It's also possible that DOM Level 3 may relax this
+   * sequence, but you may give up some intelligence in the DOM by
+   * doing so; the intent was that knowing the document type and root
+   * element might let the DOM automatically switch to a specialized
+   * subclass for particular kinds of documents.)
+   *
+   * @param isSecureProcessing state of the secure processing feature.
+   * @return The newly created DOM Document object, with no children, or
+   * null if we can't find a DOM implementation that permits creating
+   * new empty Documents.
+   */
+  public static Document createDocument(boolean isSecureProcessing)
+  {
+
+    try
+    {
+
+      // Use an implementation of the JAVA API for XML Parsing 1.0 to
+      // create a DOM Document node to contain the result.
+      DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+
+      dfactory.setNamespaceAware(true);
+      // BEGIN android-removed
+      //     If set, DocumentBuilderFactoryImpl.newDocumentBuilder() fails
+      //     because we haven't implemented validation
+      // dfactory.setValidating(true);
+      // BEGIN android-removed
+
+      // BEGIN android-removed
+      //     We haven't implemented secure processing
+      // if (isSecureProcessing)
+      // {
+      //   try
+      //   {
+      //     dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+      //   }
+      //   catch (ParserConfigurationException pce) {}
+      // }
+      // END android-removed
+      
+      DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
+      Document outNode = docBuilder.newDocument();
+
+      return outNode;
+    }
+    catch (ParserConfigurationException pce)
+    {
+      throw new RuntimeException(
+        XMLMessages.createXMLMessage(
+          XMLErrorResources.ER_CREATEDOCUMENT_NOT_SUPPORTED, null));  //"createDocument() not supported in XPathContext!");
+
+      // return null;
+    }
+  }
+
+  /**
+   * DOM Level 1 did not have a standard mechanism for creating a new
+   * Document object. This function provides a DOM-implementation-independent
+   * abstraction for that for that concept. It's typically used when 
+   * outputting a new DOM as the result of an operation.
+   *
+   * @return The newly created DOM Document object, with no children, or
+   * null if we can't find a DOM implementation that permits creating
+   * new empty Documents.
+   */
+  public static Document createDocument()
+  {
+    return createDocument(false);
+  }
+  
+  /**
+   * Tells, through the combination of the default-space attribute
+   * on xsl:stylesheet, xsl:strip-space, xsl:preserve-space, and the
+   * xml:space attribute, whether or not extra whitespace should be stripped
+   * from the node.  Literal elements from template elements should
+   * <em>not</em> be tested with this function.
+   * @param textNode A text node from the source tree.
+   * @return true if the text node should be stripped of extra whitespace.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage advanced
+   */
+  public boolean shouldStripSourceNode(Node textNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // return (null == m_envSupport) ? false : m_envSupport.shouldStripSourceNode(textNode);
+    return false;
+  }
+
+  /**
+   * Supports the XPath function GenerateID by returning a unique
+   * identifier string for any given DOM Node.
+   * <p>
+   * Warning: The base implementation uses the Node object's hashCode(),
+   * which is NOT guaranteed to be unique. If that method hasn't been
+   * overridden in this DOM ipmlementation, most Java implementions will
+   * derive it from the object's address and should be OK... but if
+   * your DOM uses a different definition of hashCode (eg hashing the
+   * contents of the subtree), or if your DOM may have multiple objects
+   * that represent a single Node in the data structure (eg via proxying),
+   * you may need to find another way to assign a unique identifier.
+   * <p>
+   * Also, be aware that if nodes are destroyed and recreated, there is
+   * an open issue regarding whether an ID may be reused. Currently
+   * we're assuming that the input document is stable for the duration
+   * of the XPath/XSLT operation, so this shouldn't arise in this context.
+   * <p>
+   * (DOM Level 3 is investigating providing a unique node "key", but
+   * that won't help Level 1 and Level 2 implementations.)
+   *
+   * @param node whose identifier you want to obtain
+   *
+   * @return a string which should be different for every Node object.
+   */
+  public String getUniqueID(Node node)
+  {
+    return "N" + Integer.toHexString(node.hashCode()).toUpperCase();
+  }
+
+  /**
+   * Figure out whether node2 should be considered as being later
+   * in the document than node1, in Document Order as defined
+   * by the XPath model. This may not agree with the ordering defined
+   * by other XML applications.
+   * <p>
+   * There are some cases where ordering isn't defined, and neither are
+   * the results of this function -- though we'll generally return true.
+   * 
+   * TODO: Make sure this does the right thing with attribute nodes!!!
+   *
+   * @param node1 DOM Node to perform position comparison on.
+   * @param node2 DOM Node to perform position comparison on .
+   * 
+   * @return false if node2 comes before node1, otherwise return true.
+   * You can think of this as 
+   * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
+   */
+  public static boolean isNodeAfter(Node node1, Node node2)
+  {
+    if (node1 == node2 || isNodeTheSame(node1, node2))
+      return true;
+
+        // Default return value, if there is no defined ordering
+    boolean isNodeAfter = true;
+        
+    Node parent1 = getParentOfNode(node1);
+    Node parent2 = getParentOfNode(node2);          
+
+    // Optimize for most common case
+    if (parent1 == parent2 || isNodeTheSame(parent1, parent2))  // then we know they are siblings
+    {
+      if (null != parent1)
+        isNodeAfter = isNodeAfterSibling(parent1, node1, node2);
+      else
+      {
+                  // If both parents are null, ordering is not defined.
+                  // We're returning a value in lieu of throwing an exception.
+                  // Not a case we expect to arise in XPath, but beware if you
+                  // try to reuse this method.
+                  
+                  // We can just fall through in this case, which allows us
+                  // to hit the debugging code at the end of the function.
+          //return isNodeAfter;
+      }
+    }
+    else
+    {
+
+      // General strategy: Figure out the lengths of the two 
+      // ancestor chains, reconcile the lengths, and look for
+          // the lowest common ancestor. If that ancestor is one of
+          // the nodes being compared, it comes before the other.
+      // Otherwise perform a sibling compare. 
+                //
+                // NOTE: If no common ancestor is found, ordering is undefined
+                // and we return the default value of isNodeAfter.
+                
+      // Count parents in each ancestor chain
+      int nParents1 = 2, nParents2 = 2;  // include node & parent obtained above
+
+      while (parent1 != null)
+      {
+        nParents1++;
+
+        parent1 = getParentOfNode(parent1);
+      }
+
+      while (parent2 != null)
+      {
+        nParents2++;
+
+        parent2 = getParentOfNode(parent2);
+      }
+
+          // Initially assume scan for common ancestor starts with
+          // the input nodes.
+      Node startNode1 = node1, startNode2 = node2;
+
+      // If one ancestor chain is longer, adjust its start point
+          // so we're comparing at the same depths
+      if (nParents1 < nParents2)
+      {
+        // Adjust startNode2 to depth of startNode1
+        int adjust = nParents2 - nParents1;
+
+        for (int i = 0; i < adjust; i++)
+        {
+          startNode2 = getParentOfNode(startNode2);
+        }
+      }
+      else if (nParents1 > nParents2)
+      {
+        // adjust startNode1 to depth of startNode2
+        int adjust = nParents1 - nParents2;
+
+        for (int i = 0; i < adjust; i++)
+        {
+          startNode1 = getParentOfNode(startNode1);
+        }
+      }
+
+      Node prevChild1 = null, prevChild2 = null;  // so we can "back up"
+
+      // Loop up the ancestor chain looking for common parent
+      while (null != startNode1)
+      {
+        if (startNode1 == startNode2 || isNodeTheSame(startNode1, startNode2))  // common parent?
+        {
+          if (null == prevChild1)  // first time in loop?
+          {
+
+            // Edge condition: one is the ancestor of the other.
+            isNodeAfter = (nParents1 < nParents2) ? true : false;
+
+            break;  // from while loop
+          }
+          else 
+          {
+                        // Compare ancestors below lowest-common as siblings
+            isNodeAfter = isNodeAfterSibling(startNode1, prevChild1,
+                                             prevChild2);
+
+            break;  // from while loop
+          }
+        }  // end if(startNode1 == startNode2)
+
+                // Move up one level and try again
+        prevChild1 = startNode1;
+        startNode1 = getParentOfNode(startNode1);
+        prevChild2 = startNode2;
+        startNode2 = getParentOfNode(startNode2);
+      }  // end while(parents exist to examine)
+    }  // end big else (not immediate siblings)
+        
+        // WARNING: The following diagnostic won't report the early
+        // "same node" case. Fix if/when needed.
+        
+    /* -- please do not remove... very useful for diagnostics --
+    System.out.println("node1 = "+node1.getNodeName()+"("+node1.getNodeType()+")"+
+    ", node2 = "+node2.getNodeName()
+    +"("+node2.getNodeType()+")"+
+    ", isNodeAfter = "+isNodeAfter); */
+    return isNodeAfter;
+  }  // end isNodeAfter(Node node1, Node node2)
+
+  /**
+   * Use DTMNodeProxy to determine whether two nodes are the same.
+   * 
+   * @param node1 The first DOM node to compare.
+   * @param node2 The second DOM node to compare.
+   * @return true if the two nodes are the same.
+   */
+  public static boolean isNodeTheSame(Node node1, Node node2)
+  {
+    if (node1 instanceof DTMNodeProxy && node2 instanceof DTMNodeProxy)
+      return ((DTMNodeProxy)node1).equals((DTMNodeProxy)node2);
+    else
+      return (node1 == node2);
+  }
+
+  /**
+   * Figure out if child2 is after child1 in document order.
+   * <p>
+   * Warning: Some aspects of "document order" are not well defined.
+   * For example, the order of attributes is considered
+   * meaningless in XML, and the order reported by our model will
+   * be consistant for a given invocation but may not 
+   * match that of either the source file or the serialized output.
+   * 
+   * @param parent Must be the parent of both child1 and child2.
+   * @param child1 Must be the child of parent and not equal to child2.
+   * @param child2 Must be the child of parent and not equal to child1.
+   * @return true if child 2 is after child1 in document order.
+   */
+  private static boolean isNodeAfterSibling(Node parent, Node child1,
+                                            Node child2)
+  {
+
+    boolean isNodeAfterSibling = false;
+    short child1type = child1.getNodeType();
+    short child2type = child2.getNodeType();
+
+    if ((Node.ATTRIBUTE_NODE != child1type)
+            && (Node.ATTRIBUTE_NODE == child2type))
+    {
+
+      // always sort attributes before non-attributes.
+      isNodeAfterSibling = false;
+    }
+    else if ((Node.ATTRIBUTE_NODE == child1type)
+             && (Node.ATTRIBUTE_NODE != child2type))
+    {
+
+      // always sort attributes before non-attributes.
+      isNodeAfterSibling = true;
+    }
+    else if (Node.ATTRIBUTE_NODE == child1type)
+    {
+      NamedNodeMap children = parent.getAttributes();
+      int nNodes = children.getLength();
+      boolean found1 = false, found2 = false;
+
+          // Count from the start until we find one or the other.
+      for (int i = 0; i < nNodes; i++)
+      {
+        Node child = children.item(i);
+
+        if (child1 == child || isNodeTheSame(child1, child))
+        {
+          if (found2)
+          {
+            isNodeAfterSibling = false;
+
+            break;
+          }
+
+          found1 = true;
+        }
+        else if (child2 == child || isNodeTheSame(child2, child))
+        {
+          if (found1)
+          {
+            isNodeAfterSibling = true;
+
+            break;
+          }
+
+          found2 = true;
+        }
+      }
+    }
+    else
+    {
+                // TODO: Check performance of alternate solution:
+                // There are two choices here: Count from the start of
+                // the document until we find one or the other, or count
+                // from one until we find or fail to find the other.
+                // Either can wind up scanning all the siblings in the worst
+                // case, which on a wide document can be a lot of work but
+                // is more typically is a short list. 
+                // Scanning from the start involves two tests per iteration,
+                // but it isn't clear that scanning from the middle doesn't
+                // yield more iterations on average. 
+                // We should run some testcases.
+      Node child = parent.getFirstChild();
+      boolean found1 = false, found2 = false;
+
+      while (null != child)
+      {
+
+        // Node child = children.item(i);
+        if (child1 == child || isNodeTheSame(child1, child))
+        {
+          if (found2)
+          {
+            isNodeAfterSibling = false;
+
+            break;
+          }
+
+          found1 = true;
+        }
+        else if (child2 == child || isNodeTheSame(child2, child))
+        {
+          if (found1)
+          {
+            isNodeAfterSibling = true;
+
+            break;
+          }
+
+          found2 = true;
+        }
+
+        child = child.getNextSibling();
+      }
+    }
+
+    return isNodeAfterSibling;
+  }  // end isNodeAfterSibling(Node parent, Node child1, Node child2)
+
+  //==========================================================
+  // SECTION: Namespace resolution
+  //==========================================================
+
+  /**
+   * Get the depth level of this node in the tree (equals 1 for
+   * a parentless node).
+   *
+   * @param n Node to be examined.
+   * @return the number of ancestors, plus one
+   * @xsl.usage internal
+   */
+  public short getLevel(Node n)
+  {
+
+    short level = 1;
+
+    while (null != (n = getParentOfNode(n)))
+    {
+      level++;
+    }
+
+    return level;
+  }
+
+  /**
+   * Given an XML Namespace prefix and a context in which the prefix
+   * is to be evaluated, return the Namespace Name this prefix was 
+   * bound to. Note that DOM Level 3 is expected to provide a version of
+   * this which deals with the DOM's "early binding" behavior.
+   * 
+   * Default handling:
+   *
+   * @param prefix String containing namespace prefix to be resolved, 
+   * without the ':' which separates it from the localname when used 
+   * in a Node Name. The empty sting signifies the default namespace
+   * at this point in the document.
+   * @param namespaceContext Element which provides context for resolution.
+   * (We could extend this to work for other nodes by first seeking their
+   * nearest Element ancestor.)
+   *
+   * @return a String containing the Namespace URI which this prefix
+   * represents in the specified context.
+   */
+  public String getNamespaceForPrefix(String prefix, Element namespaceContext)
+  {
+
+    int type;
+    Node parent = namespaceContext;
+    String namespace = null;
+
+    if (prefix.equals("xml"))
+    {
+      namespace = QName.S_XMLNAMESPACEURI; // Hardcoded, per Namespace spec
+    }
+        else if(prefix.equals("xmlns"))
+    {
+          // Hardcoded in the DOM spec, expected to be adopted by
+          // Namespace spec. NOTE: Namespace declarations _must_ use
+          // the xmlns: prefix; other prefixes declared as belonging
+          // to this namespace will not be recognized and should
+          // probably be rejected by parsers as erroneous declarations.
+      namespace = "http://www.w3.org/2000/xmlns/"; 
+    }
+    else
+    {
+          // Attribute name for this prefix's declaration
+          String declname=(prefix=="")
+                        ? "xmlns"
+                        : "xmlns:"+prefix;
+                                           
+          // Scan until we run out of Elements or have resolved the namespace
+      while ((null != parent) && (null == namespace)
+             && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
+                 || (type == Node.ENTITY_REFERENCE_NODE)))
+      {
+        if (type == Node.ELEMENT_NODE)
+        {
+                        
+                        // Look for the appropriate Namespace Declaration attribute,
+                        // either "xmlns:prefix" or (if prefix is "") "xmlns".
+                        // TODO: This does not handle "implicit declarations"
+                        // which may be created when the DOM is edited. DOM Level
+                        // 3 will define how those should be interpreted. But
+                        // this issue won't arise in freshly-parsed DOMs.
+                        
+                // NOTE: declname is set earlier, outside the loop.
+                        Attr attr=((Element)parent).getAttributeNode(declname);
+                        if(attr!=null)
+                        {
+                namespace = attr.getNodeValue();
+                break;
+                        }
+                }
+
+        parent = getParentOfNode(parent);
+      }
+    }
+
+    return namespace;
+  }
+
+  /**
+   * An experiment for the moment.
+   */
+  Hashtable m_NSInfos = new Hashtable();
+
+  /** Object to put into the m_NSInfos table that tells that a node has not been 
+   *  processed, but has xmlns namespace decls.  */
+  protected static final NSInfo m_NSInfoUnProcWithXMLNS = new NSInfo(false,
+                                                            true);
+
+  /** Object to put into the m_NSInfos table that tells that a node has not been 
+   *  processed, but has no xmlns namespace decls.  */
+  protected static final NSInfo m_NSInfoUnProcWithoutXMLNS = new NSInfo(false,
+                                                               false);
+
+  /** Object to put into the m_NSInfos table that tells that a node has not been 
+   *  processed, and has no xmlns namespace decls, and has no ancestor decls.  */
+  protected static final NSInfo m_NSInfoUnProcNoAncestorXMLNS =
+    new NSInfo(false, false, NSInfo.ANCESTORNOXMLNS);
+
+  /** Object to put into the m_NSInfos table that tells that a node has been 
+   *  processed, and has xmlns namespace decls.  */
+  protected static final NSInfo m_NSInfoNullWithXMLNS = new NSInfo(true,
+                                                          true);
+
+  /** Object to put into the m_NSInfos table that tells that a node has been 
+   *  processed, and has no xmlns namespace decls.  */
+  protected static final NSInfo m_NSInfoNullWithoutXMLNS = new NSInfo(true,
+                                                             false);
+
+  /** Object to put into the m_NSInfos table that tells that a node has been 
+   *  processed, and has no xmlns namespace decls. and has no ancestor decls.  */
+  protected static final NSInfo m_NSInfoNullNoAncestorXMLNS =
+    new NSInfo(true, false, NSInfo.ANCESTORNOXMLNS);
+
+  /** Vector of node (odd indexes) and NSInfos (even indexes) that tell if 
+   *  the given node is a candidate for ancestor namespace processing.  */
+  protected Vector m_candidateNoAncestorXMLNS = new Vector();
+
+  /**
+   * Returns the namespace of the given node. Differs from simply getting
+   * the node's prefix and using getNamespaceForPrefix in that it attempts
+   * to cache some of the data in NSINFO objects, to avoid repeated lookup.
+   * TODO: Should we consider moving that logic into getNamespaceForPrefix?
+   *
+   * @param n Node to be examined.
+   *
+   * @return String containing the Namespace Name (uri) for this node.
+   * Note that this is undefined for any nodes other than Elements and
+   * Attributes.
+   */
+  public String getNamespaceOfNode(Node n)
+  {
+
+    String namespaceOfPrefix;
+    boolean hasProcessedNS;
+    NSInfo nsInfo;
+    short ntype = n.getNodeType();
+
+    if (Node.ATTRIBUTE_NODE != ntype)
+    {
+      Object nsObj = m_NSInfos.get(n);  // return value
+
+      nsInfo = (nsObj == null) ? null : (NSInfo) nsObj;
+      hasProcessedNS = (nsInfo == null) ? false : nsInfo.m_hasProcessedNS;
+    }
+    else
+    {
+      hasProcessedNS = false;
+      nsInfo = null;
+    }
+
+    if (hasProcessedNS)
+    {
+      namespaceOfPrefix = nsInfo.m_namespace;
+    }
+    else
+    {
+      namespaceOfPrefix = null;
+
+      String nodeName = n.getNodeName();
+      int indexOfNSSep = nodeName.indexOf(':');
+      String prefix;
+
+      if (Node.ATTRIBUTE_NODE == ntype)
+      {
+        if (indexOfNSSep > 0)
+        {
+          prefix = nodeName.substring(0, indexOfNSSep);
+        }
+        else
+        {
+
+          // Attributes don't use the default namespace, so if 
+          // there isn't a prefix, we're done.
+          return namespaceOfPrefix;
+        }
+      }
+      else
+      {
+        prefix = (indexOfNSSep >= 0)
+                 ? nodeName.substring(0, indexOfNSSep) : "";
+      }
+
+      boolean ancestorsHaveXMLNS = false;
+      boolean nHasXMLNS = false;
+
+      if (prefix.equals("xml"))
+      {
+        namespaceOfPrefix = QName.S_XMLNAMESPACEURI;
+      }
+      else
+      {
+        int parentType;
+        Node parent = n;
+
+        while ((null != parent) && (null == namespaceOfPrefix))
+        {
+          if ((null != nsInfo)
+                  && (nsInfo.m_ancestorHasXMLNSAttrs
+                      == NSInfo.ANCESTORNOXMLNS))
+          {
+            break;
+          }
+
+          parentType = parent.getNodeType();
+
+          if ((null == nsInfo) || nsInfo.m_hasXMLNSAttrs)
+          {
+            boolean elementHasXMLNS = false;
+
+            if (parentType == Node.ELEMENT_NODE)
+            {
+              NamedNodeMap nnm = parent.getAttributes();
+
+              for (int i = 0; i < nnm.getLength(); i++)
+              {
+                Node attr = nnm.item(i);
+                String aname = attr.getNodeName();
+
+                if (aname.charAt(0) == 'x')
+                {
+                  boolean isPrefix = aname.startsWith("xmlns:");
+
+                  if (aname.equals("xmlns") || isPrefix)
+                  {
+                    if (n == parent)
+                      nHasXMLNS = true;
+
+                    elementHasXMLNS = true;
+                    ancestorsHaveXMLNS = true;
+
+                    String p = isPrefix ? aname.substring(6) : "";
+
+                    if (p.equals(prefix))
+                    {
+                      namespaceOfPrefix = attr.getNodeValue();
+
+                      break;
+                    }
+                  }
+                }
+              }
+            }
+
+            if ((Node.ATTRIBUTE_NODE != parentType) && (null == nsInfo)
+                    && (n != parent))
+            {
+              nsInfo = elementHasXMLNS
+                       ? m_NSInfoUnProcWithXMLNS : m_NSInfoUnProcWithoutXMLNS;
+
+              m_NSInfos.put(parent, nsInfo);
+            }
+          }
+
+          if (Node.ATTRIBUTE_NODE == parentType)
+          {
+            parent = getParentOfNode(parent);
+          }
+          else
+          {
+            m_candidateNoAncestorXMLNS.addElement(parent);
+            m_candidateNoAncestorXMLNS.addElement(nsInfo);
+
+            parent = parent.getParentNode();
+          }
+
+          if (null != parent)
+          {
+            Object nsObj = m_NSInfos.get(parent);  // return value
+
+            nsInfo = (nsObj == null) ? null : (NSInfo) nsObj;
+          }
+        }
+
+        int nCandidates = m_candidateNoAncestorXMLNS.size();
+
+        if (nCandidates > 0)
+        {
+          if ((false == ancestorsHaveXMLNS) && (null == parent))
+          {
+            for (int i = 0; i < nCandidates; i += 2)
+            {
+              Object candidateInfo = m_candidateNoAncestorXMLNS.elementAt(i
+                                       + 1);
+
+              if (candidateInfo == m_NSInfoUnProcWithoutXMLNS)
+              {
+                m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i),
+                              m_NSInfoUnProcNoAncestorXMLNS);
+              }
+              else if (candidateInfo == m_NSInfoNullWithoutXMLNS)
+              {
+                m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i),
+                              m_NSInfoNullNoAncestorXMLNS);
+              }
+            }
+          }
+
+          m_candidateNoAncestorXMLNS.removeAllElements();
+        }
+      }
+
+      if (Node.ATTRIBUTE_NODE != ntype)
+      {
+        if (null == namespaceOfPrefix)
+        {
+          if (ancestorsHaveXMLNS)
+          {
+            if (nHasXMLNS)
+              m_NSInfos.put(n, m_NSInfoNullWithXMLNS);
+            else
+              m_NSInfos.put(n, m_NSInfoNullWithoutXMLNS);
+          }
+          else
+          {
+            m_NSInfos.put(n, m_NSInfoNullNoAncestorXMLNS);
+          }
+        }
+        else
+        {
+          m_NSInfos.put(n, new NSInfo(namespaceOfPrefix, nHasXMLNS));
+        }
+      }
+    }
+
+    return namespaceOfPrefix;
+  }
+
+  /**
+   * Returns the local name of the given node. If the node's name begins
+   * with a namespace prefix, this is the part after the colon; otherwise
+   * it's the full node name.
+   *
+   * @param n the node to be examined.
+   *
+   * @return String containing the Local Name
+   */
+  public String getLocalNameOfNode(Node n)
+  {
+
+    String qname = n.getNodeName();
+    int index = qname.indexOf(':');
+
+    return (index < 0) ? qname : qname.substring(index + 1);
+  }
+
+  /**
+   * Returns the element name with the namespace prefix (if any) replaced
+   * by the Namespace URI it was bound to. This is not a standard 
+   * representation of a node name, but it allows convenient 
+   * single-string comparison of the "universal" names of two nodes.
+   *
+   * @param elem Element to be examined.
+   *
+   * @return String in the form "namespaceURI:localname" if the node
+   * belongs to a namespace, or simply "localname" if it doesn't.
+   * @see #getExpandedAttributeName
+   */
+  public String getExpandedElementName(Element elem)
+  {
+
+    String namespace = getNamespaceOfNode(elem);
+
+    return (null != namespace)
+           ? namespace + ":" + getLocalNameOfNode(elem)
+           : getLocalNameOfNode(elem);
+  }
+
+  /**
+   * Returns the attribute name with the namespace prefix (if any) replaced
+   * by the Namespace URI it was bound to. This is not a standard 
+   * representation of a node name, but it allows convenient 
+   * single-string comparison of the "universal" names of two nodes.
+   *
+   * @param attr Attr to be examined
+   *
+   * @return String in the form "namespaceURI:localname" if the node
+   * belongs to a namespace, or simply "localname" if it doesn't.
+   * @see #getExpandedElementName
+   */
+  public String getExpandedAttributeName(Attr attr)
+  {
+
+    String namespace = getNamespaceOfNode(attr);
+
+    return (null != namespace)
+           ? namespace + ":" + getLocalNameOfNode(attr)
+           : getLocalNameOfNode(attr);
+  }
+
+  //==========================================================
+  // SECTION: DOM Helper Functions
+  //==========================================================
+
+  /**
+   * Tell if the node is ignorable whitespace. Note that this can
+   * be determined only in the context of a DTD or other Schema,
+   * and that DOM Level 2 has nostandardized DOM API which can
+   * return that information.
+   * @deprecated
+   *
+   * @param node Node to be examined
+   *
+   * @return CURRENTLY HARDCODED TO FALSE, but should return true if
+   * and only if the node is of type Text, contains only whitespace,
+   * and does not appear as part of the #PCDATA content of an element.
+   * (Note that determining this last may require allowing for 
+   * Entity References.)
+   */
+  public boolean isIgnorableWhitespace(Text node)
+  {
+
+    boolean isIgnorable = false;  // return value
+
+    // TODO: I can probably do something to figure out if this 
+    // space is ignorable from just the information in
+    // the DOM tree.
+        // -- You need to be able to distinguish whitespace
+        // that is #PCDATA from whitespace that isn't.  That requires
+        // DTD support, which won't be standardized until DOM Level 3.
+    return isIgnorable;
+  }
+
+  /**
+   * Get the first unparented node in the ancestor chain.
+   * @deprecated
+   *
+   * @param node Starting node, to specify which chain to chase
+   *
+   * @return the topmost ancestor.
+   */
+  public Node getRoot(Node node)
+  {
+
+    Node root = null;
+
+    while (node != null)
+    {
+      root = node;
+      node = getParentOfNode(node);
+    }
+
+    return root;
+  }
+
+  /**
+   * Get the root node of the document tree, regardless of
+   * whether or not the node passed in is a document node.
+   * <p>
+   * TODO: This doesn't handle DocumentFragments or "orphaned" subtrees
+   * -- it's currently returning ownerDocument even when the tree is
+   * not actually part of the main Document tree. We should either
+   * rewrite the description to say that it finds the Document node,
+   * or change the code to walk up the ancestor chain.
+
+   *
+   * @param n Node to be examined
+   *
+   * @return the Document node. Note that this is not the correct answer
+   * if n was (or was a child of) a DocumentFragment or an orphaned node,
+   * as can arise if the DOM has been edited rather than being generated
+   * by a parser.
+   */
+  public Node getRootNode(Node n)
+  {
+    int nt = n.getNodeType();
+    return ( (Node.DOCUMENT_NODE == nt) || (Node.DOCUMENT_FRAGMENT_NODE == nt) ) 
+           ? n : n.getOwnerDocument();
+  }
+
+  /**
+   * Test whether the given node is a namespace decl node. In DOM Level 2
+   * this can be done in a namespace-aware manner, but in Level 1 DOMs
+   * it has to be done by testing the node name.
+   *
+   * @param n Node to be examined.
+   *
+   * @return boolean -- true iff the node is an Attr whose name is 
+   * "xmlns" or has the "xmlns:" prefix.
+   */
+  public boolean isNamespaceNode(Node n)
+  {
+
+    if (Node.ATTRIBUTE_NODE == n.getNodeType())
+    {
+      String attrName = n.getNodeName();
+
+      return (attrName.startsWith("xmlns:") || attrName.equals("xmlns"));
+    }
+
+    return false;
+  }
+
+  /**
+   * Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
+   * parent for other nodes. 
+   * <p>
+   * Background: The DOM believes that you must be your Parent's
+   * Child, and thus Attrs don't have parents. XPath said that Attrs
+   * do have their owning Element as their parent. This function
+   * bridges the difference, either by using the DOM Level 2 ownerElement
+   * function or by using a "silly and expensive function" in Level 1
+   * DOMs.
+   * <p>
+   * (There's some discussion of future DOMs generalizing ownerElement 
+   * into ownerNode and making it work on all types of nodes. This
+   * still wouldn't help the users of Level 1 or Level 2 DOMs)
+   * <p>
+   *
+   * @param node Node whose XPath parent we want to obtain
+   *
+   * @return the parent of the node, or the ownerElement if it's an
+   * Attr node, or null if the node is an orphan.
+   *
+   * @throws RuntimeException if the Document has no root element.
+   * This can't arise if the Document was created
+   * via the DOM Level 2 factory methods, but is possible if other
+   * mechanisms were used to obtain it
+   */
+  public static Node getParentOfNode(Node node) throws RuntimeException
+  {
+    Node parent;
+    short nodeType = node.getNodeType();
+
+    if (Node.ATTRIBUTE_NODE == nodeType)
+    {
+      Document doc = node.getOwnerDocument();
+          /*
+      TBD:
+      if(null == doc)
+      {
+        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
+      }
+      */
+
+          // Given how expensive the tree walk may be, we should first ask 
+          // whether this DOM can answer the question for us. The additional
+          // test does slow down Level 1 DOMs slightly. DOMHelper2, which
+          // is currently specialized for Xerces, assumes it can use the
+          // Level 2 solution. We might want to have an intermediate stage,
+          // which would assume DOM Level 2 but not assume Xerces.
+          //
+          // (Shouldn't have to check whether impl is null in a compliant DOM,
+          // but let's be paranoid for a moment...)
+          DOMImplementation impl=doc.getImplementation();
+          if(impl!=null && impl.hasFeature("Core","2.0"))
+          {
+                  parent=((Attr)node).getOwnerElement();
+                  return parent;
+          }
+
+          // DOM Level 1 solution, as fallback. Hugely expensive. 
+
+      Element rootElem = doc.getDocumentElement();
+
+      if (null == rootElem)
+      {
+        throw new RuntimeException(
+          XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
+            null));  //"Attribute child does not have an owner document element!");
+      }
+
+      parent = locateAttrParent(rootElem, node);
+
+        }
+    else
+    {
+      parent = node.getParentNode();
+
+      // if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
+      // {
+      //   throw new RuntimeException("Child does not have parent!");
+      // }
+    }
+
+    return parent;
+  }
+
+  /**
+   * Given an ID, return the element. This can work only if the document
+   * is interpreted in the context of a DTD or Schema, since otherwise
+   * we don't know which attributes are or aren't IDs.
+   * <p>
+   * Note that DOM Level 1 had no ability to retrieve this information.
+   * DOM Level 2 introduced it but does not promise that it will be
+   * supported in all DOMs; those which can't support it will always
+   * return null.
+   * <p>
+   * TODO: getElementByID is currently unimplemented. Support DOM Level 2?
+   *
+   * @param id The unique identifier to be searched for.
+   * @param doc The document to search within.
+   * @return CURRENTLY HARDCODED TO NULL, but it should be:
+   * The node which has this unique identifier, or null if there
+   * is no such node or this DOM can't reliably recognize it.
+   */
+  public Element getElementByID(String id, Document doc)
+  {
+    return null;
+  }
+
+  /**
+   * The getUnparsedEntityURI function returns the URI of the unparsed
+   * entity with the specified name in the same document as the context
+   * node (see [3.3 Unparsed Entities]). It returns the empty string if
+   * there is no such entity.
+   * <p>
+   * XML processors may choose to use the System Identifier (if one
+   * is provided) to resolve the entity, rather than the URI in the
+   * Public Identifier. The details are dependent on the processor, and
+   * we would have to support some form of plug-in resolver to handle
+   * this properly. Currently, we simply return the System Identifier if
+   * present, and hope that it a usable URI or that our caller can
+   * map it to one.
+   * TODO: Resolve Public Identifiers... or consider changing function name.
+   * <p>
+   * If we find a relative URI 
+   * reference, XML expects it to be resolved in terms of the base URI 
+   * of the document. The DOM doesn't do that for us, and it isn't 
+   * entirely clear whether that should be done here; currently that's
+   * pushed up to a higher levelof our application. (Note that DOM Level 
+   * 1 didn't store the document's base URI.)
+   * TODO: Consider resolving Relative URIs.
+   * <p>
+   * (The DOM's statement that "An XML processor may choose to
+   * completely expand entities before the structure model is passed
+   * to the DOM" refers only to parsed entities, not unparsed, and hence
+   * doesn't affect this function.)
+   *
+   * @param name A string containing the Entity Name of the unparsed
+   * entity.
+   * @param doc Document node for the document to be searched.
+   *
+   * @return String containing the URI of the Unparsed Entity, or an
+   * empty string if no such entity exists.
+   */
+  public String getUnparsedEntityURI(String name, Document doc)
+  {
+
+    String url = "";
+    DocumentType doctype = doc.getDoctype();
+
+    if (null != doctype)
+    {
+      NamedNodeMap entities = doctype.getEntities();
+      if(null == entities)
+        return url;
+      Entity entity = (Entity) entities.getNamedItem(name);
+      if(null == entity)
+        return url;
+      
+      String notationName = entity.getNotationName();
+
+      if (null != notationName)  // then it's unparsed
+      {
+        // The draft says: "The XSLT processor may use the public 
+        // identifier to generate a URI for the entity instead of the URI 
+        // specified in the system identifier. If the XSLT processor does 
+        // not use the public identifier to generate the URI, it must use 
+        // the system identifier; if the system identifier is a relative 
+        // URI, it must be resolved into an absolute URI using the URI of 
+        // the resource containing the entity declaration as the base 
+        // URI [RFC2396]."
+        // So I'm falling a bit short here.
+        url = entity.getSystemId();
+
+        if (null == url)
+        {
+          url = entity.getPublicId();
+        }
+        else
+        {
+          // This should be resolved to an absolute URL, but that's hard 
+          // to do from here.
+        }        
+      }
+    }
+
+    return url;
+  }
+
+  /**
+   * Support for getParentOfNode; walks a DOM tree until it finds
+   * the Element which owns the Attr. This is hugely expensive, and
+   * if at all possible you should use the DOM Level 2 Attr.ownerElement()
+   * method instead.
+   *  <p>
+   * The DOM Level 1 developers expected that folks would keep track
+   * of the last Element they'd seen and could recover the info from
+   * that source. Obviously that doesn't work very well if the only
+   * information you've been presented with is the Attr. The DOM Level 2
+   * getOwnerElement() method fixes that, but only for Level 2 and
+   * later DOMs.
+   *
+   * @param elem Element whose subtree is to be searched for this Attr
+   * @param attr Attr whose owner is to be located.
+   *
+   * @return the first Element whose attribute list includes the provided
+   * attr. In modern DOMs, this will also be the only such Element. (Early
+   * DOMs had some hope that Attrs might be sharable, but this idea has
+   * been abandoned.)
+   */
+  private static Node locateAttrParent(Element elem, Node attr)
+  {
+
+    Node parent = null;
+
+        // This should only be called for Level 1 DOMs, so we don't have to
+        // worry about namespace issues. In later levels, it's possible
+        // for a DOM to have two Attrs with the same NodeName but
+        // different namespaces, and we'd need to get getAttributeNodeNS...
+        // but later levels also have Attr.getOwnerElement.
+        Attr check=elem.getAttributeNode(attr.getNodeName());
+        if(check==attr)
+                parent = elem;
+
+    if (null == parent)
+    {
+      for (Node node = elem.getFirstChild(); null != node;
+              node = node.getNextSibling())
+      {
+        if (Node.ELEMENT_NODE == node.getNodeType())
+        {
+          parent = locateAttrParent((Element) node, attr);
+
+          if (null != parent)
+            break;
+        }
+      }
+    }
+
+    return parent;
+  }
+
+  /**
+   * The factory object used for creating nodes
+   * in the result tree.
+   */
+  protected Document m_DOMFactory = null;
+
+  /**
+   * Store the factory object required to create DOM nodes
+   * in the result tree. In fact, that's just the result tree's
+   * Document node...
+   *
+   * @param domFactory The DOM Document Node within whose context
+   * the result tree will be built.
+   */
+  public void setDOMFactory(Document domFactory)
+  {
+    this.m_DOMFactory = domFactory;
+  }
+
+  /**
+   * Retrieve the factory object required to create DOM nodes
+   * in the result tree.
+   *
+   * @return The result tree's DOM Document Node.
+   */
+  public Document getDOMFactory()
+  {
+
+    if (null == this.m_DOMFactory)
+    {
+      this.m_DOMFactory = createDocument();
+    }
+
+    return this.m_DOMFactory;
+  }
+
+  /**
+   * Get the textual contents of the node. See
+   * getNodeData(Node,FastStringBuffer) for discussion of how
+   * whitespace nodes are handled.
+   *
+   * @param node DOM Node to be examined
+   * @return String containing a concatenation of all the 
+   * textual content within that node. 
+   * @see #getNodeData(Node,FastStringBuffer)
+   * 
+   */
+  public static String getNodeData(Node node)
+  {
+
+    FastStringBuffer buf = StringBufferPool.get();
+    String s;
+
+    try
+    {
+      getNodeData(node, buf);
+
+      s = (buf.length() > 0) ? buf.toString() : "";
+    }
+    finally
+    {
+      StringBufferPool.free(buf);
+    }
+
+    return s;
+  }
+
+  /**
+   * Retrieve the text content of a DOM subtree, appending it into a
+   * user-supplied FastStringBuffer object. Note that attributes are
+   * not considered part of the content of an element.
+   * <p>
+   * There are open questions regarding whitespace stripping. 
+   * Currently we make no special effort in that regard, since the standard
+   * DOM doesn't yet provide DTD-based information to distinguish
+   * whitespace-in-element-context from genuine #PCDATA. Note that we
+   * should probably also consider xml:space if/when we address this.
+   * DOM Level 3 may solve the problem for us.
+   *
+   * @param node Node whose subtree is to be walked, gathering the
+   * contents of all Text or CDATASection nodes.
+   * @param buf FastStringBuffer into which the contents of the text
+   * nodes are to be concatenated.
+   */
+  public static void getNodeData(Node node, FastStringBuffer buf)
+  {
+
+    switch (node.getNodeType())
+    {
+    case Node.DOCUMENT_FRAGMENT_NODE :
+    case Node.DOCUMENT_NODE :
+    case Node.ELEMENT_NODE :
+    {
+      for (Node child = node.getFirstChild(); null != child;
+              child = child.getNextSibling())
+      {
+        getNodeData(child, buf);
+      }
+    }
+    break;
+    case Node.TEXT_NODE :
+    case Node.CDATA_SECTION_NODE :
+      buf.append(node.getNodeValue());
+      break;
+    case Node.ATTRIBUTE_NODE :
+      buf.append(node.getNodeValue());
+      break;
+    case Node.PROCESSING_INSTRUCTION_NODE :
+      // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);        
+      break;
+    default :
+      // ignore
+      break;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/DOMOrder.java b/src/main/java/org/apache/xml/utils/DOMOrder.java
new file mode 100644
index 0000000..338fced
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/DOMOrder.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOMOrder.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * @deprecated Since the introduction of the DTM, this class will be removed.
+ * Nodes that implement this index can return a document order index.
+ * Eventually, this will be replaced by DOM 3 methods. 
+ * (compareDocumentOrder and/or compareTreePosition.)
+ */
+public interface DOMOrder
+{
+
+  /**
+   * Get the UID (document order index).
+   *
+   * @return integer whose relative value corresponds to document order
+   * -- that is, if node1.getUid()<node2.getUid(), node1 comes before
+   * node2, and if they're equal node1 and node2 are the same node. No
+   * promises are made beyond that.
+   */
+  public int getUid();
+}
diff --git a/src/main/java/org/apache/xml/utils/DefaultErrorHandler.java b/src/main/java/org/apache/xml/utils/DefaultErrorHandler.java
new file mode 100644
index 0000000..bcd3860
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/DefaultErrorHandler.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DefaultErrorHandler.java 524806 2007-04-02 15:51:39Z zongaro $
+ */
+package org.apache.xml.utils;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+/**
+ * Implement SAX error handler for default reporting.
+ * @xsl.usage general
+ */
+public class DefaultErrorHandler implements ErrorHandler, ErrorListener
+{
+  PrintWriter m_pw;
+
+  /**
+   * if this flag is set to true, we will rethrow the exception on
+   * the error() and fatalError() methods. If it is false, the errors 
+   * are reported to System.err. 
+   */
+  boolean m_throwExceptionOnError = true;
+
+  /**
+   * Constructor DefaultErrorHandler
+   */
+  public DefaultErrorHandler(PrintWriter pw)
+  {
+    m_pw = pw;
+  }
+  
+  /**
+   * Constructor DefaultErrorHandler
+   */
+  public DefaultErrorHandler(PrintStream pw)
+  {
+    m_pw = new PrintWriter(pw, true);
+  }
+  
+  /**
+   * Constructor DefaultErrorHandler
+   */
+  public DefaultErrorHandler()
+  {
+    this(true);
+  }
+
+  /**
+   * Constructor DefaultErrorHandler
+   */
+  public DefaultErrorHandler(boolean throwExceptionOnError)
+  {
+    // Defer creation of a PrintWriter until it's actually needed
+    m_throwExceptionOnError = throwExceptionOnError;
+  }
+
+  /**
+   * Retrieve <code>java.io.PrintWriter</code> to which errors are being
+   * directed.
+   * @return The <code>PrintWriter</code> installed via the constructor
+   *         or the default <code>PrintWriter</code>
+   */
+  public PrintWriter getErrorWriter() {
+    // Defer creating the java.io.PrintWriter until an error needs to be
+    // reported.
+    if (m_pw == null) {
+      m_pw = new PrintWriter(System.err, true);
+    }
+    return m_pw;
+  }
+
+  /**
+   * Receive notification of a warning.
+   *
+   * <p>SAX parsers will use this method to report conditions that
+   * are not errors or fatal errors as defined by the XML 1.0
+   * recommendation.  The default behaviour is to take no action.</p>
+   *
+   * <p>The SAX parser must continue to provide normal parsing events
+   * after invoking this method: it should still be possible for the
+   * application to process the document through to the end.</p>
+   *
+   * @param exception The warning information encapsulated in a
+   *                  SAX parse exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void warning(SAXParseException exception) throws SAXException
+  {
+    PrintWriter pw = getErrorWriter();
+
+    printLocation(pw, exception);
+    pw.println("Parser warning: " + exception.getMessage());
+  }
+
+  /**
+   * Receive notification of a recoverable error.
+   *
+   * <p>This corresponds to the definition of "error" in section 1.2
+   * of the W3C XML 1.0 Recommendation.  For example, a validating
+   * parser would use this callback to report the violation of a
+   * validity constraint.  The default behaviour is to take no
+   * action.</p>
+   *
+   * <p>The SAX parser must continue to provide normal parsing events
+   * after invoking this method: it should still be possible for the
+   * application to process the document through to the end.  If the
+   * application cannot do so, then the parser should report a fatal
+   * error even if the XML 1.0 recommendation does not require it to
+   * do so.</p>
+   *
+   * @param exception The error information encapsulated in a
+   *                  SAX parse exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void error(SAXParseException exception) throws SAXException
+  {
+    //printLocation(exception);
+    // getErrorWriter().println(exception.getMessage());
+
+    throw exception;
+  }
+
+  /**
+   * Receive notification of a non-recoverable error.
+   *
+   * <p>This corresponds to the definition of "fatal error" in
+   * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
+   * parser would use this callback to report the violation of a
+   * well-formedness constraint.</p>
+   *
+   * <p>The application must assume that the document is unusable
+   * after the parser has invoked this method, and should continue
+   * (if at all) only for the sake of collecting addition error
+   * messages: in fact, SAX parsers are free to stop reporting any
+   * other events once this method has been invoked.</p>
+   *
+   * @param exception The error information encapsulated in a
+   *                  SAX parse exception.
+   * @throws SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public void fatalError(SAXParseException exception) throws SAXException
+  {
+    // printLocation(exception);
+    // getErrorWriter().println(exception.getMessage());
+
+    throw exception;
+  }
+  
+  /**
+   * Receive notification of a warning.
+   *
+   * <p>SAX parsers will use this method to report conditions that
+   * are not errors or fatal errors as defined by the XML 1.0
+   * recommendation.  The default behaviour is to take no action.</p>
+   *
+   * <p>The SAX parser must continue to provide normal parsing events
+   * after invoking this method: it should still be possible for the
+   * application to process the document through to the end.</p>
+   *
+   * @param exception The warning information encapsulated in a
+   *                  SAX parse exception.
+   * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see javax.xml.transform.TransformerException
+   */
+  public void warning(TransformerException exception) throws TransformerException
+  {
+    PrintWriter pw = getErrorWriter();
+
+    printLocation(pw, exception);
+    pw.println(exception.getMessage());
+  }
+
+  /**
+   * Receive notification of a recoverable error.
+   *
+   * <p>This corresponds to the definition of "error" in section 1.2
+   * of the W3C XML 1.0 Recommendation.  For example, a validating
+   * parser would use this callback to report the violation of a
+   * validity constraint.  The default behaviour is to take no
+   * action.</p>
+   *
+   * <p>The SAX parser must continue to provide normal parsing events
+   * after invoking this method: it should still be possible for the
+   * application to process the document through to the end.  If the
+   * application cannot do so, then the parser should report a fatal
+   * error even if the XML 1.0 recommendation does not require it to
+   * do so.</p>
+   *
+   * @param exception The error information encapsulated in a
+   *                  SAX parse exception.
+   * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see javax.xml.transform.TransformerException
+   */
+  public void error(TransformerException exception) throws TransformerException
+  {
+    // If the m_throwExceptionOnError flag is true, rethrow the exception.
+    // Otherwise report the error to System.err.
+    if (m_throwExceptionOnError)
+      throw exception;
+    else
+    {
+      PrintWriter pw = getErrorWriter();
+
+      printLocation(pw, exception);
+      pw.println(exception.getMessage());
+    }
+  }
+
+  /**
+   * Receive notification of a non-recoverable error.
+   *
+   * <p>This corresponds to the definition of "fatal error" in
+   * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
+   * parser would use this callback to report the violation of a
+   * well-formedness constraint.</p>
+   *
+   * <p>The application must assume that the document is unusable
+   * after the parser has invoked this method, and should continue
+   * (if at all) only for the sake of collecting addition error
+   * messages: in fact, SAX parsers are free to stop reporting any
+   * other events once this method has been invoked.</p>
+   *
+   * @param exception The error information encapsulated in a
+   *                  SAX parse exception.
+   * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see javax.xml.transform.TransformerException
+   */
+  public void fatalError(TransformerException exception) throws TransformerException
+  {
+    // If the m_throwExceptionOnError flag is true, rethrow the exception.
+    // Otherwise report the error to System.err.
+    if (m_throwExceptionOnError)
+      throw exception;
+    else
+    {
+      PrintWriter pw = getErrorWriter();
+
+      printLocation(pw, exception);
+      pw.println(exception.getMessage());
+    }
+  }
+  
+  public static void ensureLocationSet(TransformerException exception)
+  {
+    // SourceLocator locator = exception.getLocator();
+    SourceLocator locator = null;
+    Throwable cause = exception;
+    
+    // Try to find the locator closest to the cause.
+    do
+    {
+      if(cause instanceof SAXParseException)
+      {
+        locator = new SAXSourceLocator((SAXParseException)cause);
+      }
+      else if (cause instanceof TransformerException)
+      {
+        SourceLocator causeLocator = ((TransformerException)cause).getLocator();
+        if(null != causeLocator)
+          locator = causeLocator;
+      }
+      
+      if(cause instanceof TransformerException)
+        cause = ((TransformerException)cause).getCause();
+      else if(cause instanceof SAXException)
+        cause = ((SAXException)cause).getException();
+      else
+        cause = null;
+    }
+    while(null != cause);
+    
+    exception.setLocator(locator);
+  }
+  
+  public static void printLocation(PrintStream pw, TransformerException exception)
+  {
+    printLocation(new PrintWriter(pw), exception);
+  }
+  
+  public static void printLocation(java.io.PrintStream pw, org.xml.sax.SAXParseException exception)
+  {
+    printLocation(new PrintWriter(pw), exception);
+  }
+  
+  public static void printLocation(PrintWriter pw, Throwable exception)
+  {
+    SourceLocator locator = null;
+    Throwable cause = exception;
+    
+    // Try to find the locator closest to the cause.
+    do
+    {
+      if(cause instanceof SAXParseException)
+      {
+        locator = new SAXSourceLocator((SAXParseException)cause);
+      }
+      else if (cause instanceof TransformerException)
+      {
+        SourceLocator causeLocator = ((TransformerException)cause).getLocator();
+        if(null != causeLocator)
+          locator = causeLocator;
+      }
+      if(cause instanceof TransformerException)
+        cause = ((TransformerException)cause).getCause();
+      else if(cause instanceof WrappedRuntimeException)
+        cause = ((WrappedRuntimeException)cause).getException();
+      else if(cause instanceof SAXException)
+        cause = ((SAXException)cause).getException();
+      else
+        cause = null;
+    }
+    while(null != cause);
+        
+    if(null != locator)
+    {
+      // getErrorWriter().println("Parser fatal error: "+exception.getMessage());
+      String id = (null != locator.getPublicId() )
+                  ? locator.getPublicId()
+                    : (null != locator.getSystemId())
+                      ? locator.getSystemId() : XMLMessages.createXMLMessage(XMLErrorResources.ER_SYSTEMID_UNKNOWN, null); //"SystemId Unknown";
+
+      pw.print(id + "; " +XMLMessages.createXMLMessage("line", null) + locator.getLineNumber()
+                         + "; " +XMLMessages.createXMLMessage("column", null) + locator.getColumnNumber()+"; ");
+    }
+    else
+      pw.print("("+XMLMessages.createXMLMessage(XMLErrorResources.ER_LOCATION_UNKNOWN, null)+")");
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/FastStringBuffer.java b/src/main/java/org/apache/xml/utils/FastStringBuffer.java
new file mode 100644
index 0000000..e79d4fe
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/FastStringBuffer.java
@@ -0,0 +1,1293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FastStringBuffer.java 469279 2006-10-30 21:18:02Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * Bare-bones, unsafe, fast string buffer. No thread-safety, no
+ * parameter range checking, exposed fields. Note that in typical
+ * applications, thread-safety of a StringBuffer is a somewhat
+ * dubious concept in any case.
+ * <p>
+ * Note that Stree and DTM used a single FastStringBuffer as a string pool,
+ * by recording start and length indices within this single buffer. This
+ * minimizes heap overhead, but of course requires more work when retrieving
+ * the data.
+ * <p>
+ * FastStringBuffer operates as a "chunked buffer". Doing so
+ * reduces the need to recopy existing information when an append
+ * exceeds the space available; we just allocate another chunk and
+ * flow across to it. (The array of chunks may need to grow,
+ * admittedly, but that's a much smaller object.) Some excess
+ * recopying may arise when we extract Strings which cross chunk
+ * boundaries; larger chunks make that less frequent.
+ * <p>
+ * The size values are parameterized, to allow tuning this code. In
+ * theory, Result Tree Fragments might want to be tuned differently 
+ * from the main document's text. 
+ * <p>
+ * %REVIEW% An experiment in self-tuning is
+ * included in the code (using nested FastStringBuffers to achieve
+ * variation in chunk sizes), but this implementation has proven to
+ * be problematic when data may be being copied from the FSB into itself.
+ * We should either re-architect that to make this safe (if possible)
+ * or remove that code and clean up for performance/maintainability reasons.
+ * <p>
+ */
+public class FastStringBuffer
+{
+  // If nonzero, forces the inial chunk size.
+  /**/static final int DEBUG_FORCE_INIT_BITS=0;
+  
+  	// %BUG% %REVIEW% *****PROBLEM SUSPECTED: If data from an FSB is being copied
+  	// back into the same FSB (variable set from previous variable, for example) 
+  	// and blocksize changes in mid-copy... there's risk of severe malfunction in 
+  	// the read process, due to how the resizing code re-jiggers storage. Arggh. 
+  	// If we want to retain the variable-size-block feature, we need to reconsider 
+  	// that issue. For now, I have forced us into fixed-size mode.
+    static final boolean DEBUG_FORCE_FIXED_CHUNKSIZE=true;
+
+	/** Manifest constant: Suppress leading whitespace.
+	 * This should be used when normalize-to-SAX is called for the first chunk of a
+	 * multi-chunk output, or one following unsuppressed whitespace in a previous
+	 * chunk.
+	 * @see #sendNormalizedSAXcharacters(org.xml.sax.ContentHandler,int,int)
+	 */
+	public static final int SUPPRESS_LEADING_WS=0x01;
+	
+	/** Manifest constant: Suppress trailing whitespace.
+	 * This should be used when normalize-to-SAX is called for the last chunk of a
+	 * multi-chunk output; it may have to be or'ed with SUPPRESS_LEADING_WS.
+	 */
+	public static final int SUPPRESS_TRAILING_WS=0x02;
+	
+	/** Manifest constant: Suppress both leading and trailing whitespace.
+	 * This should be used when normalize-to-SAX is called for a complete string.
+	 * (I'm not wild about the name of this one. Ideas welcome.)
+	 * @see #sendNormalizedSAXcharacters(org.xml.sax.ContentHandler,int,int)
+	 */
+	public static final int SUPPRESS_BOTH
+		= SUPPRESS_LEADING_WS | SUPPRESS_TRAILING_WS;
+
+	/** Manifest constant: Carry trailing whitespace of one chunk as leading 
+	 * whitespace of the next chunk. Used internally; I don't see any reason
+	 * to make it public right now.
+	 */
+	private static final int CARRY_WS=0x04;
+
+	/**
+   * Field m_chunkBits sets our chunking strategy, by saying how many
+   * bits of index can be used within a single chunk before flowing over
+   * to the next chunk. For example, if m_chunkbits is set to 15, each
+   * chunk can contain up to 2^15 (32K) characters  
+   */
+  int m_chunkBits = 15;
+
+  /**
+   * Field m_maxChunkBits affects our chunk-growth strategy, by saying what
+   * the largest permissible chunk size is in this particular FastStringBuffer
+   * hierarchy. 
+   */
+  int m_maxChunkBits = 15;
+
+  /**
+   * Field m_rechunkBits affects our chunk-growth strategy, by saying how
+   * many chunks should be allocated at one size before we encapsulate them
+   * into the first chunk of the next size up. For example, if m_rechunkBits
+   * is set to 3, then after 8 chunks at a given size we will rebundle
+   * them as the first element of a FastStringBuffer using a chunk size
+   * 8 times larger (chunkBits shifted left three bits).
+   */
+  int m_rebundleBits = 2;
+
+  /**
+   * Field m_chunkSize establishes the maximum size of one chunk of the array
+   * as 2**chunkbits characters.
+   * (Which may also be the minimum size if we aren't tuning for storage) 
+   */
+  int m_chunkSize;  // =1<<(m_chunkBits-1);
+
+  /**
+   * Field m_chunkMask is m_chunkSize-1 -- in other words, m_chunkBits
+   * worth of low-order '1' bits, useful for shift-and-mask addressing
+   * within the chunks. 
+   */
+  int m_chunkMask;  // =m_chunkSize-1;
+
+  /**
+   * Field m_array holds the string buffer's text contents, using an
+   * array-of-arrays. Note that this array, and the arrays it contains, may be
+   * reallocated when necessary in order to allow the buffer to grow;
+   * references to them should be considered to be invalidated after any
+   * append. However, the only time these arrays are directly exposed
+   * is in the sendSAXcharacters call.
+   */
+  char[][] m_array;
+
+  /**
+   * Field m_lastChunk is an index into m_array[], pointing to the last
+   * chunk of the Chunked Array currently in use. Note that additional
+   * chunks may actually be allocated, eg if the FastStringBuffer had
+   * previously been truncated or if someone issued an ensureSpace request.
+   * <p>
+   * The insertion point for append operations is addressed by the combination
+   * of m_lastChunk and m_firstFree.
+   */
+  int m_lastChunk = 0;
+
+  /**
+   * Field m_firstFree is an index into m_array[m_lastChunk][], pointing to
+   * the first character in the Chunked Array which is not part of the
+   * FastStringBuffer's current content. Since m_array[][] is zero-based,
+   * the length of that content can be calculated as
+   * (m_lastChunk<<m_chunkBits) + m_firstFree 
+   */
+  int m_firstFree = 0;
+
+  /**
+   * Field m_innerFSB, when non-null, is a FastStringBuffer whose total
+   * length equals m_chunkSize, and which replaces m_array[0]. This allows
+   * building a hierarchy of FastStringBuffers, where early appends use
+   * a smaller chunkSize (for less wasted memory overhead) but later
+   * ones use a larger chunkSize (for less heap activity overhead).
+   */
+  FastStringBuffer m_innerFSB = null;
+
+  /**
+   * Construct a FastStringBuffer, with allocation policy as per parameters.
+   * <p>
+   * For coding convenience, I've expressed both allocation sizes in terms of
+   * a number of bits. That's needed for the final size of a chunk,
+   * to permit fast and efficient shift-and-mask addressing. It's less critical
+   * for the inital size, and may be reconsidered.
+   * <p>
+   * An alternative would be to accept integer sizes and round to powers of two;
+   * that really doesn't seem to buy us much, if anything.
+   *
+   * @param initChunkBits Length in characters of the initial allocation
+   * of a chunk, expressed in log-base-2. (That is, 10 means allocate 1024
+   * characters.) Later chunks will use larger allocation units, to trade off
+   * allocation speed of large document against storage efficiency of small
+   * ones.
+   * @param maxChunkBits Number of character-offset bits that should be used for
+   * addressing within a chunk. Maximum length of a chunk is 2^chunkBits
+   * characters.
+   * @param rebundleBits Number of character-offset bits that addressing should
+   * advance before we attempt to take a step from initChunkBits to maxChunkBits
+   */
+  public FastStringBuffer(int initChunkBits, int maxChunkBits,
+                          int rebundleBits)
+  {
+    if(DEBUG_FORCE_INIT_BITS!=0) initChunkBits=DEBUG_FORCE_INIT_BITS;
+    
+    // %REVIEW%
+    // Should this force to larger value, or smaller? Smaller less efficient, but if
+    // someone requested variable mode it's because they care about storage space.
+    // On the other hand, given the other changes I'm making, odds are that we should
+    // adopt the larger size. Dither, dither, dither... This is just stopgap workaround
+    // anyway; we need a permanant solution.
+    //
+    if(DEBUG_FORCE_FIXED_CHUNKSIZE) maxChunkBits=initChunkBits;
+    //if(DEBUG_FORCE_FIXED_CHUNKSIZE) initChunkBits=maxChunkBits;
+
+    m_array = new char[16][];
+
+    // Don't bite off more than we're prepared to swallow!
+    if (initChunkBits > maxChunkBits)
+      initChunkBits = maxChunkBits;
+
+    m_chunkBits = initChunkBits;
+    m_maxChunkBits = maxChunkBits;
+    m_rebundleBits = rebundleBits;
+    m_chunkSize = 1 << (initChunkBits);
+    m_chunkMask = m_chunkSize - 1;
+    m_array[0] = new char[m_chunkSize];
+  }
+
+  /**
+   * Construct a FastStringBuffer, using a default rebundleBits value.
+   *
+   * NEEDSDOC @param initChunkBits
+   * NEEDSDOC @param maxChunkBits
+   */
+  public FastStringBuffer(int initChunkBits, int maxChunkBits)
+  {
+    this(initChunkBits, maxChunkBits, 2);
+  }
+
+  /**
+   * Construct a FastStringBuffer, using default maxChunkBits and
+   * rebundleBits values.
+   * <p>
+   * ISSUE: Should this call assert initial size, or fixed size?
+   * Now configured as initial, with a default for fixed.
+   *
+   * NEEDSDOC @param initChunkBits
+   */
+  public FastStringBuffer(int initChunkBits)
+  {
+    this(initChunkBits, 15, 2);
+  }
+
+  /**
+   * Construct a FastStringBuffer, using a default allocation policy.
+   */
+  public FastStringBuffer()
+  {
+
+    // 10 bits is 1K. 15 bits is 32K. Remember that these are character
+    // counts, so actual memory allocation unit is doubled for UTF-16 chars.
+    //
+    // For reference: In the original FastStringBuffer, we simply
+    // overallocated by blocksize (default 1KB) on each buffer-growth.
+    this(10, 15, 2);
+  }
+
+  /**
+   * Get the length of the list. Synonym for length().
+   *
+   * @return the number of characters in the FastStringBuffer's content.
+   */
+  public final int size()
+  {
+    return (m_lastChunk << m_chunkBits) + m_firstFree;
+  }
+
+  /**
+   * Get the length of the list. Synonym for size().
+   *
+   * @return the number of characters in the FastStringBuffer's content.
+   */
+  public final int length()
+  {
+    return (m_lastChunk << m_chunkBits) + m_firstFree;
+  }
+
+  /**
+   * Discard the content of the FastStringBuffer, and most of the memory
+   * that was allocated by it, restoring the initial state. Note that this
+   * may eventually be different from setLength(0), which see.
+   */
+  public final void reset()
+  {
+
+    m_lastChunk = 0;
+    m_firstFree = 0;
+
+    // Recover the original chunk size
+    FastStringBuffer innermost = this;
+
+    while (innermost.m_innerFSB != null)
+    {
+      innermost = innermost.m_innerFSB;
+    }
+
+    m_chunkBits = innermost.m_chunkBits;
+    m_chunkSize = innermost.m_chunkSize;
+    m_chunkMask = innermost.m_chunkMask;
+
+    // Discard the hierarchy
+    m_innerFSB = null;
+    m_array = new char[16][0];
+    m_array[0] = new char[m_chunkSize];
+  }
+
+  /**
+   * Directly set how much of the FastStringBuffer's storage is to be
+   * considered part of its content. This is a fast but hazardous
+   * operation. It is not protected against negative values, or values
+   * greater than the amount of storage currently available... and even
+   * if additional storage does exist, its contents are unpredictable.
+   * The only safe use for our setLength() is to truncate the FastStringBuffer
+   * to a shorter string.
+   *
+   * @param l New length. If l<0 or l>=getLength(), this operation will
+   * not report an error but future operations will almost certainly fail.
+   */
+  public final void setLength(int l)
+  {
+    m_lastChunk = l >>> m_chunkBits;
+
+    if (m_lastChunk == 0 && m_innerFSB != null)
+    {
+      // Replace this FSB with the appropriate inner FSB, truncated
+      m_innerFSB.setLength(l, this);
+    }
+    else
+    {
+      m_firstFree = l & m_chunkMask;
+      
+	  // There's an edge case if l is an exact multiple of m_chunkBits, which risks leaving
+	  // us pointing at the start of a chunk which has not yet been allocated. Rather than 
+	  // pay the cost of dealing with that in the append loops (more scattered and more
+	  // inner-loop), we correct it here by moving to the safe side of that
+	  // line -- as we would have left the indexes had we appended up to that point.
+      if(m_firstFree==0 && m_lastChunk>0)
+      {
+      	--m_lastChunk;
+      	m_firstFree=m_chunkSize;
+      }
+    }
+  }
+
+  /**
+   * Subroutine for the public setLength() method. Deals with the fact
+   * that truncation may require restoring one of the innerFSBs
+   *
+   * NEEDSDOC @param l
+   * NEEDSDOC @param rootFSB
+   */
+  private final void setLength(int l, FastStringBuffer rootFSB)
+  {
+
+    m_lastChunk = l >>> m_chunkBits;
+
+    if (m_lastChunk == 0 && m_innerFSB != null)
+    {
+      m_innerFSB.setLength(l, rootFSB);
+    }
+    else
+    {
+
+      // Undo encapsulation -- pop the innerFSB data back up to root.
+      // Inefficient, but attempts to keep the code simple.
+      rootFSB.m_chunkBits = m_chunkBits;
+      rootFSB.m_maxChunkBits = m_maxChunkBits;
+      rootFSB.m_rebundleBits = m_rebundleBits;
+      rootFSB.m_chunkSize = m_chunkSize;
+      rootFSB.m_chunkMask = m_chunkMask;
+      rootFSB.m_array = m_array;
+      rootFSB.m_innerFSB = m_innerFSB;
+      rootFSB.m_lastChunk = m_lastChunk;
+
+      // Finally, truncate this sucker.
+      rootFSB.m_firstFree = l & m_chunkMask;
+    }
+  }
+
+  /**
+   * Note that this operation has been somewhat deoptimized by the shift to a
+   * chunked array, as there is no factory method to produce a String object
+   * directly from an array of arrays and hence a double copy is needed.
+   * By using ensureCapacity we hope to minimize the heap overhead of building
+   * the intermediate StringBuffer.
+   * <p>
+   * (It really is a pity that Java didn't design String as a final subclass
+   * of MutableString, rather than having StringBuffer be a separate hierarchy.
+   * We'd avoid a <strong>lot</strong> of double-buffering.)
+   *
+   * @return the contents of the FastStringBuffer as a standard Java string.
+   */
+  public final String toString()
+  {
+
+    int length = (m_lastChunk << m_chunkBits) + m_firstFree;
+
+    return getString(new StringBuffer(length), 0, 0, length).toString();
+  }
+
+  /**
+   * Append a single character onto the FastStringBuffer, growing the
+   * storage if necessary.
+   * <p>
+   * NOTE THAT after calling append(), previously obtained
+   * references to m_array[][] may no longer be valid....
+   * though in fact they should be in this instance.
+   *
+   * @param value character to be appended.
+   */
+  public final void append(char value)
+  {
+    
+    char[] chunk;
+
+    // We may have preallocated chunks. If so, all but last should
+    // be at full size.
+
+    if (m_firstFree < m_chunkSize)  // Simplified test single-character-fits
+      chunk = m_array[m_lastChunk];
+    else
+    {
+
+      // Extend array?
+      int i = m_array.length;
+
+      if (m_lastChunk + 1 == i)
+      {
+        char[][] newarray = new char[i + 16][];
+
+        System.arraycopy(m_array, 0, newarray, 0, i);
+
+        m_array = newarray;
+      }
+
+      // Advance one chunk
+      chunk = m_array[++m_lastChunk];
+
+      if (chunk == null)
+      {
+
+        // Hierarchical encapsulation
+        if (m_lastChunk == 1 << m_rebundleBits
+                && m_chunkBits < m_maxChunkBits)
+        {
+
+          // Should do all the work of both encapsulating
+          // existing data and establishing new sizes/offsets
+          m_innerFSB = new FastStringBuffer(this);
+        }
+
+        // Add a chunk.
+        chunk = m_array[m_lastChunk] = new char[m_chunkSize];
+      }
+
+      m_firstFree = 0;
+    }
+
+    // Space exists in the chunk. Append the character.
+    chunk[m_firstFree++] = value;
+  }
+
+  /**
+   * Append the contents of a String onto the FastStringBuffer,
+   * growing the storage if necessary.
+   * <p>
+   * NOTE THAT after calling append(), previously obtained
+   * references to m_array[] may no longer be valid.
+   *
+   * @param value String whose contents are to be appended.
+   */
+  public final void append(String value)
+  {
+
+    if (value == null) 
+      return;
+    int strlen = value.length();
+
+    if (0 == strlen)
+      return;
+
+    int copyfrom = 0;
+    char[] chunk = m_array[m_lastChunk];
+    int available = m_chunkSize - m_firstFree;
+
+    // Repeat while data remains to be copied
+    while (strlen > 0)
+    {
+
+      // Copy what fits
+      if (available > strlen)
+        available = strlen;
+
+      value.getChars(copyfrom, copyfrom + available, m_array[m_lastChunk],
+                     m_firstFree);
+
+      strlen -= available;
+      copyfrom += available;
+
+      // If there's more left, allocate another chunk and continue
+      if (strlen > 0)
+      {
+
+        // Extend array?
+        int i = m_array.length;
+
+        if (m_lastChunk + 1 == i)
+        {
+          char[][] newarray = new char[i + 16][];
+
+          System.arraycopy(m_array, 0, newarray, 0, i);
+
+          m_array = newarray;
+        }
+
+        // Advance one chunk
+        chunk = m_array[++m_lastChunk];
+
+        if (chunk == null)
+        {
+
+          // Hierarchical encapsulation
+          if (m_lastChunk == 1 << m_rebundleBits
+                  && m_chunkBits < m_maxChunkBits)
+          {
+
+            // Should do all the work of both encapsulating
+            // existing data and establishing new sizes/offsets
+            m_innerFSB = new FastStringBuffer(this);
+          }
+
+          // Add a chunk. 
+          chunk = m_array[m_lastChunk] = new char[m_chunkSize];
+        }
+
+        available = m_chunkSize;
+        m_firstFree = 0;
+      }
+    }
+
+    // Adjust the insert point in the last chunk, when we've reached it.
+    m_firstFree += available;
+  }
+
+  /**
+   * Append the contents of a StringBuffer onto the FastStringBuffer,
+   * growing the storage if necessary.
+   * <p>
+   * NOTE THAT after calling append(), previously obtained
+   * references to m_array[] may no longer be valid.
+   *
+   * @param value StringBuffer whose contents are to be appended.
+   */
+  public final void append(StringBuffer value)
+  {
+
+    if (value == null) 
+      return;
+    int strlen = value.length();
+
+    if (0 == strlen)
+      return;
+
+    int copyfrom = 0;
+    char[] chunk = m_array[m_lastChunk];
+    int available = m_chunkSize - m_firstFree;
+
+    // Repeat while data remains to be copied
+    while (strlen > 0)
+    {
+
+      // Copy what fits
+      if (available > strlen)
+        available = strlen;
+
+      value.getChars(copyfrom, copyfrom + available, m_array[m_lastChunk],
+                     m_firstFree);
+
+      strlen -= available;
+      copyfrom += available;
+
+      // If there's more left, allocate another chunk and continue
+      if (strlen > 0)
+      {
+
+        // Extend array?
+        int i = m_array.length;
+
+        if (m_lastChunk + 1 == i)
+        {
+          char[][] newarray = new char[i + 16][];
+
+          System.arraycopy(m_array, 0, newarray, 0, i);
+
+          m_array = newarray;
+        }
+
+        // Advance one chunk
+        chunk = m_array[++m_lastChunk];
+
+        if (chunk == null)
+        {
+
+          // Hierarchical encapsulation
+          if (m_lastChunk == 1 << m_rebundleBits
+                  && m_chunkBits < m_maxChunkBits)
+          {
+
+            // Should do all the work of both encapsulating
+            // existing data and establishing new sizes/offsets
+            m_innerFSB = new FastStringBuffer(this);
+          }
+
+          // Add a chunk.
+          chunk = m_array[m_lastChunk] = new char[m_chunkSize];
+        }
+
+        available = m_chunkSize;
+        m_firstFree = 0;
+      }
+    }
+
+    // Adjust the insert point in the last chunk, when we've reached it.
+    m_firstFree += available;
+  }
+
+  /**
+   * Append part of the contents of a Character Array onto the
+   * FastStringBuffer,  growing the storage if necessary.
+   * <p>
+   * NOTE THAT after calling append(), previously obtained
+   * references to m_array[] may no longer be valid.
+   *
+   * @param chars character array from which data is to be copied
+   * @param start offset in chars of first character to be copied,
+   * zero-based.
+   * @param length number of characters to be copied
+   */
+  public final void append(char[] chars, int start, int length)
+  {
+
+    int strlen = length;
+
+    if (0 == strlen)
+      return;
+
+    int copyfrom = start;
+    char[] chunk = m_array[m_lastChunk];
+    int available = m_chunkSize - m_firstFree;
+
+    // Repeat while data remains to be copied
+    while (strlen > 0)
+    {
+
+      // Copy what fits
+      if (available > strlen)
+        available = strlen;
+
+      System.arraycopy(chars, copyfrom, m_array[m_lastChunk], m_firstFree,
+                       available);
+
+      strlen -= available;
+      copyfrom += available;
+
+      // If there's more left, allocate another chunk and continue
+      if (strlen > 0)
+      {
+
+        // Extend array?
+        int i = m_array.length;
+
+        if (m_lastChunk + 1 == i)
+        {
+          char[][] newarray = new char[i + 16][];
+
+          System.arraycopy(m_array, 0, newarray, 0, i);
+
+          m_array = newarray;
+        }
+
+        // Advance one chunk
+        chunk = m_array[++m_lastChunk];
+
+        if (chunk == null)
+        {
+
+          // Hierarchical encapsulation
+          if (m_lastChunk == 1 << m_rebundleBits
+                  && m_chunkBits < m_maxChunkBits)
+          {
+
+            // Should do all the work of both encapsulating
+            // existing data and establishing new sizes/offsets
+            m_innerFSB = new FastStringBuffer(this);
+          }
+
+          // Add a chunk.
+          chunk = m_array[m_lastChunk] = new char[m_chunkSize];
+        }
+
+        available = m_chunkSize;
+        m_firstFree = 0;
+      }
+    }
+
+    // Adjust the insert point in the last chunk, when we've reached it.
+    m_firstFree += available;
+  }
+
+  /**
+   * Append the contents of another FastStringBuffer onto
+   * this FastStringBuffer, growing the storage if necessary.
+   * <p>
+   * NOTE THAT after calling append(), previously obtained
+   * references to m_array[] may no longer be valid.
+   *
+   * @param value FastStringBuffer whose contents are
+   * to be appended.
+   */
+  public final void append(FastStringBuffer value)
+  {
+
+    // Complicating factor here is that the two buffers may use
+    // different chunk sizes, and even if they're the same we're
+    // probably on a different alignment due to previously appended
+    // data. We have to work through the source in bite-sized chunks.
+    if (value == null) 
+      return;
+    int strlen = value.length();
+
+    if (0 == strlen)
+      return;
+
+    int copyfrom = 0;
+    char[] chunk = m_array[m_lastChunk];
+    int available = m_chunkSize - m_firstFree;
+
+    // Repeat while data remains to be copied
+    while (strlen > 0)
+    {
+
+      // Copy what fits
+      if (available > strlen)
+        available = strlen;
+
+      int sourcechunk = (copyfrom + value.m_chunkSize - 1)
+                        >>> value.m_chunkBits;
+      int sourcecolumn = copyfrom & value.m_chunkMask;
+      int runlength = value.m_chunkSize - sourcecolumn;
+
+      if (runlength > available)
+        runlength = available;
+
+      System.arraycopy(value.m_array[sourcechunk], sourcecolumn,
+                       m_array[m_lastChunk], m_firstFree, runlength);
+
+      if (runlength != available)
+        System.arraycopy(value.m_array[sourcechunk + 1], 0,
+                         m_array[m_lastChunk], m_firstFree + runlength,
+                         available - runlength);
+
+      strlen -= available;
+      copyfrom += available;
+
+      // If there's more left, allocate another chunk and continue
+      if (strlen > 0)
+      {
+
+        // Extend array?
+        int i = m_array.length;
+
+        if (m_lastChunk + 1 == i)
+        {
+          char[][] newarray = new char[i + 16][];
+
+          System.arraycopy(m_array, 0, newarray, 0, i);
+
+          m_array = newarray;
+        }
+
+        // Advance one chunk
+        chunk = m_array[++m_lastChunk];
+
+        if (chunk == null)
+        {
+
+          // Hierarchical encapsulation
+          if (m_lastChunk == 1 << m_rebundleBits
+                  && m_chunkBits < m_maxChunkBits)
+          {
+
+            // Should do all the work of both encapsulating
+            // existing data and establishing new sizes/offsets
+            m_innerFSB = new FastStringBuffer(this);
+          }
+
+          // Add a chunk. 
+          chunk = m_array[m_lastChunk] = new char[m_chunkSize];
+        }
+
+        available = m_chunkSize;
+        m_firstFree = 0;
+      }
+    }
+
+    // Adjust the insert point in the last chunk, when we've reached it.
+    m_firstFree += available;
+  }
+
+  /**
+   * @return true if the specified range of characters are all whitespace,
+   * as defined by XMLCharacterRecognizer.
+   * <p>
+   * CURRENTLY DOES NOT CHECK FOR OUT-OF-RANGE.
+   *
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   */
+  public boolean isWhitespace(int start, int length)
+  {
+
+    int sourcechunk = start >>> m_chunkBits;
+    int sourcecolumn = start & m_chunkMask;
+    int available = m_chunkSize - sourcecolumn;
+    boolean chunkOK;
+
+    while (length > 0)
+    {
+      int runlength = (length <= available) ? length : available;
+
+      if (sourcechunk == 0 && m_innerFSB != null)
+        chunkOK = m_innerFSB.isWhitespace(sourcecolumn, runlength);
+      else
+        chunkOK = org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(
+          m_array[sourcechunk], sourcecolumn, runlength);
+
+      if (!chunkOK)
+        return false;
+
+      length -= runlength;
+
+      ++sourcechunk;
+
+      sourcecolumn = 0;
+      available = m_chunkSize;
+    }
+
+    return true;
+  }
+
+  /**
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   * @return a new String object initialized from the specified range of
+   * characters.
+   */
+  public String getString(int start, int length)
+  {
+    int startColumn = start & m_chunkMask;
+    int startChunk = start >>> m_chunkBits;
+    if (startColumn + length < m_chunkMask && m_innerFSB == null) {
+      return getOneChunkString(startChunk, startColumn, length);
+    }
+    return getString(new StringBuffer(length), startChunk, startColumn,
+                     length).toString();
+  }
+
+  protected String getOneChunkString(int startChunk, int startColumn,
+                                     int length) {
+    return new String(m_array[startChunk], startColumn, length);
+  }
+
+  /**
+   * @param sb StringBuffer to be appended to
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   * @return sb with the requested text appended to it
+   */
+  StringBuffer getString(StringBuffer sb, int start, int length)
+  {
+    return getString(sb, start >>> m_chunkBits, start & m_chunkMask, length);
+  }
+
+  /**
+   * Internal support for toString() and getString().
+   * PLEASE NOTE SIGNATURE CHANGE from earlier versions; it now appends into
+   * and returns a StringBuffer supplied by the caller. This simplifies
+   * m_innerFSB support.
+   * <p>
+   * Note that this operation has been somewhat deoptimized by the shift to a
+   * chunked array, as there is no factory method to produce a String object
+   * directly from an array of arrays and hence a double copy is needed.
+   * By presetting length we hope to minimize the heap overhead of building
+   * the intermediate StringBuffer.
+   * <p>
+   * (It really is a pity that Java didn't design String as a final subclass
+   * of MutableString, rather than having StringBuffer be a separate hierarchy.
+   * We'd avoid a <strong>lot</strong> of double-buffering.)
+   *
+   *
+   * @param sb
+   * @param startChunk
+   * @param startColumn
+   * @param length
+   * 
+   * @return the contents of the FastStringBuffer as a standard Java string.
+   */
+  StringBuffer getString(StringBuffer sb, int startChunk, int startColumn,
+                         int length)
+  {
+
+    int stop = (startChunk << m_chunkBits) + startColumn + length;
+    int stopChunk = stop >>> m_chunkBits;
+    int stopColumn = stop & m_chunkMask;
+
+    // Factored out
+    //StringBuffer sb=new StringBuffer(length);
+    for (int i = startChunk; i < stopChunk; ++i)
+    {
+      if (i == 0 && m_innerFSB != null)
+        m_innerFSB.getString(sb, startColumn, m_chunkSize - startColumn);
+      else
+        sb.append(m_array[i], startColumn, m_chunkSize - startColumn);
+
+      startColumn = 0;  // after first chunk
+    }
+
+    if (stopChunk == 0 && m_innerFSB != null)
+      m_innerFSB.getString(sb, startColumn, stopColumn - startColumn);
+    else if (stopColumn > startColumn)
+      sb.append(m_array[stopChunk], startColumn, stopColumn - startColumn);
+
+    return sb;
+  }
+
+  /**
+   * Get a single character from the string buffer.
+   *
+   *
+   * @param pos character position requested.
+   * @return A character from the requested position.
+   */
+  public char charAt(int pos)
+  {
+    int startChunk = pos >>> m_chunkBits;
+
+    if (startChunk == 0 && m_innerFSB != null)
+      return m_innerFSB.charAt(pos & m_chunkMask);
+    else
+      return m_array[startChunk][pos & m_chunkMask];
+  }
+
+  /**
+   * Sends the specified range of characters as one or more SAX characters()
+   * events.
+   * Note that the buffer reference passed to the ContentHandler may be
+   * invalidated if the FastStringBuffer is edited; it's the user's
+   * responsibility to manage access to the FastStringBuffer to prevent this
+   * problem from arising.
+   * <p>
+   * Note too that there is no promise that the output will be sent as a
+   * single call. As is always true in SAX, one logical string may be split
+   * across multiple blocks of memory and hence delivered as several
+   * successive events.
+   *
+   * @param ch SAX ContentHandler object to receive the event.
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   * @exception org.xml.sax.SAXException may be thrown by handler's
+   * characters() method.
+   */
+  public void sendSAXcharacters(
+          org.xml.sax.ContentHandler ch, int start, int length)
+            throws org.xml.sax.SAXException
+  {
+
+    int startChunk = start >>> m_chunkBits;
+    int startColumn = start & m_chunkMask;
+    if (startColumn + length < m_chunkMask && m_innerFSB == null) {
+        ch.characters(m_array[startChunk], startColumn, length);
+        return;
+    }
+    
+    int stop = start + length;
+    int stopChunk = stop >>> m_chunkBits;
+    int stopColumn = stop & m_chunkMask;
+
+    for (int i = startChunk; i < stopChunk; ++i)
+    {
+      if (i == 0 && m_innerFSB != null)
+        m_innerFSB.sendSAXcharacters(ch, startColumn,
+                                     m_chunkSize - startColumn);
+      else
+        ch.characters(m_array[i], startColumn, m_chunkSize - startColumn);
+
+      startColumn = 0;  // after first chunk
+    }
+
+    // Last, or only, chunk
+    if (stopChunk == 0 && m_innerFSB != null)
+      m_innerFSB.sendSAXcharacters(ch, startColumn, stopColumn - startColumn);
+    else if (stopColumn > startColumn)
+    {
+      ch.characters(m_array[stopChunk], startColumn,
+                    stopColumn - startColumn);
+    }
+  }
+  
+  /**
+   * Sends the specified range of characters as one or more SAX characters()
+   * events, normalizing the characters according to XSLT rules.
+   *
+   * @param ch SAX ContentHandler object to receive the event.
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   * @return normalization status to apply to next chunk (because we may
+   * have been called recursively to process an inner FSB):
+   * <dl>
+   * <dt>0</dt>
+   * <dd>if this output did not end in retained whitespace, and thus whitespace
+   * at the start of the following chunk (if any) should be converted to a
+   * single space.
+   * <dt>SUPPRESS_LEADING_WS</dt>
+   * <dd>if this output ended in retained whitespace, and thus whitespace
+   * at the start of the following chunk (if any) should be completely
+   * suppressed.</dd>
+   * </dd>
+   * </dl>
+   * @exception org.xml.sax.SAXException may be thrown by handler's
+   * characters() method.
+   */
+  public int sendNormalizedSAXcharacters(
+          org.xml.sax.ContentHandler ch, int start, int length)
+            throws org.xml.sax.SAXException
+  {
+	// This call always starts at the beginning of the 
+    // string being written out, either because it was called directly or
+    // because it was an m_innerFSB recursion. This is important since
+	// it gives us a well-known initial state for this flag:
+	int stateForNextChunk=SUPPRESS_LEADING_WS;
+
+    int stop = start + length;
+    int startChunk = start >>> m_chunkBits;
+    int startColumn = start & m_chunkMask;
+    int stopChunk = stop >>> m_chunkBits;
+    int stopColumn = stop & m_chunkMask;
+
+    for (int i = startChunk; i < stopChunk; ++i)
+    {
+      if (i == 0 && m_innerFSB != null)
+				stateForNextChunk=
+        m_innerFSB.sendNormalizedSAXcharacters(ch, startColumn,
+                                     m_chunkSize - startColumn);
+      else
+				stateForNextChunk=
+        sendNormalizedSAXcharacters(m_array[i], startColumn, 
+                                    m_chunkSize - startColumn, 
+																		ch,stateForNextChunk);
+
+      startColumn = 0;  // after first chunk
+    }
+
+    // Last, or only, chunk
+    if (stopChunk == 0 && m_innerFSB != null)
+			stateForNextChunk= // %REVIEW% Is this update really needed?
+      m_innerFSB.sendNormalizedSAXcharacters(ch, startColumn, stopColumn - startColumn);
+    else if (stopColumn > startColumn)
+    {
+			stateForNextChunk= // %REVIEW% Is this update really needed?
+      sendNormalizedSAXcharacters(m_array[stopChunk], 
+																	startColumn, stopColumn - startColumn,
+																	ch, stateForNextChunk | SUPPRESS_TRAILING_WS);
+    }
+		return stateForNextChunk;
+  }
+  
+  static final char[] SINGLE_SPACE = {' '};
+	  
+  /**
+   * Internal method to directly normalize and dispatch the character array.
+   * This version is aware of the fact that it may be called several times
+   * in succession if the data is made up of multiple "chunks", and thus
+   * must actively manage the handling of leading and trailing whitespace.
+   * 
+   * Note: The recursion is due to the possible recursion of inner FSBs.
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @param handler SAX ContentHandler object to receive the event.
+   * @param edgeTreatmentFlags How leading/trailing spaces should be handled. 
+   * This is a bitfield contining two flags, bitwise-ORed together:
+   * <dl>
+   * <dt>SUPPRESS_LEADING_WS</dt>
+   * <dd>When false, causes leading whitespace to be converted to a single
+   * space; when true, causes it to be discarded entirely.
+   * Should be set TRUE for the first chunk, and (in multi-chunk output)
+   * whenever the previous chunk ended in retained whitespace.</dd>
+   * <dt>SUPPRESS_TRAILING_WS</dt>
+   * <dd>When false, causes trailing whitespace to be converted to a single
+   * space; when true, causes it to be discarded entirely.
+   * Should be set TRUE for the last or only chunk.
+   * </dd>
+   * </dl>
+   * @return normalization status, as in the edgeTreatmentFlags parameter:
+   * <dl>
+   * <dt>0</dt>
+   * <dd>if this output did not end in retained whitespace, and thus whitespace
+   * at the start of the following chunk (if any) should be converted to a
+   * single space.
+   * <dt>SUPPRESS_LEADING_WS</dt>
+   * <dd>if this output ended in retained whitespace, and thus whitespace
+   * at the start of the following chunk (if any) should be completely
+   * suppressed.</dd>
+   * </dd>
+   * </dl>
+   *
+   * 
+   * @exception org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  static int sendNormalizedSAXcharacters(char ch[], 
+             int start, int length, 
+             org.xml.sax.ContentHandler handler,
+						 int edgeTreatmentFlags)
+          throws org.xml.sax.SAXException
+  {
+     boolean processingLeadingWhitespace =
+                       ((edgeTreatmentFlags & SUPPRESS_LEADING_WS) != 0);
+     boolean seenWhitespace = ((edgeTreatmentFlags & CARRY_WS) != 0);
+     int currPos = start;
+     int limit = start+length;
+
+     // Strip any leading spaces first, if required
+     if (processingLeadingWhitespace) {
+         for (; currPos < limit
+                && XMLCharacterRecognizer.isWhiteSpace(ch[currPos]);
+              currPos++) { }
+
+         // If we've only encountered leading spaces, the
+         // current state remains unchanged
+         if (currPos == limit) {
+             return edgeTreatmentFlags;
+         }
+     }
+
+     // If we get here, there are no more leading spaces to strip
+     while (currPos < limit) {
+         int startNonWhitespace = currPos;
+
+         // Grab a chunk of non-whitespace characters
+         for (; currPos < limit
+                && !XMLCharacterRecognizer.isWhiteSpace(ch[currPos]);
+              currPos++) { }
+
+         // Non-whitespace seen - emit them, along with a single
+         // space for any preceding whitespace characters
+         if (startNonWhitespace != currPos) {
+             if (seenWhitespace) {
+                 handler.characters(SINGLE_SPACE, 0, 1);
+                 seenWhitespace = false;
+             }
+             handler.characters(ch, startNonWhitespace,
+                                currPos - startNonWhitespace);
+         }
+
+         int startWhitespace = currPos;
+
+         // Consume any whitespace characters
+         for (; currPos < limit
+                && XMLCharacterRecognizer.isWhiteSpace(ch[currPos]);
+              currPos++) { }
+
+         if (startWhitespace != currPos) {
+             seenWhitespace = true;
+         }
+     }
+
+     return (seenWhitespace ? CARRY_WS : 0)
+            | (edgeTreatmentFlags & SUPPRESS_TRAILING_WS);
+  }
+
+  /**
+   * Directly normalize and dispatch the character array.
+   *
+   * @param ch The characters from the XML document.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   * @param handler SAX ContentHandler object to receive the event.
+   * @exception org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   */
+  public static void sendNormalizedSAXcharacters(char ch[], 
+             int start, int length, 
+             org.xml.sax.ContentHandler handler)
+          throws org.xml.sax.SAXException
+  {
+		sendNormalizedSAXcharacters(ch, start, length, 
+             handler, SUPPRESS_BOTH);
+	}
+		
+	/**
+   * Sends the specified range of characters as sax Comment.
+   * <p>
+   * Note that, unlike sendSAXcharacters, this has to be done as a single 
+   * call to LexicalHandler#comment.
+   *
+   * @param ch SAX LexicalHandler object to receive the event.
+   * @param start Offset of first character in the range.
+   * @param length Number of characters to send.
+   * @exception org.xml.sax.SAXException may be thrown by handler's
+   * characters() method.
+   */
+  public void sendSAXComment(
+          org.xml.sax.ext.LexicalHandler ch, int start, int length)
+            throws org.xml.sax.SAXException
+  {
+
+    // %OPT% Do it this way for now...
+    String comment = getString(start, length);
+    ch.comment(comment.toCharArray(), 0, length);
+  }
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  private void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
+  {
+    // %TBD% Joe needs to write this function.  Make public when implemented.
+  }
+
+  /**
+   * Encapsulation c'tor. After this is called, the source FastStringBuffer
+   * will be reset to use the new object as its m_innerFSB, and will have
+   * had its chunk size reset appropriately. IT SHOULD NEVER BE CALLED
+   * EXCEPT WHEN source.length()==1<<(source.m_chunkBits+source.m_rebundleBits)
+   *
+   * NEEDSDOC @param source
+   */
+  private FastStringBuffer(FastStringBuffer source)
+  {
+
+    // Copy existing information into new encapsulation
+    m_chunkBits = source.m_chunkBits;
+    m_maxChunkBits = source.m_maxChunkBits;
+    m_rebundleBits = source.m_rebundleBits;
+    m_chunkSize = source.m_chunkSize;
+    m_chunkMask = source.m_chunkMask;
+    m_array = source.m_array;
+    m_innerFSB = source.m_innerFSB;
+
+    // These have to be adjusted because we're calling just at the time
+    // when we would be about to allocate another chunk
+    m_lastChunk = source.m_lastChunk - 1;
+    m_firstFree = source.m_chunkSize;
+
+    // Establish capsule as the Inner FSB, reset chunk sizes/addressing
+    source.m_array = new char[16][];
+    source.m_innerFSB = this;
+
+    // Since we encapsulated just as we were about to append another
+    // chunk, return ready to create the chunk after the innerFSB
+    // -- 1, not 0.
+    source.m_lastChunk = 1;
+    source.m_firstFree = 0;
+    source.m_chunkBits += m_rebundleBits;
+    source.m_chunkSize = 1 << (source.m_chunkBits);
+    source.m_chunkMask = source.m_chunkSize - 1;
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/IntStack.java b/src/main/java/org/apache/xml/utils/IntStack.java
new file mode 100644
index 0000000..0212cef
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/IntStack.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IntStack.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.EmptyStackException;
+
+/**
+ * Implement a stack of simple integers.
+ *
+ * %OPT%
+ * This is currently based on IntVector, which permits fast acess but pays a
+ * heavy recopying penalty if/when its size is increased. If we expect deep
+ * stacks, we should consider a version based on ChunkedIntVector.
+ * @xsl.usage internal
+ */
+public class IntStack extends IntVector
+{
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public IntStack()
+  {
+    super();
+  }
+
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public IntStack(int blocksize)
+  {
+    super(blocksize);
+  }
+  
+  /**
+   * Copy constructor for IntStack
+   * 
+   * @param v IntStack to copy
+   */
+  public IntStack (IntStack v)
+  {
+  	super(v);
+  }
+
+  /**
+   * Pushes an item onto the top of this stack.
+   *
+   * @param   i   the int to be pushed onto this stack.
+   * @return  the <code>item</code> argument.
+   */
+  public int push(int i)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = i;
+
+    m_firstFree++;
+
+    return i;
+  }
+
+  /**
+   * Removes the object at the top of this stack and returns that
+   * object as the value of this function.
+   *
+   * @return     The object at the top of this stack.
+   */
+  public final int pop()
+  {
+    return m_map[--m_firstFree];
+  }
+
+  /**
+   * Quickly pops a number of items from the stack.
+   */
+
+  public final void quickPop(int n)
+  {
+    m_firstFree -= n;
+  }
+
+  /**
+   * Looks at the object at the top of this stack without removing it
+   * from the stack.
+   *
+   * @return     the object at the top of this stack.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public final int peek()
+  {
+    try {
+      return m_map[m_firstFree - 1];
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Looks at the object at the position the stack counting down n items.
+   *
+   * @param n The number of items down, indexed from zero.
+   * @return     the object at n items down.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public int peek(int n)
+  {
+    try {
+      return m_map[m_firstFree-(1+n)];
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Sets an object at a the top of the statck
+   *
+   *
+   * @param val object to set at the top
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public void setTop(int val)
+  {
+    try {
+      m_map[m_firstFree - 1] = val;
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Tests if this stack is empty.
+   *
+   * @return  <code>true</code> if this stack is empty;
+   *          <code>false</code> otherwise.
+   * @since   JDK1.0
+   */
+  public boolean empty()
+  {
+    return m_firstFree == 0;
+  }
+
+  /**
+   * Returns where an object is on this stack.
+   *
+   * @param   o   the desired object.
+   * @return  the distance from the top of the stack where the object is]
+   *          located; the return value <code>-1</code> indicates that the
+   *          object is not on the stack.
+   * @since   JDK1.0
+   */
+  public int search(int o)
+  {
+
+    int i = lastIndexOf(o);
+
+    if (i >= 0)
+    {
+      return size() - i;
+    }
+
+    return -1;
+  }
+  
+  /**
+   * Returns clone of current IntStack
+   * 
+   * @return clone of current IntStack
+   */
+  public Object clone()
+    throws CloneNotSupportedException
+  {
+  	return (IntStack) super.clone();
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/IntVector.java b/src/main/java/org/apache/xml/utils/IntVector.java
new file mode 100644
index 0000000..f815e4f
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/IntVector.java
@@ -0,0 +1,419 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IntVector.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A very simple table that stores a list of int.
+ *
+ * This version is based on a "realloc" strategy -- a simle array is
+ * used, and when more storage is needed, a larger array is obtained
+ * and all existing data is recopied into it. As a result, read/write
+ * access to existing nodes is O(1) fast but appending may be O(N**2)
+ * slow. See also SuballocatedIntVector.
+ * @xsl.usage internal
+ */
+public class IntVector implements Cloneable
+{
+
+  /** Size of blocks to allocate          */
+  protected int m_blocksize;
+
+  /** Array of ints          */
+  protected int m_map[]; // IntStack is trying to see this directly
+
+  /** Number of ints in array          */
+  protected int m_firstFree = 0;
+
+  /** Size of array          */
+  protected int m_mapSize;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public IntVector()
+  {
+
+    m_blocksize = 32;
+    m_mapSize = m_blocksize;
+    m_map = new int[m_blocksize];
+  }
+
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public IntVector(int blocksize)
+  {
+
+    m_blocksize = blocksize;
+    m_mapSize = blocksize;
+    m_map = new int[blocksize];
+  }
+  
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public IntVector(int blocksize, int increaseSize)
+  {
+
+    m_blocksize = increaseSize;
+    m_mapSize = blocksize;
+    m_map = new int[blocksize];
+  }
+
+  /**
+   * Copy constructor for IntVector
+   * 
+   * @param v Existing IntVector to copy
+   */
+  public IntVector(IntVector v)
+  {
+  	m_map = new int[v.m_mapSize];
+    m_mapSize = v.m_mapSize;
+    m_firstFree = v.m_firstFree;
+  	m_blocksize = v.m_blocksize;
+  	System.arraycopy(v.m_map, 0, m_map, 0, m_firstFree);
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return length of the list
+   */
+  public final int size()
+  {
+    return m_firstFree;
+  }
+  
+  /**
+   * Get the length of the list.
+   *
+   * @return length of the list
+   */
+  public final void setSize(int sz)
+  {
+    m_firstFree = sz;
+  }
+
+
+  /**
+   * Append a int onto the vector.
+   *
+   * @param value Int to add to the list 
+   */
+  public final void addElement(int value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+  
+  /**
+   * Append several int values onto the vector.
+   *
+   * @param value Int to add to the list 
+   */
+  public final void addElements(int value, int numberOfElements)
+  {
+
+    if ((m_firstFree + numberOfElements) >= m_mapSize)
+    {
+      m_mapSize += (m_blocksize+numberOfElements);
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    for (int i = 0; i < numberOfElements; i++) 
+    {
+      m_map[m_firstFree] = value;
+      m_firstFree++;
+    }
+  }
+  
+  /**
+   * Append several slots onto the vector, but do not set the values.
+   *
+   * @param numberOfElements Int to add to the list 
+   */
+  public final void addElements(int numberOfElements)
+  {
+
+    if ((m_firstFree + numberOfElements) >= m_mapSize)
+    {
+      m_mapSize += (m_blocksize+numberOfElements);
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+    
+    m_firstFree += numberOfElements;
+  }
+  
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * @param value Int to insert
+   * @param at Index of where to insert 
+   */
+  public final void insertElementAt(int value, int at)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    if (at <= (m_firstFree - 1))
+    {
+      System.arraycopy(m_map, at, m_map, at + 1, m_firstFree - at);
+    }
+
+    m_map[at] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   */
+  public final void removeAllElements()
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      m_map[i] = java.lang.Integer.MIN_VALUE;
+    }
+
+    m_firstFree = 0;
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s Int to remove from array
+   *
+   * @return True if the int was removed, false if it was not found
+   */
+  public final boolean removeElement(int s)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == s)
+      {
+        if ((i + 1) < m_firstFree)
+          System.arraycopy(m_map, i + 1, m_map, i - 1, m_firstFree - i);
+        else
+          m_map[i] = java.lang.Integer.MIN_VALUE;
+
+        m_firstFree--;
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i index of where to remove and int
+   */
+  public final void removeElementAt(int i)
+  {
+
+    if (i > m_firstFree)
+      System.arraycopy(m_map, i + 1, m_map, i, m_firstFree);
+    else
+      m_map[i] = java.lang.Integer.MIN_VALUE;
+
+    m_firstFree--;
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param value object to set
+   * @param index Index of where to set the object
+   */
+  public final void setElementAt(int value, int index)
+  {
+    m_map[index] = value;
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i index of object to get
+   *
+   * @return object at given index
+   */
+  public final int elementAt(int i)
+  {
+    return m_map[i];
+  }
+
+  /**
+   * Tell if the table contains the given node.
+   *
+   * @param s object to look for
+   *
+   * @return true if the object is in the list
+   */
+  public final boolean contains(int s)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == s)
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @param index Index of where to begin search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int indexOf(int elem, int index)
+  {
+
+    for (int i = index; i < m_firstFree; i++)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int indexOf(int elem)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int lastIndexOf(int elem)
+  {
+
+    for (int i = (m_firstFree - 1); i >= 0; i--)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+  
+  /**
+   * Returns clone of current IntVector
+   * 
+   * @return clone of current IntVector
+   */
+  public Object clone()
+    throws CloneNotSupportedException
+  {
+  	return new IntVector(this);
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/utils/NSInfo.java b/src/main/java/org/apache/xml/utils/NSInfo.java
new file mode 100644
index 0000000..70f4be2
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/NSInfo.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NSInfo.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * This class holds information about the namespace info
+ * of a node.  It is used to optimize namespace lookup in
+ * a generic DOM.
+ * @xsl.usage internal
+ */
+public class NSInfo
+{
+
+  /**
+   * Constructor NSInfo
+   *
+   *
+   * @param hasProcessedNS Flag indicating whether namespaces
+   * have been processed for this node 
+   * @param hasXMLNSAttrs Flag indicating whether this node
+   * has XMLNS attributes. 
+   */
+  public NSInfo(boolean hasProcessedNS, boolean hasXMLNSAttrs)
+  {
+
+    m_hasProcessedNS = hasProcessedNS;
+    m_hasXMLNSAttrs = hasXMLNSAttrs;
+    m_namespace = null;
+    m_ancestorHasXMLNSAttrs = ANCESTORXMLNSUNPROCESSED;
+  }
+
+  // Unused at the moment
+
+  /**
+   * Constructor NSInfo
+   *
+   *
+   * @param hasProcessedNS Flag indicating whether namespaces
+   * have been processed for this node 
+   * @param hasXMLNSAttrs Flag indicating whether this node
+   * has XMLNS attributes. 
+   * @param ancestorHasXMLNSAttrs Flag indicating whether one of this node's
+   * ancestor has XMLNS attributes.
+   */
+  public NSInfo(boolean hasProcessedNS, boolean hasXMLNSAttrs,
+                int ancestorHasXMLNSAttrs)
+  {
+
+    m_hasProcessedNS = hasProcessedNS;
+    m_hasXMLNSAttrs = hasXMLNSAttrs;
+    m_ancestorHasXMLNSAttrs = ancestorHasXMLNSAttrs;
+    m_namespace = null;
+  }
+
+  /**
+   * Constructor NSInfo
+   *
+   *
+   * @param namespace The namespace URI 
+   * @param hasXMLNSAttrs Flag indicating whether this node
+   * has XMLNS attributes.
+   */
+  public NSInfo(String namespace, boolean hasXMLNSAttrs)
+  {
+
+    m_hasProcessedNS = true;
+    m_hasXMLNSAttrs = hasXMLNSAttrs;
+    m_namespace = namespace;
+    m_ancestorHasXMLNSAttrs = ANCESTORXMLNSUNPROCESSED;
+  }
+
+  /** The namespace URI          */
+  public String m_namespace;
+
+  /** Flag indicating whether this node has an XMLNS attribute          */
+  public boolean m_hasXMLNSAttrs;
+
+  /** Flag indicating whether namespaces have been processed for this node */
+  public boolean m_hasProcessedNS;
+
+  /** Flag indicating whether one of this node's ancestor has an XMLNS attribute          */
+  public int m_ancestorHasXMLNSAttrs;
+
+  /** Constant for ancestors XMLNS atributes not processed          */
+  public static final int ANCESTORXMLNSUNPROCESSED = 0;
+
+  /** Constant indicating an ancestor has an XMLNS attribute           */
+  public static final int ANCESTORHASXMLNS = 1;
+
+  /** Constant indicating ancestors don't have an XMLNS attribute           */
+  public static final int ANCESTORNOXMLNS = 2;
+}
diff --git a/src/main/java/org/apache/xml/utils/NameSpace.java b/src/main/java/org/apache/xml/utils/NameSpace.java
new file mode 100644
index 0000000..0387df1
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/NameSpace.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NameSpace.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.Serializable;
+
+/**
+ * A representation of a namespace.  One of these will
+ * be pushed on the namespace stack for each
+ * element.
+ * @xsl.usage advanced
+ */
+public class NameSpace implements Serializable
+{
+    static final long serialVersionUID = 1471232939184881839L;
+
+  /** Next NameSpace element on the stack.
+   *  @serial             */
+  public NameSpace m_next = null;
+
+  /** Prefix of this NameSpace element.
+   *  @serial          */
+  public String m_prefix;
+
+  /** Namespace URI of this NameSpace element.
+   *  @serial           */
+  public String m_uri;  // if null, then Element namespace is empty.
+
+  /**
+   * Construct a namespace for placement on the
+   * result tree namespace stack.
+   *
+   * @param prefix Prefix of this element
+   * @param uri URI of  this element
+   */
+  public NameSpace(String prefix, String uri)
+  {
+    m_prefix = prefix;
+    m_uri = uri;
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/NamespaceSupport2.java b/src/main/java/org/apache/xml/utils/NamespaceSupport2.java
new file mode 100644
index 0000000..de7eb16
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/NamespaceSupport2.java
@@ -0,0 +1,749 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NamespaceSupport2.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.EmptyStackException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * Encapsulate Namespace tracking logic for use by SAX drivers.
+ *
+ * <p>This class is an attempt to rewrite the SAX NamespaceSupport
+ * "helper" class for improved efficiency. It can be used to track the
+ * namespace declarations currently in scope, providing lookup
+ * routines to map prefixes to URIs and vice versa.</p>
+ *
+ * <p>ISSUE: For testing purposes, I've extended NamespaceSupport even
+ * though I'm completely reasserting all behaviors and fields.
+ * Wasteful.... But SAX did not put an interface under that object and
+ * we seem to have written that SAX class into our APIs... and I don't
+ * want to argue with it right now. </p>
+ *
+ * @see org.xml.sax.helpers.NamespaceSupport
+ * */
+public class NamespaceSupport2
+    extends org.xml.sax.helpers.NamespaceSupport
+{
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private Context2 currentContext; // Current point on the double-linked stack
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constants.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * The XML Namespace as a constant.
+     *
+     * <p>This is the Namespace URI that is automatically mapped
+     * to the "xml" prefix.</p>
+     */
+    public final static String XMLNS =
+        "http://www.w3.org/XML/1998/namespace";
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructor.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new Namespace support object.
+     */
+    public NamespaceSupport2 ()
+    {
+        reset();
+    }
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Context management.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Reset this Namespace support object for reuse.
+     *
+     * <p>It is necessary to invoke this method before reusing the
+     * Namespace support object for a new session.</p>
+     */
+    public void reset ()
+    {
+        // Discarding the whole stack doesn't save us a lot versus
+        // creating a new NamespaceSupport. Do we care, or should we
+        // change this to just reset the root context?
+        currentContext = new Context2(null);
+        currentContext.declarePrefix("xml", XMLNS);
+    }
+
+
+    /**
+     * Start a new Namespace context.
+     *
+     * <p>Normally, you should push a new context at the beginning
+     * of each XML element: the new context will automatically inherit
+     * the declarations of its parent context, but it will also keep
+     * track of which declarations were made within this context.</p>
+     *
+     * <p>The Namespace support object always starts with a base context
+     * already in force: in this context, only the "xml" prefix is
+     * declared.</p>
+     *
+     * @see #popContext
+     */
+    public void pushContext ()
+    {
+        // JJK: Context has a parent pointer.
+        // That means we don't need a stack to pop.
+        // We may want to retain for reuse, but that can be done via
+        // a child pointer.
+
+        Context2 parentContext=currentContext;
+        currentContext = parentContext.getChild();
+        if (currentContext == null){
+                currentContext = new Context2(parentContext);
+            }
+        else{
+            // JJK: This will wipe out any leftover data
+            // if we're reusing a previously allocated Context.
+            currentContext.setParent(parentContext);
+        }
+    }
+
+
+    /**
+     * Revert to the previous Namespace context.
+     *
+     * <p>Normally, you should pop the context at the end of each
+     * XML element.  After popping the context, all Namespace prefix
+     * mappings that were previously in force are restored.</p>
+     *
+     * <p>You must not attempt to declare additional Namespace
+     * prefixes after popping a context, unless you push another
+     * context first.</p>
+     *
+     * @see #pushContext
+     */
+    public void popContext ()
+    {
+        Context2 parentContext=currentContext.getParent();
+        if(parentContext==null)
+            throw new EmptyStackException();
+        else
+            currentContext = parentContext;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Operations within a context.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Declare a Namespace prefix.
+     *
+     * <p>This method declares a prefix in the current Namespace
+     * context; the prefix will remain in force until this context
+     * is popped, unless it is shadowed in a descendant context.</p>
+     *
+     * <p>To declare a default Namespace, use the empty string.  The
+     * prefix must not be "xml" or "xmlns".</p>
+     *
+     * <p>Note that you must <em>not</em> declare a prefix after
+     * you've pushed and popped another Namespace.</p>
+     *
+     * <p>Note that there is an asymmetry in this library: while {@link
+     * #getPrefix getPrefix} will not return the default "" prefix,
+     * even if you have declared one; to check for a default prefix,
+     * you have to look it up explicitly using {@link #getURI getURI}.
+     * This asymmetry exists to make it easier to look up prefixes
+     * for attribute names, where the default prefix is not allowed.</p>
+     *
+     * @param prefix The prefix to declare, or null for the empty
+     *        string.
+     * @param uri The Namespace URI to associate with the prefix.
+     * @return true if the prefix was legal, false otherwise
+     * @see #processName
+     * @see #getURI
+     * @see #getPrefix
+     */
+    public boolean declarePrefix (String prefix, String uri)
+    {
+        if (prefix.equals("xml") || prefix.equals("xmlns")) {
+            return false;
+        } else {
+            currentContext.declarePrefix(prefix, uri);
+            return true;
+        }
+    }
+
+
+    /**
+     * Process a raw XML 1.0 name.
+     *
+     * <p>This method processes a raw XML 1.0 name in the current
+     * context by removing the prefix and looking it up among the
+     * prefixes currently declared.  The return value will be the
+     * array supplied by the caller, filled in as follows:</p>
+     *
+     * <dl>
+     * <dt>parts[0]</dt>
+     * <dd>The Namespace URI, or an empty string if none is
+     *  in use.</dd>
+     * <dt>parts[1]</dt>
+     * <dd>The local name (without prefix).</dd>
+     * <dt>parts[2]</dt>
+     * <dd>The original raw name.</dd>
+     * </dl>
+     *
+     * <p>All of the strings in the array will be internalized.  If
+     * the raw name has a prefix that has not been declared, then
+     * the return value will be null.</p>
+     *
+     * <p>Note that attribute names are processed differently than
+     * element names: an unprefixed element name will received the
+     * default Namespace (if any), while an unprefixed element name
+     * will not.</p>
+     *
+     * @param qName The raw XML 1.0 name to be processed.
+     * @param parts A string array supplied by the caller, capable of
+     *        holding at least three members.
+     * @param isAttribute A flag indicating whether this is an
+     *        attribute name (true) or an element name (false).
+     * @return The supplied array holding three internalized strings 
+     *        representing the Namespace URI (or empty string), the
+     *        local name, and the raw XML 1.0 name; or null if there
+     *        is an undeclared prefix.
+     * @see #declarePrefix
+     * @see java.lang.String#intern */
+    public String [] processName (String qName, String[] parts,
+                                  boolean isAttribute)
+    {
+        String[] name=currentContext.processName(qName, isAttribute);
+        if(name==null)
+            return null;
+
+        // JJK: This recopying is required because processName may return
+        // a cached result. I Don't Like It. *****
+        System.arraycopy(name,0,parts,0,3);
+        return parts;
+    }
+
+
+    /**
+     * Look up a prefix and get the currently-mapped Namespace URI.
+     *
+     * <p>This method looks up the prefix in the current context.
+     * Use the empty string ("") for the default Namespace.</p>
+     *
+     * @param prefix The prefix to look up.
+     * @return The associated Namespace URI, or null if the prefix
+     *         is undeclared in this context.
+     * @see #getPrefix
+     * @see #getPrefixes
+     */
+    public String getURI (String prefix)
+    {
+        return currentContext.getURI(prefix);
+    }
+
+
+    /**
+     * Return an enumeration of all prefixes currently declared.
+     *
+     * <p><strong>Note:</strong> if there is a default prefix, it will not be
+     * returned in this enumeration; check for the default prefix
+     * using the {@link #getURI getURI} with an argument of "".</p>
+     *
+     * @return An enumeration of all prefixes declared in the
+     *         current context except for the empty (default)
+     *         prefix.
+     * @see #getDeclaredPrefixes
+     * @see #getURI
+     */
+    public Enumeration getPrefixes ()
+    {
+        return currentContext.getPrefixes();
+    }
+
+
+    /**
+     * Return one of the prefixes mapped to a Namespace URI.
+     *
+     * <p>If more than one prefix is currently mapped to the same
+     * URI, this method will make an arbitrary selection; if you
+     * want all of the prefixes, use the {@link #getPrefixes}
+     * method instead.</p>
+     *
+     * <p><strong>Note:</strong> this will never return the empty
+     * (default) prefix; to check for a default prefix, use the {@link
+     * #getURI getURI} method with an argument of "".</p>
+     *
+     * @param uri The Namespace URI.
+     * @return One of the prefixes currently mapped to the URI supplied,
+     *         or null if none is mapped or if the URI is assigned to
+     *         the default Namespace.
+     * @see #getPrefixes(java.lang.String)
+     * @see #getURI */
+    public String getPrefix (String uri)
+    {
+        return currentContext.getPrefix(uri);
+    }
+
+
+    /**
+     * Return an enumeration of all prefixes currently declared for a URI.
+     *
+     * <p>This method returns prefixes mapped to a specific Namespace
+     * URI.  The xml: prefix will be included.  If you want only one
+     * prefix that's mapped to the Namespace URI, and you don't care 
+     * which one you get, use the {@link #getPrefix getPrefix}
+     *  method instead.</p>
+     *
+     * <p><strong>Note:</strong> the empty (default) prefix is
+     * <em>never</em> included in this enumeration; to check for the
+     * presence of a default Namespace, use the {@link #getURI getURI}
+     * method with an argument of "".</p>
+     *
+     * @param uri The Namespace URI.
+     * @return An enumeration of all prefixes declared in the
+     *         current context.
+     * @see #getPrefix
+     * @see #getDeclaredPrefixes
+     * @see #getURI */
+    public Enumeration getPrefixes (String uri)
+    {
+        // JJK: The old code involved creating a vector, filling it
+        // with all the matching prefixes, and then getting its
+        // elements enumerator. Wastes storage, wastes cycles if we
+        // don't actually need them all. Better to either implement
+        // a specific enumerator for these prefixes... or a filter
+        // around the all-prefixes enumerator, which comes out to
+        // roughly the same thing.
+        //
+        // **** Currently a filter. That may not be most efficient
+        // when I'm done restructuring storage!
+        return new PrefixForUriEnumerator(this,uri,getPrefixes());       
+    }
+    
+
+    /**
+     * Return an enumeration of all prefixes declared in this context.
+     *
+     * <p>The empty (default) prefix will be included in this 
+     * enumeration; note that this behaviour differs from that of
+     * {@link #getPrefix} and {@link #getPrefixes}.</p>
+     *
+     * @return An enumeration of all prefixes declared in this
+     *         context.
+     * @see #getPrefixes
+     * @see #getURI
+     */
+    public Enumeration getDeclaredPrefixes ()
+    {
+        return currentContext.getDeclaredPrefixes();
+    }
+
+
+
+}
+
+////////////////////////////////////////////////////////////////////
+// Local classes.
+// These were _internal_ classes... but in fact they don't have to be,
+// and may be more efficient if they aren't. 
+////////////////////////////////////////////////////////////////////
+
+/**
+ * Implementation of Enumeration filter, wrapped
+ * aroung the get-all-prefixes version of the operation. This is NOT
+ * necessarily the most efficient approach; finding the URI and then asking
+ * what prefixes apply to it might make much more sense.
+ */
+class PrefixForUriEnumerator implements Enumeration
+{
+    private Enumeration allPrefixes;
+    private String uri;
+    private String lookahead=null;
+    private NamespaceSupport2 nsup;
+     
+    // Kluge: Since one can't do a constructor on an
+    // anonymous class (as far as I know)...
+    PrefixForUriEnumerator(NamespaceSupport2 nsup,String uri, Enumeration allPrefixes)
+    {
+	this.nsup=nsup;
+        this.uri=uri;
+        this.allPrefixes=allPrefixes;
+    }
+        
+    public boolean hasMoreElements()
+    {
+        if(lookahead!=null)
+            return true;
+            
+        while(allPrefixes.hasMoreElements())
+            {
+                String prefix=(String)allPrefixes.nextElement();
+                if(uri.equals(nsup.getURI(prefix)))
+                    {
+                        lookahead=prefix;
+                        return true;
+                    }
+            }
+        return false;
+    }
+        
+    public Object nextElement()
+    {
+        if(hasMoreElements())
+            {
+                String tmp=lookahead;
+                lookahead=null;
+                return tmp;
+            }
+        else
+            throw new java.util.NoSuchElementException();
+    }
+}
+
+/**
+ * Internal class for a single Namespace context.
+ *
+ * <p>This module caches and reuses Namespace contexts, so the number allocated
+ * will be equal to the element depth of the document, not to the total
+ * number of elements (i.e. 5-10 rather than tens of thousands).</p>
+ */
+final class Context2 {
+
+    ////////////////////////////////////////////////////////////////
+    // Manefest Constants
+    ////////////////////////////////////////////////////////////////
+        
+    /**
+     * An empty enumeration.
+     */
+    private final static Enumeration EMPTY_ENUMERATION =
+        new Vector().elements();
+
+    ////////////////////////////////////////////////////////////////
+    // Protected state.
+    ////////////////////////////////////////////////////////////////
+        
+    Hashtable prefixTable;
+    Hashtable uriTable;
+    Hashtable elementNameTable;
+    Hashtable attributeNameTable;
+    String defaultNS = null;
+
+    ////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////
+        
+    private Vector declarations = null;
+    private boolean tablesDirty = false;
+    private Context2 parent = null;
+    private Context2 child = null;
+
+    /**
+     * Create a new Namespace context.
+     */
+    Context2 (Context2 parent)
+    {
+        if(parent==null)
+            {
+                prefixTable = new Hashtable();
+                uriTable = new Hashtable();
+                elementNameTable=null; 
+                attributeNameTable=null; 
+            }
+        else
+            setParent(parent);
+    }
+
+        
+    /**
+     * @returns The child Namespace context object, or null if this
+     * is the last currently on the chain.
+     */
+    Context2 getChild()
+    {
+        return child;
+    }
+        
+    /**
+     * @returns The parent Namespace context object, or null if this
+     * is the root.
+     */
+    Context2 getParent()
+    {
+        return parent;
+    }
+        
+    /**
+     * (Re)set the parent of this Namespace context.
+     * This is separate from the c'tor because it's re-applied
+     * when a Context2 is reused by push-after-pop.
+     *
+     * @param context The parent Namespace context object.
+     */
+    void setParent (Context2 parent)
+    {
+        this.parent = parent;
+        parent.child = this;        // JJK: Doubly-linked
+        declarations = null;
+        prefixTable = parent.prefixTable;
+        uriTable = parent.uriTable;
+        elementNameTable = parent.elementNameTable;
+        attributeNameTable = parent.attributeNameTable;
+        defaultNS = parent.defaultNS;
+        tablesDirty = false;
+    }
+        
+        
+    /**
+     * Declare a Namespace prefix for this context.
+     *
+     * @param prefix The prefix to declare.
+     * @param uri The associated Namespace URI.
+     * @see org.xml.sax.helpers.NamespaceSupport2#declarePrefix
+     */
+    void declarePrefix (String prefix, String uri)
+    {
+                                // Lazy processing...
+        if (!tablesDirty) {
+            copyTables();
+        }
+        if (declarations == null) {
+            declarations = new Vector();
+        }
+            
+        prefix = prefix.intern();
+        uri = uri.intern();
+        if ("".equals(prefix)) {
+            if ("".equals(uri)) {
+                defaultNS = null;
+            } else {
+                defaultNS = uri;
+            }
+        } else {
+            prefixTable.put(prefix, uri);
+            uriTable.put(uri, prefix); // may wipe out another prefix
+        }
+        declarations.addElement(prefix);
+    }
+
+
+    /**
+     * Process a raw XML 1.0 name in this context.
+     *
+     * @param qName The raw XML 1.0 name.
+     * @param isAttribute true if this is an attribute name.
+     * @return An array of three strings containing the
+     *         URI part (or empty string), the local part,
+     *         and the raw name, all internalized, or null
+     *         if there is an undeclared prefix.
+     * @see org.xml.sax.helpers.NamespaceSupport2#processName
+     */
+    String [] processName (String qName, boolean isAttribute)
+    {
+        String name[];
+        Hashtable table;
+            
+                                // Select the appropriate table.
+        if (isAttribute) {
+            if(elementNameTable==null)
+                elementNameTable=new Hashtable();
+            table = elementNameTable;
+        } else {
+            if(attributeNameTable==null)
+                attributeNameTable=new Hashtable();
+            table = attributeNameTable;
+        }
+            
+                                // Start by looking in the cache, and
+                                // return immediately if the name
+                                // is already known in this content
+        name = (String[])table.get(qName);
+        if (name != null) {
+            return name;
+        }
+            
+                                // We haven't seen this name in this
+                                // context before.
+        name = new String[3];
+        int index = qName.indexOf(':');
+            
+            
+                                // No prefix.
+        if (index == -1) {
+            if (isAttribute || defaultNS == null) {
+                name[0] = "";
+            } else {
+                name[0] = defaultNS;
+            }
+            name[1] = qName.intern();
+            name[2] = name[1];
+        }
+            
+                                // Prefix
+        else {
+            String prefix = qName.substring(0, index);
+            String local = qName.substring(index+1);
+            String uri;
+            if ("".equals(prefix)) {
+                uri = defaultNS;
+            } else {
+                uri = (String)prefixTable.get(prefix);
+            }
+            if (uri == null) {
+                return null;
+            }
+            name[0] = uri;
+            name[1] = local.intern();
+            name[2] = qName.intern();
+        }
+            
+                                // Save in the cache for future use.
+        table.put(name[2], name);
+        tablesDirty = true;
+        return name;
+    }
+        
+
+    /**
+     * Look up the URI associated with a prefix in this context.
+     *
+     * @param prefix The prefix to look up.
+     * @return The associated Namespace URI, or null if none is
+     *         declared.    
+     * @see org.xml.sax.helpers.NamespaceSupport2#getURI
+     */
+    String getURI (String prefix)
+    {
+        if ("".equals(prefix)) {
+            return defaultNS;
+        } else if (prefixTable == null) {
+            return null;
+        } else {
+            return (String)prefixTable.get(prefix);
+        }
+    }
+
+
+    /**
+     * Look up one of the prefixes associated with a URI in this context.
+     *
+     * <p>Since many prefixes may be mapped to the same URI,
+     * the return value may be unreliable.</p>
+     *
+     * @param uri The URI to look up.
+     * @return The associated prefix, or null if none is declared.
+     * @see org.xml.sax.helpers.NamespaceSupport2#getPrefix
+     */
+    String getPrefix (String uri)
+    {
+        if (uriTable == null) {
+            return null;
+        } else {
+            return (String)uriTable.get(uri);
+        }
+    }
+        
+        
+    /**
+     * Return an enumeration of prefixes declared in this context.
+     *
+     * @return An enumeration of prefixes (possibly empty).
+     * @see org.xml.sax.helpers.NamespaceSupport2#getDeclaredPrefixes
+     */
+    Enumeration getDeclaredPrefixes ()
+    {
+        if (declarations == null) {
+            return EMPTY_ENUMERATION;
+        } else {
+            return declarations.elements();
+        }
+    }
+        
+        
+    /**
+     * Return an enumeration of all prefixes currently in force.
+     *
+     * <p>The default prefix, if in force, is <em>not</em>
+     * returned, and will have to be checked for separately.</p>
+     *
+     * @return An enumeration of prefixes (never empty).
+     * @see org.xml.sax.helpers.NamespaceSupport2#getPrefixes
+     */
+    Enumeration getPrefixes ()
+    {
+        if (prefixTable == null) {
+            return EMPTY_ENUMERATION;
+        } else {
+            return prefixTable.keys();
+        }
+    }
+        
+    ////////////////////////////////////////////////////////////////
+    // Internal methods.
+    ////////////////////////////////////////////////////////////////
+
+    /**
+     * Copy on write for the internal tables in this context.
+     *
+     * <p>This class is optimized for the normal case where most
+     * elements do not contain Namespace declarations. In that case,
+     * the Context2 will share data structures with its parent.
+     * New tables are obtained only when new declarations are issued,
+     * so they can be popped off the stack.</p>
+     *
+     * <p> JJK: **** Alternative: each Context2 might declare
+     *  _only_ its local bindings, and delegate upward if not found.</p>
+     */     
+    private void copyTables ()
+    {
+        // Start by copying our parent's bindings
+        prefixTable = (Hashtable)prefixTable.clone();
+        uriTable = (Hashtable)uriTable.clone();
+
+        // Replace the caches with empty ones, rather than
+        // trying to determine which bindings should be flushed.
+        // As far as I can tell, these caches are never actually
+        // used in Xalan... More efficient to remove the whole
+        // cache system? ****
+        if(elementNameTable!=null)
+            elementNameTable=new Hashtable(); 
+        if(attributeNameTable!=null)
+            attributeNameTable=new Hashtable(); 
+        tablesDirty = true;
+    }
+
+}
+
+
+// end of NamespaceSupport2.java
diff --git a/src/main/java/org/apache/xml/utils/NodeConsumer.java b/src/main/java/org/apache/xml/utils/NodeConsumer.java
new file mode 100644
index 0000000..17e5c1c
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/NodeConsumer.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeConsumer.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import org.w3c.dom.Node;
+
+/**
+ * The tree walker will test for this interface, and call
+ * setOriginatingNode before calling the SAX event.  For creating
+ * DOM backpointers for things that are normally created via
+ * SAX events.
+ */
+public interface NodeConsumer
+{
+
+  /**
+   * Set the node that is originating the SAX event.
+   *
+   * @param n Reference to node that originated the current event.
+   */
+  public void setOriginatingNode(Node n);
+}
diff --git a/src/main/java/org/apache/xml/utils/NodeVector.java b/src/main/java/org/apache/xml/utils/NodeVector.java
new file mode 100644
index 0000000..c33d5c9
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/NodeVector.java
@@ -0,0 +1,739 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeVector.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.Serializable;
+
+import org.apache.xml.dtm.DTM;
+
+/**
+ * A very simple table that stores a list of Nodes.
+ * @xsl.usage internal
+ */
+public class NodeVector implements Serializable, Cloneable
+{
+    static final long serialVersionUID = -713473092200731870L;
+
+  /**
+   * Size of blocks to allocate.
+   *  @serial          
+   */
+  private int m_blocksize;
+
+  /**
+   * Array of nodes this points to.
+   *  @serial          
+   */
+  private int m_map[];
+
+  /**
+   * Number of nodes in this NodeVector.
+   *  @serial          
+   */
+  protected int m_firstFree = 0;
+
+  /**
+   * Size of the array this points to.
+   *  @serial           
+   */
+  private int m_mapSize;  // lazy initialization
+
+  /**
+   * Default constructor.
+   */
+  public NodeVector()
+  {
+    m_blocksize = 32;
+    m_mapSize = 0;
+  }
+
+  /**
+   * Construct a NodeVector, using the given block size.
+   *
+   * @param blocksize Size of blocks to allocate
+   */
+  public NodeVector(int blocksize)
+  {
+    m_blocksize = blocksize;
+    m_mapSize = 0;
+  }
+
+  /**
+   * Get a cloned LocPathIterator.
+   *
+   * @return A clone of this
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    NodeVector clone = (NodeVector) super.clone();
+
+    if ((null != this.m_map) && (this.m_map == clone.m_map))
+    {
+      clone.m_map = new int[this.m_map.length];
+
+      System.arraycopy(this.m_map, 0, clone.m_map, 0, this.m_map.length);
+    }
+
+    return clone;
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return Number of nodes in this NodeVector
+   */
+  public int size()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Append a Node onto the vector.
+   *
+   * @param value Node to add to the vector
+   */
+  public void addElement(int value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      if (null == m_map)
+      {
+        m_map = new int[m_blocksize];
+        m_mapSize = m_blocksize;
+      }
+      else
+      {
+        m_mapSize += m_blocksize;
+
+        int newMap[] = new int[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Append a Node onto the vector.
+   *
+   * @param value Node to add to the vector
+   */
+  public final void push(int value)
+  {
+
+    int ff = m_firstFree;
+
+    if ((ff + 1) >= m_mapSize)
+    {
+      if (null == m_map)
+      {
+        m_map = new int[m_blocksize];
+        m_mapSize = m_blocksize;
+      }
+      else
+      {
+        m_mapSize += m_blocksize;
+
+        int newMap[] = new int[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, ff + 1);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[ff] = value;
+
+    ff++;
+
+    m_firstFree = ff;
+  }
+
+  /**
+   * Pop a node from the tail of the vector and return the result.
+   *
+   * @return the node at the tail of the vector
+   */
+  public final int pop()
+  {
+
+    m_firstFree--;
+
+    int n = m_map[m_firstFree];
+
+    m_map[m_firstFree] = DTM.NULL;
+
+    return n;
+  }
+
+  /**
+   * Pop a node from the tail of the vector and return the
+   * top of the stack after the pop.
+   *
+   * @return The top of the stack after it's been popped
+   */
+  public final int popAndTop()
+  {
+
+    m_firstFree--;
+
+    m_map[m_firstFree] = DTM.NULL;
+
+    return (m_firstFree == 0) ? DTM.NULL : m_map[m_firstFree - 1];
+  }
+
+  /**
+   * Pop a node from the tail of the vector.
+   */
+  public final void popQuick()
+  {
+
+    m_firstFree--;
+
+    m_map[m_firstFree] = DTM.NULL;
+  }
+
+  /**
+   * Return the node at the top of the stack without popping the stack.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node at the top of the stack or null if stack is empty.
+   */
+  public final int peepOrNull()
+  {
+    return ((null != m_map) && (m_firstFree > 0))
+           ? m_map[m_firstFree - 1] : DTM.NULL;
+  }
+
+  /**
+   * Push a pair of nodes into the stack.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param v1 First node to add to vector
+   * @param v2 Second node to add to vector
+   */
+  public final void pushPair(int v1, int v2)
+  {
+
+    if (null == m_map)
+    {
+      m_map = new int[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+    else
+    {
+      if ((m_firstFree + 2) >= m_mapSize)
+      {
+        m_mapSize += m_blocksize;
+
+        int newMap[] = new int[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, m_firstFree);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[m_firstFree] = v1;
+    m_map[m_firstFree + 1] = v2;
+    m_firstFree += 2;
+  }
+
+  /**
+   * Pop a pair of nodes from the tail of the stack.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   */
+  public final void popPair()
+  {
+
+    m_firstFree -= 2;
+    m_map[m_firstFree] = DTM.NULL;
+    m_map[m_firstFree + 1] = DTM.NULL;
+  }
+
+  /**
+   * Set the tail of the stack to the given node.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param n Node to set at the tail of vector
+   */
+  public final void setTail(int n)
+  {
+    m_map[m_firstFree - 1] = n;
+  }
+
+  /**
+   * Set the given node one position from the tail.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param n Node to set
+   */
+  public final void setTailSub1(int n)
+  {
+    m_map[m_firstFree - 2] = n;
+  }
+
+  /**
+   * Return the node at the tail of the vector without popping
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node at the tail of the vector
+   */
+  public final int peepTail()
+  {
+    return m_map[m_firstFree - 1];
+  }
+
+  /**
+   * Return the node one position from the tail without popping.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node one away from the tail
+   */
+  public final int peepTailSub1()
+  {
+    return m_map[m_firstFree - 2];
+  }
+
+  /**
+   * Insert a node in order in the list.
+   *
+   * @param value Node to insert
+   */
+  public void insertInOrder(int value)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (value < m_map[i])
+      {
+        insertElementAt(value, i);
+
+        return;
+      }
+    }
+
+    addElement(value);
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * @param value Node to insert
+   * @param at Position where to insert
+   */
+  public void insertElementAt(int value, int at)
+  {
+
+    if (null == m_map)
+    {
+      m_map = new int[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+    else if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    if (at <= (m_firstFree - 1))
+    {
+      System.arraycopy(m_map, at, m_map, at + 1, m_firstFree - at);
+    }
+
+    m_map[at] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Append the nodes to the list.
+   *
+   * @param nodes NodeVector to append to this list
+   */
+  public void appendNodes(NodeVector nodes)
+  {
+
+    int nNodes = nodes.size();
+
+    if (null == m_map)
+    {
+      m_mapSize = nNodes + m_blocksize;
+      m_map = new int[m_mapSize];
+    }
+    else if ((m_firstFree + nNodes) >= m_mapSize)
+    {
+      m_mapSize += (nNodes + m_blocksize);
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + nNodes);
+
+      m_map = newMap;
+    }
+
+    System.arraycopy(nodes.m_map, 0, m_map, m_firstFree, nNodes);
+
+    m_firstFree += nNodes;
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   */
+  public void removeAllElements()
+  {
+
+    if (null == m_map)
+      return;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      m_map[i] = DTM.NULL;
+    }
+
+    m_firstFree = 0;
+  }
+  
+  /**
+   * Set the length to zero, but don't clear the array.
+   */
+  public void RemoveAllNoClear()
+  {
+
+    if (null == m_map)
+      return;
+
+    m_firstFree = 0;
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s Node to remove from the list
+   *
+   * @return True if the node was successfully removed
+   */
+  public boolean removeElement(int s)
+  {
+
+    if (null == m_map)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      int node = m_map[i];
+
+      if (node == s)
+      {
+        if (i > m_firstFree)
+          System.arraycopy(m_map, i + 1, m_map, i - 1, m_firstFree - i);
+        else
+          m_map[i] = DTM.NULL;
+
+        m_firstFree--;
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i Index of node to remove
+   */
+  public void removeElementAt(int i)
+  {
+
+    if (null == m_map)
+      return;
+
+    if (i > m_firstFree)
+      System.arraycopy(m_map, i + 1, m_map, i - 1, m_firstFree - i);
+    else
+      m_map[i] = DTM.NULL;
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param node Node to set
+   * @param index Index of where to set the node
+   */
+  public void setElementAt(int node, int index)
+  {
+
+    if (null == m_map)
+    {
+      m_map = new int[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+    
+    if(index == -1)
+    	addElement(node);
+
+    m_map[index] = node;
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i Index of node to get
+   *
+   * @return Node at specified index
+   */
+  public int elementAt(int i)
+  {
+
+    if (null == m_map)
+      return DTM.NULL;
+
+    return m_map[i];
+  }
+
+  /**
+   * Tell if the table contains the given node.
+   *
+   * @param s Node to look for
+   *
+   * @return True if the given node was found.
+   */
+  public boolean contains(int s)
+  {
+
+    if (null == m_map)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      int node = m_map[i];
+
+      if (node == s)
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for
+   * @param index Index of where to start the search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem, int index)
+  {
+
+    if (null == m_map)
+      return -1;
+
+    for (int i = index; i < m_firstFree; i++)
+    {
+      int node = m_map[i];
+
+      if (node == elem)
+        return i;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem)
+  {
+
+    if (null == m_map)
+      return -1;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      int node = m_map[i];
+
+      if (node == elem)
+        return i;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Sort an array using a quicksort algorithm.
+   *
+   * @param a The array to be sorted.
+   * @param lo0  The low index.
+   * @param hi0  The high index.
+   *
+   * @throws Exception
+   */
+  public void sort(int a[], int lo0, int hi0) throws Exception
+  {
+
+    int lo = lo0;
+    int hi = hi0;
+
+    // pause(lo, hi);
+    if (lo >= hi)
+    {
+      return;
+    }
+    else if (lo == hi - 1)
+    {
+
+      /*
+       *  sort a two element list by swapping if necessary
+       */
+      if (a[lo] > a[hi])
+      {
+        int T = a[lo];
+
+        a[lo] = a[hi];
+        a[hi] = T;
+      }
+
+      return;
+    }
+
+    /*
+     *  Pick a pivot and move it out of the way
+     */
+    int pivot = a[(lo + hi) / 2];
+
+    a[(lo + hi) / 2] = a[hi];
+    a[hi] = pivot;
+
+    while (lo < hi)
+    {
+
+      /*
+       *  Search forward from a[lo] until an element is found that
+       *  is greater than the pivot or lo >= hi
+       */
+      while (a[lo] <= pivot && lo < hi)
+      {
+        lo++;
+      }
+
+      /*
+       *  Search backward from a[hi] until element is found that
+       *  is less than the pivot, or lo >= hi
+       */
+      while (pivot <= a[hi] && lo < hi)
+      {
+        hi--;
+      }
+
+      /*
+       *  Swap elements a[lo] and a[hi]
+       */
+      if (lo < hi)
+      {
+        int T = a[lo];
+
+        a[lo] = a[hi];
+        a[hi] = T;
+
+        // pause();
+      }
+
+      // if (stopRequested) {
+      //    return;
+      // }
+    }
+
+    /*
+     *  Put the median in the "center" of the list
+     */
+    a[hi0] = a[hi];
+    a[hi] = pivot;
+
+    /*
+     *  Recursive calls, elements a[lo0] to a[lo-1] are less than or
+     *  equal to pivot, elements a[hi+1] to a[hi0] are greater than
+     *  pivot.
+     */
+    sort(a, lo0, lo - 1);
+    sort(a, hi + 1, hi0);
+  }
+
+  /**
+   * Sort an array using a quicksort algorithm.
+   *
+   * @throws Exception
+   */
+  public void sort() throws Exception
+  {
+    sort(m_map, 0, m_firstFree - 1);
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/ObjectFactory.java b/src/main/java/org/apache/xml/utils/ObjectFactory.java
new file mode 100644
index 0000000..cd41234
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/ObjectFactory.java
@@ -0,0 +1,661 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.utils;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id:  $
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services/";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                FileInputStream fis = null;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        fis = ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                    }
+	        } catch (Exception x) {
+	            fXalanProperties = null;
+	            fLastModified = -1;
+                    // assert(x instanceof FileNotFoundException
+	            //        || x instanceof SecurityException)
+	            // In both cases, ignore and continue w/ next location
+	        }
+                finally {
+                    // try to close the input stream if one was opened.
+                    if (fis != null) {
+                        try {
+                            fis.close();
+                        }
+                        // Ignore the exception.
+                        catch (IOException exc) {}
+                    }
+                }	            
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            FileInputStream fis = null;
+            try {
+                fis = ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+            finally {
+                // try to close the input stream if one was opened.
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    }
+                    // Ignore the exception.
+                    catch (IOException exc) {}
+                }
+            }               
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+        finally {
+            try {
+                // try to close the reader.
+                rd.close();
+            }
+            // Ignore the exception.
+            catch (IOException exc) {}
+        }          
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = 2036619216663421552L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xml/utils/ObjectPool.java b/src/main/java/org/apache/xml/utils/ObjectPool.java
new file mode 100644
index 0000000..43d71ab
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/ObjectPool.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectPool.java 475981 2006-11-16 23:35:53Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.ArrayList;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+
+/**
+ * Pool of object of a given type to pick from to help memory usage
+ * @xsl.usage internal
+ */
+public class ObjectPool implements java.io.Serializable
+{
+    static final long serialVersionUID = -8519013691660936643L;
+
+  /** Type of objects in this pool.
+   *  @serial          */
+  private final Class objectType;
+
+  /** Stack of given objects this points to.
+   *  @serial          */
+  private final ArrayList freeStack;
+
+  /**
+   * Constructor ObjectPool
+   *
+   * @param type Type of objects for this pool
+   */
+  public ObjectPool(Class type)
+  {
+    objectType = type;
+    freeStack = new ArrayList();
+  }
+  
+  /**
+   * Constructor ObjectPool
+   *
+   * @param className Fully qualified name of the type of objects for this pool.
+   */
+  public ObjectPool(String className)
+  {
+    try
+    {
+      objectType = ObjectFactory.findProviderClass(
+        className, ObjectFactory.findClassLoader(), true);
+    }
+    catch(ClassNotFoundException cnfe)
+    {
+      throw new WrappedRuntimeException(cnfe);
+    }
+    freeStack = new ArrayList();
+  }
+
+
+  /**
+   * Constructor ObjectPool
+   *
+   *
+   * @param type Type of objects for this pool
+   * @param size Size of vector to allocate
+   */
+  public ObjectPool(Class type, int size)
+  {
+    objectType = type;
+    freeStack = new ArrayList(size);
+  }
+
+  /**
+   * Constructor ObjectPool
+   *
+   */
+  public ObjectPool()
+  {
+    objectType = null;
+    freeStack = new ArrayList();
+  }
+
+  /**
+   * Get an instance of the given object in this pool if available
+   *
+   *
+   * @return an instance of the given object if available or null
+   */
+  public synchronized Object getInstanceIfFree()
+  {
+
+    // Check if the pool is empty.
+    if (!freeStack.isEmpty())
+    {
+
+      // Remove object from end of free pool.
+      Object result = freeStack.remove(freeStack.size() - 1);
+      return result;
+    }
+
+    return null;
+  }
+
+  /**
+   * Get an instance of the given object in this pool 
+   *
+   *
+   * @return An instance of the given object
+   */
+  public synchronized Object getInstance()
+  {
+
+    // Check if the pool is empty.
+    if (freeStack.isEmpty())
+    {
+
+      // Create a new object if so.
+      try
+      {
+        return objectType.newInstance();
+      }
+      catch (InstantiationException ex){}
+      catch (IllegalAccessException ex){}
+
+      // Throw unchecked exception for error in pool configuration.
+      throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_EXCEPTION_CREATING_POOL, null)); //"exception creating new instance for pool");
+    }
+    else
+    {
+
+      // Remove object from end of free pool.
+      Object result = freeStack.remove(freeStack.size() - 1);
+
+      return result;
+    }
+  }
+
+  /**
+   * Add an instance of the given object to the pool  
+   *
+   *
+   * @param obj Object to add.
+   */
+  public synchronized void freeInstance(Object obj)
+  {
+
+    // Make sure the object is of the correct type.
+    // Remove safety.  -sb
+    // if (objectType.isInstance(obj))
+    // {
+    freeStack.add(obj);
+    // }
+    // else
+    // {
+    //  throw new IllegalArgumentException("argument type invalid for pool");
+    // }
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/ObjectStack.java b/src/main/java/org/apache/xml/utils/ObjectStack.java
new file mode 100644
index 0000000..7b406f6
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/ObjectStack.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xml.utils;
+
+import java.util.EmptyStackException;
+
+/**
+ * Implement a stack of simple integers.
+ *
+ * %OPT%
+ * This is currently based on ObjectVector, which permits fast acess but pays a
+ * heavy recopying penalty if/when its size is increased. If we expect deep
+ * stacks, we should consider a version based on ChunkedObjectVector.
+ * @xsl.usage internal
+ */
+public class ObjectStack extends ObjectVector
+{
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public ObjectStack()
+  {
+    super();
+  }
+
+  /**
+   * Construct a ObjectVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public ObjectStack(int blocksize)
+  {
+    super(blocksize);
+  }
+
+  /**
+   * Copy constructor for ObjectStack
+   * 
+   * @param v ObjectStack to copy
+   */
+  public ObjectStack (ObjectStack v)
+  {
+  	super(v);
+  }
+  
+  /**
+   * Pushes an item onto the top of this stack.
+   *
+   * @param   i   the int to be pushed onto this stack.
+   * @return  the <code>item</code> argument.
+   */
+  public Object push(Object i)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      Object newMap[] = new Object[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = i;
+
+    m_firstFree++;
+
+    return i;
+  }
+
+  /**
+   * Removes the object at the top of this stack and returns that
+   * object as the value of this function.
+   *
+   * @return     The object at the top of this stack.
+   */
+  public Object pop()
+  {
+    Object val = m_map[--m_firstFree];
+    m_map[m_firstFree] = null;
+    
+    return val;
+  }
+
+  /**
+   * Quickly pops a number of items from the stack.
+   */
+
+  public void quickPop(int n)
+  {
+    m_firstFree -= n;
+  }
+
+  /**
+   * Looks at the object at the top of this stack without removing it
+   * from the stack.
+   *
+   * @return     the object at the top of this stack.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public Object peek()
+  {
+    try {
+      return m_map[m_firstFree - 1];
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Looks at the object at the position the stack counting down n items.
+   *
+   * @param n The number of items down, indexed from zero.
+   * @return     the object at n items down.
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public Object peek(int n)
+  {
+    try {
+      return m_map[m_firstFree-(1+n)];
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Sets an object at a the top of the statck
+   *
+   *
+   * @param val object to set at the top
+   * @throws  EmptyStackException  if this stack is empty.
+   */
+  public void setTop(Object val)
+  {
+    try {
+      m_map[m_firstFree - 1] = val;
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      throw new EmptyStackException();
+    }
+  }
+
+  /**
+   * Tests if this stack is empty.
+   *
+   * @return  <code>true</code> if this stack is empty;
+   *          <code>false</code> otherwise.
+   * @since   JDK1.0
+   */
+  public boolean empty()
+  {
+    return m_firstFree == 0;
+  }
+
+  /**
+   * Returns where an object is on this stack.
+   *
+   * @param   o   the desired object.
+   * @return  the distance from the top of the stack where the object is]
+   *          located; the return value <code>-1</code> indicates that the
+   *          object is not on the stack.
+   * @since   JDK1.0
+   */
+  public int search(Object o)
+  {
+
+    int i = lastIndexOf(o);
+
+    if (i >= 0)
+    {
+      return size() - i;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Returns clone of current ObjectStack
+   * 
+   * @return clone of current ObjectStack
+   */
+  public Object clone()
+    throws CloneNotSupportedException
+  {
+  	return (ObjectStack) super.clone();
+  }  
+  
+}
diff --git a/src/main/java/org/apache/xml/utils/ObjectVector.java b/src/main/java/org/apache/xml/utils/ObjectVector.java
new file mode 100644
index 0000000..9b6cbb2
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/ObjectVector.java
@@ -0,0 +1,431 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xml.utils;
+
+/**
+ * A very simple table that stores a list of objects.
+ *
+ * This version is based on a "realloc" strategy -- a simle array is
+ * used, and when more storage is needed, a larger array is obtained
+ * and all existing data is recopied into it. As a result, read/write
+ * access to existing nodes is O(1) fast but appending may be O(N**2)
+ * slow. 
+ * @xsl.usage internal
+ */
+public class ObjectVector implements Cloneable
+{
+
+  /** Size of blocks to allocate          */
+  protected int m_blocksize;
+
+  /** Array of objects          */
+  protected Object m_map[]; 
+
+  /** Number of ints in array          */
+  protected int m_firstFree = 0;
+
+  /** Size of array          */
+  protected int m_mapSize;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public ObjectVector()
+  {
+
+    m_blocksize = 32;
+    m_mapSize = m_blocksize;
+    m_map = new Object[m_blocksize];
+  }
+
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public ObjectVector(int blocksize)
+  {
+
+    m_blocksize = blocksize;
+    m_mapSize = blocksize;
+    m_map = new Object[blocksize];
+  }
+  
+  /**
+   * Construct a IntVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public ObjectVector(int blocksize, int increaseSize)
+  {
+
+    m_blocksize = increaseSize;
+    m_mapSize = blocksize;
+    m_map = new Object[blocksize];
+  }
+
+  /**
+   * Copy constructor for ObjectVector
+   * 
+   * @param v Existing ObjectVector to copy
+   */
+  public ObjectVector(ObjectVector v)
+  {
+  	m_map = new Object[v.m_mapSize];
+    m_mapSize = v.m_mapSize;
+    m_firstFree = v.m_firstFree;
+  	m_blocksize = v.m_blocksize;
+  	System.arraycopy(v.m_map, 0, m_map, 0, m_firstFree);
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return length of the list
+   */
+  public final int size()
+  {
+    return m_firstFree;
+  }
+  
+  /**
+   * Get the length of the list.
+   *
+   * @return length of the list
+   */
+  public final void setSize(int sz)
+  {
+    m_firstFree = sz;
+  }
+
+
+  /**
+   * Append an object onto the vector.
+   *
+   * @param value Object to add to the list 
+   */
+  public final void addElement(Object value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      Object newMap[] = new Object[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+  
+  /**
+   * Append several Object values onto the vector.
+   *
+   * @param value Object to add to the list 
+   */
+  public final void addElements(Object value, int numberOfElements)
+  {
+
+    if ((m_firstFree + numberOfElements) >= m_mapSize)
+    {
+      m_mapSize += (m_blocksize+numberOfElements);
+
+      Object newMap[] = new Object[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    for (int i = 0; i < numberOfElements; i++) 
+    {
+      m_map[m_firstFree] = value;
+      m_firstFree++;
+    }
+  }
+  
+  /**
+   * Append several slots onto the vector, but do not set the values.
+   *
+   * @param numberOfElements number of slots to append
+   */
+  public final void addElements(int numberOfElements)
+  {
+
+    if ((m_firstFree + numberOfElements) >= m_mapSize)
+    {
+      m_mapSize += (m_blocksize+numberOfElements);
+
+      Object newMap[] = new Object[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+    
+    m_firstFree += numberOfElements;
+  }
+  
+
+  /**
+   * Inserts the specified object in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * @param value Object to insert
+   * @param at Index of where to insert 
+   */
+  public final void insertElementAt(Object value, int at)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      Object newMap[] = new Object[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    if (at <= (m_firstFree - 1))
+    {
+      System.arraycopy(m_map, at, m_map, at + 1, m_firstFree - at);
+    }
+
+    m_map[at] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Remove all elements objects from the list. 
+   */
+  public final void removeAllElements()
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      m_map[i] = null;
+    }
+
+    m_firstFree = 0;
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s Object to remove from array
+   *
+   * @return True if the object was removed, false if it was not found
+   */
+  public final boolean removeElement(Object s)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == s)
+      {
+        if ((i + 1) < m_firstFree)
+          System.arraycopy(m_map, i + 1, m_map, i - 1, m_firstFree - i);
+        else
+          m_map[i] = null;
+
+        m_firstFree--;
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i index of where to remove an object
+   */
+  public final void removeElementAt(int i)
+  {
+
+    if (i > m_firstFree)
+      System.arraycopy(m_map, i + 1, m_map, i, m_firstFree);
+    else
+      m_map[i] = null;
+
+    m_firstFree--;
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param value object to set
+   * @param index Index of where to set the object
+   */
+  public final void setElementAt(Object value, int index)
+  {
+    m_map[index] = value;
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i index of object to get
+   *
+   * @return object at given index
+   */
+  public final Object elementAt(int i)
+  {
+    return m_map[i];
+  }
+
+  /**
+   * Tell if the table contains the given Object.
+   *
+   * @param s object to look for
+   *
+   * @return true if the object is in the list
+   */
+  public final boolean contains(Object s)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == s)
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @param index Index of where to begin search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int indexOf(Object elem, int index)
+  {
+
+    for (int i = index; i < m_firstFree; i++)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int indexOf(Object elem)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public final int lastIndexOf(Object elem)
+  {
+
+    for (int i = (m_firstFree - 1); i >= 0; i--)
+    {
+      if (m_map[i] == elem)
+        return i;
+    }
+
+    return java.lang.Integer.MIN_VALUE;
+  }
+  
+  /*
+   * Reset the array to the supplied size.  
+   * 
+   * @param size 
+   */
+  public final void setToSize(int size) {
+    
+    Object newMap[] = new Object[size];
+    
+    System.arraycopy(m_map, 0, newMap, 0, m_firstFree);
+    m_mapSize = size;
+
+    m_map = newMap;
+    
+  }  
+  
+  /**
+   * Returns clone of current ObjectVector
+   * 
+   * @return clone of current ObjectVector
+   */
+  public Object clone()
+    throws CloneNotSupportedException
+  {
+  	return new ObjectVector(this);
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/PrefixResolver.java b/src/main/java/org/apache/xml/utils/PrefixResolver.java
new file mode 100644
index 0000000..bdeb08a
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/PrefixResolver.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: PrefixResolver.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * The class that implements this interface can resolve prefixes to
+ * namespaces. Examples would include resolving the meaning of a
+ * prefix at a particular point in a document, or mapping the prefixes
+ * used in an XPath expression.
+ * @xsl.usage advanced
+ */
+public interface PrefixResolver
+{
+
+  /**
+   * Given a namespace, get the corrisponding prefix.  This assumes that
+   * the PrefixResolver holds its own namespace context, or is a namespace
+   * context itself.
+   *
+   * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
+   *
+   * @return The associated Namespace URI, or null if the prefix
+   *         is undeclared in this context.
+   */
+  String getNamespaceForPrefix(String prefix);
+
+  /**
+   * Given a namespace, get the corresponding prefix, based on the context node.
+   *
+   * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
+   * @param context The node context from which to look up the URI.
+   *
+   * @return The associated Namespace URI as a string, or null if the prefix
+   *         is undeclared in this context.
+   */
+  String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context);
+
+  /**
+   * Return the base identifier.
+   *
+   * @return The base identifier from where relative URIs should be absolutized, or null 
+   * if the base ID is unknown.
+   * <p>
+   * CAVEAT: Note that the base URI in an XML document may vary with where
+   * you are in the document, if part of the doc's contents were brought in
+   * via an external entity reference or if mechanisms such as xml:base have
+   * been used. Unless this PrefixResolver is bound to a specific portion of
+   * the document, or has been kept up to date via some other mechanism, it
+   * may not accurately reflect that context information.
+   */
+  public String getBaseIdentifier();
+  
+  public boolean handlesNullPrefixes();
+}
diff --git a/src/main/java/org/apache/xml/utils/PrefixResolverDefault.java b/src/main/java/org/apache/xml/utils/PrefixResolverDefault.java
new file mode 100644
index 0000000..38ced11
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/PrefixResolverDefault.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: PrefixResolverDefault.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * This class implements a generic PrefixResolver that
+ * can be used to perform prefix-to-namespace lookup
+ * for the XPath object.
+ * @xsl.usage general
+ */
+public class PrefixResolverDefault implements PrefixResolver
+{
+
+  /**
+   * The context to resolve the prefix from, if the context
+   * is not given.
+   */
+  Node m_context;
+
+  /**
+   * Construct a PrefixResolverDefault object.
+   * @param xpathExpressionContext The context from
+   * which XPath expression prefixes will be resolved.
+   * Warning: This will not work correctly if xpathExpressionContext
+   * is an attribute node.
+   */
+  public PrefixResolverDefault(Node xpathExpressionContext)
+  {
+    m_context = xpathExpressionContext;
+  }
+
+  /**
+   * Given a namespace, get the corrisponding prefix.  This assumes that
+   * the PrevixResolver hold's it's own namespace context, or is a namespace
+   * context itself.
+   * @param prefix Prefix to resolve.
+   * @return Namespace that prefix resolves to, or null if prefix
+   * is not bound.
+   */
+  public String getNamespaceForPrefix(String prefix)
+  {
+    return getNamespaceForPrefix(prefix, m_context);
+  }
+
+  /**
+   * Given a namespace, get the corrisponding prefix.
+   * Warning: This will not work correctly if namespaceContext
+   * is an attribute node.
+   * @param prefix Prefix to resolve.
+   * @param namespaceContext Node from which to start searching for a
+   * xmlns attribute that binds a prefix to a namespace.
+   * @return Namespace that prefix resolves to, or null if prefix
+   * is not bound.
+   */
+  public String getNamespaceForPrefix(String prefix,
+                                      org.w3c.dom.Node namespaceContext)
+  {
+
+    Node parent = namespaceContext;
+    String namespace = null;
+
+    if (prefix.equals("xml"))
+    {
+      namespace = Constants.S_XMLNAMESPACEURI;
+    }
+    else
+    {
+      int type;
+
+      while ((null != parent) && (null == namespace)
+             && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
+                 || (type == Node.ENTITY_REFERENCE_NODE)))
+      {
+        if (type == Node.ELEMENT_NODE)
+        {
+                if (parent.getNodeName().indexOf(prefix+":") == 0) 
+                        return parent.getNamespaceURI();                
+          NamedNodeMap nnm = parent.getAttributes();
+
+          for (int i = 0; i < nnm.getLength(); i++)
+          {
+            Node attr = nnm.item(i);
+            String aname = attr.getNodeName();
+            boolean isPrefix = aname.startsWith("xmlns:");
+
+            if (isPrefix || aname.equals("xmlns"))
+            {
+              int index = aname.indexOf(':');
+              String p = isPrefix ? aname.substring(index + 1) : "";
+
+              if (p.equals(prefix))
+              {
+                namespace = attr.getNodeValue();
+
+                break;
+              }
+            }
+          }
+        }
+
+        parent = parent.getParentNode();
+      }
+    }
+
+    return namespace;
+  }
+
+  /**
+   * Return the base identifier.
+   *
+   * @return null
+   */
+  public String getBaseIdentifier()
+  {
+    return null;
+  }
+	/**
+	 * @see PrefixResolver#handlesNullPrefixes()
+	 */
+	public boolean handlesNullPrefixes() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/apache/xml/utils/QName.java b/src/main/java/org/apache/xml/utils/QName.java
new file mode 100644
index 0000000..09fd90d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/QName.java
@@ -0,0 +1,709 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: QName.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+import org.w3c.dom.Element;
+
+/**
+ * Class to represent a qualified name: "The name of an internal XSLT object,
+ * specifically a named template (see [7 Named Templates]), a mode (see [6.7 Modes]),
+ * an attribute set (see [8.1.4 Named Attribute Sets]), a key (see [14.2 Keys]),
+ * a locale (see [14.3 Number Formatting]), a variable or a parameter (see
+ * [12 Variables and Parameters]) is specified as a QName. If it has a prefix,
+ * then the prefix is expanded into a URI reference using the namespace declarations
+ * in effect on the attribute in which the name occurs. The expanded name
+ * consisting of the local part of the name and the possibly null URI reference
+ * is used as the name of the object. The default namespace is not used for
+ * unprefixed names."
+ * @xsl.usage general
+ */
+public class QName implements java.io.Serializable
+{
+    static final long serialVersionUID = 467434581652829920L;
+
+  /**
+   * The local name.
+   * @serial
+   */
+  protected String _localName;
+
+  /**
+   * The namespace URI.
+   * @serial
+   */
+  protected String _namespaceURI;
+
+  /**
+   * The namespace prefix.
+   * @serial
+   */
+  protected String _prefix;
+
+  /**
+   * The XML namespace.
+   */
+  public static final String S_XMLNAMESPACEURI =
+    "http://www.w3.org/XML/1998/namespace";
+
+  /**
+   * The cached hashcode, which is calculated at construction time.
+   * @serial
+   */
+  private int m_hashCode;
+
+  /**
+   * Constructs an empty QName.
+   * 20001019: Try making this public, to support Serializable? -- JKESS
+   */
+  public QName(){}
+
+  /**
+   * Constructs a new QName with the specified namespace URI and
+   * local name.
+   *
+   * @param namespaceURI The namespace URI if known, or null
+   * @param localName The local name
+   */
+  public QName(String namespaceURI, String localName)
+  {
+    this(namespaceURI, localName, false); 
+  }
+
+  /**
+   * Constructs a new QName with the specified namespace URI and
+   * local name.
+   *
+   * @param namespaceURI The namespace URI if known, or null
+   * @param localName The local name
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String namespaceURI, String localName, boolean validate) 
+  {
+
+    // This check was already here.  So, for now, I will not add it to the validation
+    // that is done when the validate parameter is true.
+    if (localName == null)
+      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
+
+    if (validate) 
+    {
+        if (!XML11Char.isXML11ValidNCName(localName))
+        {
+            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+    }
+    
+    _namespaceURI = namespaceURI;
+    _localName = localName;
+    m_hashCode = toString().hashCode();
+  }
+  
+  /**
+   * Constructs a new QName with the specified namespace URI, prefix
+   * and local name.
+   *
+   * @param namespaceURI The namespace URI if known, or null
+   * @param prefix The namespace prefix is known, or null
+   * @param localName The local name
+   * 
+   */
+  public QName(String namespaceURI, String prefix, String localName)
+  {
+     this(namespaceURI, prefix, localName, false);
+  }
+  
+ /**
+   * Constructs a new QName with the specified namespace URI, prefix
+   * and local name.
+   *
+   * @param namespaceURI The namespace URI if known, or null
+   * @param prefix The namespace prefix is known, or null
+   * @param localName The local name
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String namespaceURI, String prefix, String localName, boolean validate)
+  {
+
+    // This check was already here.  So, for now, I will not add it to the validation
+    // that is done when the validate parameter is true.
+    if (localName == null)
+      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
+
+    if (validate)
+    {    
+        if (!XML11Char.isXML11ValidNCName(localName))
+        {
+            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+
+        if ((null != prefix) && (!XML11Char.isXML11ValidNCName(prefix)))
+        {
+            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_PREFIX_INVALID,null )); //"Argument 'prefix' not a valid NCName");
+        }
+
+    }
+    _namespaceURI = namespaceURI;
+    _prefix = prefix;
+    _localName = localName;
+    m_hashCode = toString().hashCode();
+  }  
+
+  /**
+   * Construct a QName from a string, without namespace resolution.  Good
+   * for a few odd cases.
+   *
+   * @param localName Local part of qualified name
+   * 
+   */
+  public QName(String localName)
+  {
+    this(localName, false);
+  }
+  
+  /**
+   * Construct a QName from a string, without namespace resolution.  Good
+   * for a few odd cases.
+   *
+   * @param localName Local part of qualified name
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String localName, boolean validate)
+  {
+
+    // This check was already here.  So, for now, I will not add it to the validation
+    // that is done when the validate parameter is true.
+    if (localName == null)
+      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
+
+    if (validate)
+    {    
+        if (!XML11Char.isXML11ValidNCName(localName))
+        {
+            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+    }
+    _namespaceURI = null;
+    _localName = localName;
+    m_hashCode = toString().hashCode();
+  }  
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace stack. The default namespace is
+   * not resolved.
+   *
+   * @param qname Qualified name to resolve
+   * @param namespaces Namespace stack to use to resolve namespace
+   */
+  public QName(String qname, Stack namespaces)
+  {
+    this(qname, namespaces, false);
+  }
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace stack. The default namespace is
+   * not resolved.
+   *
+   * @param qname Qualified name to resolve
+   * @param namespaces Namespace stack to use to resolve namespace
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String qname, Stack namespaces, boolean validate)
+  {
+
+    String namespace = null;
+    String prefix = null;
+    int indexOfNSSep = qname.indexOf(':');
+
+    if (indexOfNSSep > 0)
+    {
+      prefix = qname.substring(0, indexOfNSSep);
+
+      if (prefix.equals("xml"))
+      {
+        namespace = S_XMLNAMESPACEURI;
+      }
+      // Do we want this?
+      else if (prefix.equals("xmlns"))
+      {
+        return;
+      }
+      else
+      {
+        int depth = namespaces.size();
+
+        for (int i = depth - 1; i >= 0; i--)
+        {
+          NameSpace ns = (NameSpace) namespaces.elementAt(i);
+
+          while (null != ns)
+          {
+            if ((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
+            {
+              namespace = ns.m_uri;
+              i = -1;
+
+              break;
+            }
+
+            ns = ns.m_next;
+          }
+        }
+      }
+
+      if (null == namespace)
+      {
+        throw new RuntimeException(
+          XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
+            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
+      }
+    }
+
+    _localName = (indexOfNSSep < 0)
+                 ? qname : qname.substring(indexOfNSSep + 1);
+                 
+    if (validate)
+    {
+        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
+        {
+           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+    }                 
+    _namespaceURI = namespace;
+    _prefix = prefix;
+    m_hashCode = toString().hashCode();
+  }
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace context and prefix resolver. 
+   * The default namespace is not resolved.
+   * 
+   * @param qname Qualified name to resolve
+   * @param namespaceContext Namespace Context to use
+   * @param resolver Prefix resolver for this context
+   */
+  public QName(String qname, Element namespaceContext,
+               PrefixResolver resolver)
+  {
+      this(qname, namespaceContext, resolver, false);
+  }
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace context and prefix resolver. 
+   * The default namespace is not resolved.
+   * 
+   * @param qname Qualified name to resolve
+   * @param namespaceContext Namespace Context to use
+   * @param resolver Prefix resolver for this context
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String qname, Element namespaceContext,
+               PrefixResolver resolver, boolean validate)
+  {
+
+    _namespaceURI = null;
+
+    int indexOfNSSep = qname.indexOf(':');
+
+    if (indexOfNSSep > 0)
+    {
+      if (null != namespaceContext)
+      {
+        String prefix = qname.substring(0, indexOfNSSep);
+
+        _prefix = prefix;
+
+        if (prefix.equals("xml"))
+        {
+          _namespaceURI = S_XMLNAMESPACEURI;
+        }
+        
+        // Do we want this?
+        else if (prefix.equals("xmlns"))
+        {
+          return;
+        }
+        else
+        {
+          _namespaceURI = resolver.getNamespaceForPrefix(prefix,
+                  namespaceContext);
+        }
+
+        if (null == _namespaceURI)
+        {
+          throw new RuntimeException(
+            XMLMessages.createXMLMessage(
+              XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
+              new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
+        }
+      }
+      else
+      {
+
+        // TODO: error or warning...
+      }
+    }
+
+    _localName = (indexOfNSSep < 0)
+                 ? qname : qname.substring(indexOfNSSep + 1);
+
+    if (validate)
+    {
+        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
+        {
+           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+    }                 
+                 
+    m_hashCode = toString().hashCode();
+  }
+
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace stack. The default namespace is
+   * not resolved.
+   *
+   * @param qname Qualified name to resolve
+   * @param resolver Prefix resolver for this context
+   */
+  public QName(String qname, PrefixResolver resolver)
+  {
+    this(qname, resolver, false);
+  }
+
+  /**
+   * Construct a QName from a string, resolving the prefix
+   * using the given namespace stack. The default namespace is
+   * not resolved.
+   *
+   * @param qname Qualified name to resolve
+   * @param resolver Prefix resolver for this context
+   * @param validate If true the new QName will be validated and an IllegalArgumentException will
+   *                 be thrown if it is invalid.
+   */
+  public QName(String qname, PrefixResolver resolver, boolean validate)
+  {
+
+	String prefix = null;
+    _namespaceURI = null;
+
+    int indexOfNSSep = qname.indexOf(':');
+
+    if (indexOfNSSep > 0)
+    {
+      prefix = qname.substring(0, indexOfNSSep);
+
+      if (prefix.equals("xml"))
+      {
+        _namespaceURI = S_XMLNAMESPACEURI;
+      }
+      else
+      {
+        _namespaceURI = resolver.getNamespaceForPrefix(prefix);
+      }
+
+      if (null == _namespaceURI)
+      {
+        throw new RuntimeException(
+          XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
+            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
+      }
+      _localName = qname.substring(indexOfNSSep + 1);
+    }
+    else if (indexOfNSSep == 0) 
+    {
+      throw new RuntimeException(
+         XMLMessages.createXMLMessage(
+           XMLErrorResources.ER_NAME_CANT_START_WITH_COLON,
+           null));
+    }
+    else
+    {
+      _localName = qname;
+    }   
+                 
+    if (validate)
+    {
+        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
+        {
+           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
+            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
+        }
+    }                 
+
+              
+    m_hashCode = toString().hashCode();
+    _prefix = prefix;
+  }
+
+  /**
+   * Returns the namespace URI. Returns null if the namespace URI
+   * is not known.
+   *
+   * @return The namespace URI, or null
+   */
+  public String getNamespaceURI()
+  {
+    return _namespaceURI;
+  }
+
+  /**
+   * Returns the namespace prefix. Returns null if the namespace
+   * prefix is not known.
+   *
+   * @return The namespace prefix, or null
+   */
+  public String getPrefix()
+  {
+    return _prefix;
+  }
+
+  /**
+   * Returns the local part of the qualified name.
+   *
+   * @return The local part of the qualified name
+   */
+  public String getLocalName()
+  {
+    return _localName;
+  }
+
+  /**
+   * Return the string representation of the qualified name, using the 
+   * prefix if available, or the '{ns}foo' notation if not. Performs
+   * string concatenation, so beware of performance issues.
+   *
+   * @return the string representation of the namespace
+   */
+  public String toString()
+  {
+
+    return _prefix != null
+           ? (_prefix + ":" + _localName)
+           : (_namespaceURI != null
+              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
+  }
+  
+  /**
+   * Return the string representation of the qualified name using the 
+   * the '{ns}foo' notation. Performs
+   * string concatenation, so beware of performance issues.
+   *
+   * @return the string representation of the namespace
+   */
+  public String toNamespacedString()
+  {
+
+    return (_namespaceURI != null
+              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
+  }
+
+
+  /**
+   * Get the namespace of the qualified name.
+   *
+   * @return the namespace URI of the qualified name
+   */
+  public String getNamespace()
+  {
+    return getNamespaceURI();
+  }
+
+  /**
+   * Get the local part of the qualified name.
+   *
+   * @return the local part of the qualified name
+   */
+  public String getLocalPart()
+  {
+    return getLocalName();
+  }
+
+  /**
+   * Return the cached hashcode of the qualified name.
+   *
+   * @return the cached hashcode of the qualified name
+   */
+  public int hashCode()
+  {
+    return m_hashCode;
+  }
+
+  /**
+   * Override equals and agree that we're equal if
+   * the passed object is a string and it matches
+   * the name of the arg.
+   *
+   * @param ns Namespace URI to compare to
+   * @param localPart Local part of qualified name to compare to 
+   *
+   * @return True if the local name and uri match 
+   */
+  public boolean equals(String ns, String localPart)
+  {
+
+    String thisnamespace = getNamespaceURI();
+
+    return getLocalName().equals(localPart)
+           && (((null != thisnamespace) && (null != ns))
+               ? thisnamespace.equals(ns)
+               : ((null == thisnamespace) && (null == ns)));
+  }
+
+  /**
+   * Override equals and agree that we're equal if
+   * the passed object is a QName and it matches
+   * the name of the arg.
+   *
+   * @return True if the qualified names are equal
+   */
+  public boolean equals(Object object)
+  {
+
+    if (object == this)
+      return true;
+
+    if (object instanceof QName) {
+      QName qname = (QName) object;
+      String thisnamespace = getNamespaceURI();
+      String thatnamespace = qname.getNamespaceURI();
+
+      return getLocalName().equals(qname.getLocalName())
+             && (((null != thisnamespace) && (null != thatnamespace))
+                 ? thisnamespace.equals(thatnamespace)
+                 : ((null == thisnamespace) && (null == thatnamespace)));
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Given a string, create and return a QName object  
+   *
+   *
+   * @param name String to use to create QName
+   *
+   * @return a QName object
+   */
+  public static QName getQNameFromString(String name)
+  {
+
+    StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
+    QName qname;
+    String s1 = tokenizer.nextToken();
+    String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+
+    if (null == s2)
+      qname = new QName(null, s1);
+    else
+      qname = new QName(s1, s2);
+
+    return qname;
+  }
+
+  /**
+   * This function tells if a raw attribute name is a
+   * xmlns attribute.
+   *
+   * @param attRawName Raw name of attribute
+   *
+   * @return True if the attribute starts with or is equal to xmlns 
+   */
+  public static boolean isXMLNSDecl(String attRawName)
+  {
+
+    return (attRawName.startsWith("xmlns")
+            && (attRawName.equals("xmlns")
+                || attRawName.startsWith("xmlns:")));
+  }
+
+  /**
+   * This function tells if a raw attribute name is a
+   * xmlns attribute.
+   *
+   * @param attRawName Raw name of attribute
+   *
+   * @return Prefix of attribute
+   */
+  public static String getPrefixFromXMLNSDecl(String attRawName)
+  {
+
+    int index = attRawName.indexOf(':');
+
+    return (index >= 0) ? attRawName.substring(index + 1) : "";
+  }
+
+  /**
+   * Returns the local name of the given node.
+   *
+   * @param qname Input name
+   *
+   * @return Local part of the name if prefixed, or the given name if not
+   */
+  public static String getLocalPart(String qname)
+  {
+
+    int index = qname.indexOf(':');
+
+    return (index < 0) ? qname : qname.substring(index + 1);
+  }
+
+  /**
+   * Returns the local name of the given node.
+   *
+   * @param qname Input name 
+   *
+   * @return Prefix of name or empty string if none there   
+   */
+  public static String getPrefixPart(String qname)
+  {
+
+    int index = qname.indexOf(':');
+
+    return (index >= 0) ? qname.substring(0, index) : "";
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/SAXSourceLocator.java b/src/main/java/org/apache/xml/utils/SAXSourceLocator.java
new file mode 100644
index 0000000..39fe2a7
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/SAXSourceLocator.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SAXSourceLocator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.Serializable;
+
+import javax.xml.transform.SourceLocator;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * Class SAXSourceLocator extends org.xml.sax.helpers.LocatorImpl
+ * for the purpose of implementing the SourceLocator interface, 
+ * and thus can be both a SourceLocator and a SAX Locator.
+ */
+public class SAXSourceLocator extends LocatorImpl
+        implements SourceLocator, Serializable
+{
+    static final long serialVersionUID = 3181680946321164112L;
+  /** The SAX Locator object.
+   *  @serial
+   */
+  Locator m_locator;
+
+  /**
+   * Constructor SAXSourceLocator
+   *
+   */
+  public SAXSourceLocator(){}
+
+  /**
+   * Constructor SAXSourceLocator
+   *
+   *
+   * @param locator Source locator
+   */
+  public SAXSourceLocator(Locator locator)
+  {
+    m_locator = locator;
+    this.setColumnNumber(locator.getColumnNumber());
+    this.setLineNumber(locator.getLineNumber());
+    this.setPublicId(locator.getPublicId());
+    this.setSystemId(locator.getSystemId());
+  }
+  
+  /**
+   * Constructor SAXSourceLocator
+   *
+   *
+   * @param locator Source locator
+   */
+  public SAXSourceLocator(javax.xml.transform.SourceLocator locator)
+  {
+    m_locator = null;
+    this.setColumnNumber(locator.getColumnNumber());
+    this.setLineNumber(locator.getLineNumber());
+    this.setPublicId(locator.getPublicId());
+    this.setSystemId(locator.getSystemId());
+  }
+
+  
+  /**
+   * Constructor SAXSourceLocator
+   *
+   *
+   * @param spe SAXParseException exception.
+   */
+  public SAXSourceLocator(SAXParseException spe)
+  {
+    this.setLineNumber( spe.getLineNumber() );
+    this.setColumnNumber( spe.getColumnNumber() );
+    this.setPublicId( spe.getPublicId() );
+    this.setSystemId( spe.getSystemId() );
+  }
+  
+  /**
+   * Return the public identifier for the current document event.
+   *
+   * <p>The return value is the public identifier of the document
+   * entity or of the external parsed entity in which the markup
+   * triggering the event appears.</p>
+   *
+   * @return A string containing the public identifier, or
+   *         null if none is available.
+   * @see #getSystemId
+   */
+  public String getPublicId()
+  {
+    return (null == m_locator) ? super.getPublicId() : m_locator.getPublicId();
+  }
+
+  /**
+   * Return the system identifier for the current document event.
+   *
+   * <p>The return value is the system identifier of the document
+   * entity or of the external parsed entity in which the markup
+   * triggering the event appears.</p>
+   *
+   * <p>If the system identifier is a URL, the parser must resolve it
+   * fully before passing it to the application.</p>
+   *
+   * @return A string containing the system identifier, or null
+   *         if none is available.
+   * @see #getPublicId
+   */
+  public String getSystemId()
+  {
+    return (null == m_locator) ? super.getSystemId() : m_locator.getSystemId();
+  }
+  
+  /**
+   * Return the line number where the current document event ends.
+   *
+   * <p><strong>Warning:</strong> The return value from the method
+   * is intended only as an approximation for the sake of error
+   * reporting; it is not intended to provide sufficient information
+   * to edit the character content of the original XML document.</p>
+   *
+   * <p>The return value is an approximation of the line number
+   * in the document entity or external parsed entity where the
+   * markup triggering the event appears.</p>
+   *
+   * @return The line number, or -1 if none is available.
+   * @see #getColumnNumber
+   */
+  public int getLineNumber()
+  {
+    return (null == m_locator) ? super.getLineNumber() : m_locator.getLineNumber();
+  }
+
+  /**
+   * Return the column number where the current document event ends.
+   *
+   * <p><strong>Warning:</strong> The return value from the method
+   * is intended only as an approximation for the sake of error
+   * reporting; it is not intended to provide sufficient information
+   * to edit the character content of the original XML document.</p>
+   *
+   * <p>The return value is an approximation of the column number
+   * in the document entity or external parsed entity where the
+   * markup triggering the event appears.</p>
+   *
+   * @return The column number, or -1 if none is available.
+   * @see #getLineNumber
+   */
+  public int getColumnNumber()
+  {
+    return (null == m_locator) ? super.getColumnNumber() : m_locator.getColumnNumber();
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/SecuritySupport.java b/src/main/java/org/apache/xml/utils/SecuritySupport.java
new file mode 100644
index 0000000..c847fab
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/SecuritySupport.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xml/utils/SecuritySupport12.java b/src/main/java/org/apache/xml/utils/SecuritySupport12.java
new file mode 100644
index 0000000..52954b5
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/SecuritySupport12.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xml/utils/StopParseException.java b/src/main/java/org/apache/xml/utils/StopParseException.java
new file mode 100644
index 0000000..2f809da
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/StopParseException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StopParseException.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * This is a special exception that is used to stop parsing when 
+ * search for an element.  For instance, when searching for xml:stylesheet 
+ * PIs, it is used to stop the parse once the document element is found.
+ * @see StylesheetPIHandler
+ * @xsl.usage internal
+ */
+public class StopParseException extends org.xml.sax.SAXException
+{
+        static final long serialVersionUID = 210102479218258961L;
+  /**
+   * Constructor StopParseException.
+   */
+  StopParseException()
+  {
+    super("Stylesheet PIs found, stop the parse");
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/StringBufferPool.java b/src/main/java/org/apache/xml/utils/StringBufferPool.java
new file mode 100644
index 0000000..d70e6de
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/StringBufferPool.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StringBufferPool.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * This class pools string buffers, since they are reused so often.
+ * String buffers are good candidates for pooling, because of 
+ * their supporting character arrays.
+ * @xsl.usage internal
+ */
+public class StringBufferPool
+{
+
+  /** The global pool of string buffers.   */
+  private static ObjectPool m_stringBufPool =
+    new ObjectPool(org.apache.xml.utils.FastStringBuffer.class);
+
+  /**
+   * Get the first free instance of a string buffer, or create one 
+   * if there are no free instances.
+   *
+   * @return A string buffer ready for use.
+   */
+  public synchronized static FastStringBuffer get()
+  {
+    return (FastStringBuffer) m_stringBufPool.getInstance();
+  }
+
+  /**
+   * Return a string buffer back to the pool.
+   *
+   * @param sb Must be a non-null reference to a string buffer.
+   */
+  public synchronized static void free(FastStringBuffer sb)
+  {
+    // Since this isn't synchronized, setLength must be 
+    // done before the instance is freed.
+    // Fix attributed to Peter Speck <speck@ruc.dk>.
+    sb.setLength(0);
+    m_stringBufPool.freeInstance(sb);
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/StringToIntTable.java b/src/main/java/org/apache/xml/utils/StringToIntTable.java
new file mode 100644
index 0000000..9287d86
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/StringToIntTable.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StringToIntTable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A very simple lookup table that stores a list of strings, the even
+ * number strings being keys, and the odd number strings being values.
+ * @xsl.usage internal
+ */
+public class StringToIntTable
+{
+
+  public static final int INVALID_KEY = -10000;
+  
+  /** Block size to allocate          */
+  private int m_blocksize;
+
+  /** Array of strings this table points to. Associated with ints
+   * in m_values         */
+  private String m_map[];
+
+  /** Array of ints this table points. Associated with strings from
+   * m_map.         */
+  private int m_values[];
+
+  /** Number of ints in the table          */
+  private int m_firstFree = 0;
+
+  /** Size of this table         */
+  private int m_mapSize;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public StringToIntTable()
+  {
+
+    m_blocksize = 8;
+    m_mapSize = m_blocksize;
+    m_map = new String[m_blocksize];
+    m_values = new int[m_blocksize];
+  }
+
+  /**
+   * Construct a StringToIntTable, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public StringToIntTable(int blocksize)
+  {
+
+    m_blocksize = blocksize;
+    m_mapSize = blocksize;
+    m_map = new String[blocksize];
+    m_values = new int[m_blocksize];
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return the length of the list 
+   */
+  public final int getLength()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Append a string onto the vector.
+   *
+   * @param key String to append
+   * @param value The int value of the string
+   */
+  public final void put(String key, int value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      String newMap[] = new String[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+
+      int newValues[] = new int[m_mapSize];
+
+      System.arraycopy(m_values, 0, newValues, 0, m_firstFree + 1);
+
+      m_values = newValues;
+    }
+
+    m_map[m_firstFree] = key;
+    m_values[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param key String to look for
+   *
+   * @return The String's int value
+   * 
+   */
+  public final int get(String key)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equals(key))
+        return m_values[i];
+    }
+
+	return INVALID_KEY;
+  }
+
+  /**
+   * Tell if the table contains the given string. Ignore case.
+   *
+   * @param key String to look for
+   *
+   * @return The string's int value
+   */
+  public final int getIgnoreCase(String key)
+  {
+
+    if (null == key)
+        return INVALID_KEY;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equalsIgnoreCase(key))
+        return m_values[i];
+    }
+
+    return INVALID_KEY;
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param key String to look for
+   *
+   * @return True if the string is in the table
+   */
+  public final boolean contains(String key)
+  {
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equals(key))
+        return true;
+    }
+
+    return false;
+  }
+  
+  /**
+   * Return array of keys in the table.
+   * 
+   * @return Array of strings
+   */
+  public final String[] keys()
+  {
+    String [] keysArr = new String[m_firstFree];
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      keysArr[i] = m_map[i];
+    }
+
+    return keysArr;
+  }  
+}
diff --git a/src/main/java/org/apache/xml/utils/StringVector.java b/src/main/java/org/apache/xml/utils/StringVector.java
new file mode 100644
index 0000000..79dee1d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/StringVector.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StringVector.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A very simple table that stores a list of strings, optimized
+ * for small lists.
+ * @xsl.usage internal
+ */
+public class StringVector implements java.io.Serializable
+{
+    static final long serialVersionUID = 4995234972032919748L;
+
+  /** @serial Size of blocks to allocate           */
+  protected int m_blocksize;
+
+  /** @serial Array of strings this contains          */
+  protected String m_map[];
+
+  /** @serial Number of strings this contains          */
+  protected int m_firstFree = 0;
+
+  /** @serial Size of the array          */
+  protected int m_mapSize;
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is very small, for small lists.
+   */
+  public StringVector()
+  {
+
+    m_blocksize = 8;
+    m_mapSize = m_blocksize;
+    m_map = new String[m_blocksize];
+  }
+
+  /**
+   * Construct a StringVector, using the given block size.
+   *
+   * @param blocksize Size of the blocks to allocate 
+   */
+  public StringVector(int blocksize)
+  {
+
+    m_blocksize = blocksize;
+    m_mapSize = blocksize;
+    m_map = new String[blocksize];
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return Number of strings in the list 
+   */
+  public int getLength()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return Number of strings in the list
+   */
+  public final int size()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Append a string onto the vector.
+   *
+   * @param value Sting to add to the vector
+   */
+  public final void addElement(String value)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      String newMap[] = new String[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i Index of string to find
+   *
+   * @return String at given index
+   */
+  public final String elementAt(int i)
+  {
+    return m_map[i];
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param s String to look for
+   *
+   * @return True if the string is in this table  
+   */
+  public final boolean contains(String s)
+  {
+
+    if (null == s)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equals(s))
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Tell if the table contains the given string. Ignore case.
+   *
+   * @param s String to find
+   *
+   * @return True if the String is in this vector
+   */
+  public final boolean containsIgnoreCase(String s)
+  {
+
+    if (null == s)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      if (m_map[i].equalsIgnoreCase(s))
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Tell if the table contains the given string.
+   *
+   * @param s String to push into the vector
+   */
+  public final void push(String s)
+  {
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      String newMap[] = new String[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    m_map[m_firstFree] = s;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Pop the tail of this vector.
+   *
+   * @return The String last added to this vector or null not found.
+   * The string is removed from the vector.
+   */
+  public final String pop()
+  {
+
+    if (m_firstFree <= 0)
+      return null;
+
+    m_firstFree--;
+
+    String s = m_map[m_firstFree];
+
+    m_map[m_firstFree] = null;
+
+    return s;
+  }
+
+  /**
+   * Get the string at the tail of this vector without popping.
+   *
+   * @return The string at the tail of this vector.
+   */
+  public final String peek()
+  {
+    return (m_firstFree <= 0) ? null : m_map[m_firstFree - 1];
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/StylesheetPIHandler.java b/src/main/java/org/apache/xml/utils/StylesheetPIHandler.java
new file mode 100644
index 0000000..8005d06
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/StylesheetPIHandler.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StylesheetPIHandler.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.xml.utils.SystemIDResolver;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Search for the xml-stylesheet processing instructions in an XML document.
+ * @see <a href="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents, Version 1.0</a>
+ */
+public class StylesheetPIHandler extends DefaultHandler
+{
+  /** The baseID of the document being processed.  */
+  String m_baseID;
+
+  /** The desired media criteria. */
+  String m_media;
+
+  /** The desired title criteria.  */
+  String m_title;
+
+  /** The desired character set criteria.   */
+  String m_charset;
+
+  /** A list of SAXSource objects that match the criteria.  */
+  Vector m_stylesheets = new Vector();
+  
+  // Add code to use a URIResolver. Patch from Dmitri Ilyin. 
+  
+  /**
+   * The object that implements the URIResolver interface,
+   * or null.
+   */
+  URIResolver m_uriResolver;
+
+  /**
+   * Get the object that will be used to resolve URIs in href 
+   * in xml-stylesheet processing instruction.
+   *
+   * @param resolver An object that implements the URIResolver interface,
+   * or null.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+    m_uriResolver = resolver;
+  }
+
+  /**
+   * Get the object that will be used to resolve URIs in href 
+   * in xml-stylesheet processing instruction.
+   *
+   * @return The URIResolver that was set with setURIResolver.
+   */
+  public URIResolver getURIResolver()
+  {
+    return m_uriResolver;
+  }
+
+  /**
+   * Construct a StylesheetPIHandler instance that will search 
+   * for xml-stylesheet PIs based on the given criteria.
+   *
+   * @param baseID The base ID of the XML document, needed to resolve 
+   *               relative IDs.
+   * @param media The desired media criteria.
+   * @param title The desired title criteria.
+   * @param charset The desired character set criteria.
+   */
+  public StylesheetPIHandler(String baseID, String media, String title,
+                             String charset)
+  {
+
+    m_baseID = baseID;
+    m_media = media;
+    m_title = title;
+    m_charset = charset;
+  }
+
+  /**
+   * Return the last stylesheet found that match the constraints.
+   *
+   * @return Source object that references the last stylesheet reference 
+   *         that matches the constraints.
+   */
+  public Source getAssociatedStylesheet()
+  {
+
+    int sz = m_stylesheets.size();
+
+    if (sz > 0)
+    {
+      Source source = (Source) m_stylesheets.elementAt(sz-1);
+      return source;      
+    }
+    else
+      return null;
+  }
+
+  /**
+   * Handle the xml-stylesheet processing instruction.
+   *
+   * @param target The processing instruction target.
+   * @param data The processing instruction data, or null if
+   *             none is supplied.
+   * @throws org.xml.sax.SAXException Any SAX exception, possibly
+   *            wrapping another exception.
+   * @see org.xml.sax.ContentHandler#processingInstruction
+   * @see <a href="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents, Version 1.0</a>
+   */
+  public void processingInstruction(String target, String data)
+          throws org.xml.sax.SAXException
+  {
+
+    if (target.equals("xml-stylesheet"))
+    {
+      String href = null;  // CDATA #REQUIRED
+      String type = null;  // CDATA #REQUIRED
+      String title = null;  // CDATA #IMPLIED
+      String media = null;  // CDATA #IMPLIED
+      String charset = null;  // CDATA #IMPLIED
+      boolean alternate = false;  // (yes|no) "no"
+      StringTokenizer tokenizer = new StringTokenizer(data, " \t=\n", true);
+      boolean lookedAhead = false; 
+      Source source = null;
+
+      String token = "";
+      while (tokenizer.hasMoreTokens())
+      {        
+        if (!lookedAhead)
+          token = tokenizer.nextToken();
+        else
+          lookedAhead = false;
+        if (tokenizer.hasMoreTokens() && 
+               (token.equals(" ") || token.equals("\t") || token.equals("=")))
+          continue;
+          
+        String name = token;  
+        if (name.equals("type"))
+        { 
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          type = token.substring(1, token.length() - 1);
+          
+        }
+        else if (name.equals("href"))
+        {
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          href = token;
+          if (tokenizer.hasMoreTokens())
+          {
+            token = tokenizer.nextToken();
+            // If the href value has parameters to be passed to a 
+            // servlet(something like "foobar?id=12..."), 
+            // we want to make sure we get them added to
+            // the href value. Without this check, we would move on 
+            // to try to process another attribute and that would be
+            // wrong.
+            // We need to set lookedAhead here to flag that we
+            // already have the next token. 
+            while ( token.equals("=") && tokenizer.hasMoreTokens())
+            {  
+              href = href + token + tokenizer.nextToken();
+              if (tokenizer.hasMoreTokens())
+              {  
+                token = tokenizer.nextToken();
+                lookedAhead = true;
+              }
+              else
+              {
+                break;
+              }
+            }
+          }
+          href = href.substring(1, href.length() - 1);
+          try
+          { 
+            // Add code to use a URIResolver. Patch from Dmitri Ilyin. 
+            if (m_uriResolver != null) 
+            {
+              source = m_uriResolver.resolve(href, m_baseID);
+            } 
+           else 
+            {
+              href = SystemIDResolver.getAbsoluteURI(href, m_baseID);
+              source = new SAXSource(new InputSource(href));
+            }            
+          }
+          catch(TransformerException te)
+          {
+            throw new org.xml.sax.SAXException(te);
+          }
+        }
+        else if (name.equals("title"))
+        {
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          title = token.substring(1, token.length() - 1);
+        }
+        else if (name.equals("media"))
+        {
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          media = token.substring(1, token.length() - 1);
+        }
+        else if (name.equals("charset"))
+        {
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+              (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          charset = token.substring(1, token.length() - 1);
+        }
+        else if (name.equals("alternate"))
+        {
+          token = tokenizer.nextToken();
+          while (tokenizer.hasMoreTokens() && 
+               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
+            token = tokenizer.nextToken();
+          alternate = token.substring(1, token.length()
+                                             - 1).equals("yes");
+        }
+        
+      }
+
+      if ((null != type) 
+          && (type.equals("text/xsl") || type.equals("text/xml") || type.equals("application/xml+xslt"))  
+          && (null != href))
+      {
+        if (null != m_media)
+        {
+          if (null != media)
+          {
+            if (!media.equals(m_media))
+              return;
+          }
+          else
+            return;
+        }
+
+        if (null != m_charset)
+        {
+          if (null != charset)
+          {
+            if (!charset.equals(m_charset))
+              return;
+          }
+          else
+            return;
+        }
+
+        if (null != m_title)
+        {
+          if (null != title)
+          {
+            if (!title.equals(m_title))
+              return;
+          }
+          else
+            return;
+        }
+
+        m_stylesheets.addElement(source);
+      }
+    }
+  }
+  
+  
+  /**
+   * The spec notes that "The xml-stylesheet processing instruction is allowed only in the prolog of an XML document.",
+   * so, at least for right now, I'm going to go ahead an throw a TransformerException
+   * in order to stop the parse.
+   *
+   * @param namespaceURI The Namespace URI, or an empty string.
+   * @param localName The local name (without prefix), or empty string if not namespace processing.
+   * @param qName The qualified name (with prefix).
+   * @param atts  The specified or defaulted attributes.
+   *
+   * @throws StopParseException since there can be no valid xml-stylesheet processing 
+   *                            instructions past the first element.
+   */
+  public void startElement(
+          String namespaceURI, String localName, String qName, Attributes atts)
+            throws org.xml.sax.SAXException
+  {
+    throw new StopParseException();
+  }
+
+  /**
+    * Added additional getter and setter methods for the Base Id
+    * to fix bugzilla bug 24187
+    * 
+    */
+   public void setBaseId(String baseId) {
+       m_baseID = baseId;
+ 
+   }
+   public String  getBaseId() {
+       return m_baseID ;
+   }
+
+}
diff --git a/src/main/java/org/apache/xml/utils/SuballocatedIntVector.java b/src/main/java/org/apache/xml/utils/SuballocatedIntVector.java
new file mode 100644
index 0000000..3104939
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/SuballocatedIntVector.java
@@ -0,0 +1,557 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SuballocatedIntVector.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A very simple table that stores a list of int. Very similar API to our
+ * IntVector class (same API); different internal storage.
+ * 
+ * This version uses an array-of-arrays solution. Read/write access is thus
+ * a bit slower than the simple IntVector, and basic storage is a trifle
+ * higher due to the top-level array -- but appending is O(1) fast rather
+ * than O(N**2) slow, which will swamp those costs in situations where
+ * long vectors are being built up.
+ * 
+ * Known issues:
+ * 
+ * Some methods are private because they haven't yet been tested properly.
+ *
+ * Retrieval performance is critical, since this is used at the core
+ * of the DTM model. (Append performance is almost as important.)
+ * That's pushing me toward just letting reads from unset indices
+ * throw exceptions or return stale data; safer behavior would have
+ * performance costs.
+ * */
+public class SuballocatedIntVector
+{
+  /** Size of blocks to allocate          */
+  protected int m_blocksize;
+
+  /** Bitwise addressing (much faster than div/remainder */
+  protected int m_SHIFT, m_MASK;
+  
+  /** The default number of blocks to (over)allocate by */
+  protected static final int NUMBLOCKS_DEFAULT = 32;
+  
+  /** The number of blocks to (over)allocate by */
+  protected int m_numblocks = NUMBLOCKS_DEFAULT;
+  
+  /** Array of arrays of ints          */
+  protected int m_map[][];
+
+  /** Number of ints in array          */
+  protected int m_firstFree = 0;
+
+  /** "Shortcut" handle to m_map[0]. Surprisingly helpful for short vectors. */
+  protected int m_map0[];
+
+  /** "Shortcut" handle to most recently added row of m_map.
+   * Very helpful during construction.
+   * @xsl.usage internal
+   */
+  protected int m_buildCache[];
+  protected int m_buildCacheStartIndex;
+
+
+  /**
+   * Default constructor.  Note that the default
+   * block size is currently 2K, which may be overkill for
+   * small lists and undershootng for large ones.
+   */
+  public SuballocatedIntVector()
+  {
+    this(2048);
+  }
+
+  /**
+   * Construct a IntVector, using the given block size and number
+   * of blocks. For efficiency, we will round the requested size 
+   * off to a power of two.
+   *
+   * @param blocksize Size of block to allocate
+   * @param numblocks Number of blocks to allocate
+   * */
+  public SuballocatedIntVector(int blocksize, int numblocks)
+  {
+    //m_blocksize = blocksize;
+    for(m_SHIFT=0;0!=(blocksize>>>=1);++m_SHIFT)
+      ;
+    m_blocksize=1<<m_SHIFT;
+    m_MASK=m_blocksize-1;
+    m_numblocks = numblocks;
+    	
+    m_map0=new int[m_blocksize];
+    m_map = new int[numblocks][];
+    m_map[0]=m_map0;
+    m_buildCache = m_map0;
+    m_buildCacheStartIndex = 0;
+  }
+	
+  /** Construct a IntVector, using the given block size and
+   * the default number of blocks (32).
+   *
+   * @param blocksize Size of block to allocate
+   * */
+  public SuballocatedIntVector(int blocksize)
+  {
+    this(blocksize, NUMBLOCKS_DEFAULT);
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return length of the list
+   */
+  public int size()
+  {
+    return m_firstFree;
+  }
+  
+  /**
+   * Set the length of the list. This will only work to truncate the list, and
+   * even then it has not been heavily tested and may not be trustworthy.
+   *
+   * @return length of the list
+   */
+  public void setSize(int sz)
+  {
+    if(m_firstFree>sz) // Whups; had that backward!
+      m_firstFree = sz;
+  }
+
+  /**
+   * Append a int onto the vector.
+   *
+   * @param value Int to add to the list 
+   */
+  public  void addElement(int value)
+  {
+    int indexRelativeToCache = m_firstFree - m_buildCacheStartIndex;
+
+    // Is the new index an index into the cache row of m_map?
+    if(indexRelativeToCache >= 0 && indexRelativeToCache < m_blocksize) {
+      m_buildCache[indexRelativeToCache]=value;
+      ++m_firstFree;
+    } else {
+      // Growing the outer array should be rare. We initialize to a
+      // total of m_blocksize squared elements, which at the default
+      // size is 4M integers... and we grow by at least that much each
+      // time.  However, attempts to microoptimize for this (assume
+      // long enough and catch exceptions) yield no noticable
+      // improvement.
+
+      int index=m_firstFree>>>m_SHIFT;
+      int offset=m_firstFree&m_MASK;
+
+      if(index>=m_map.length)
+      {
+	int newsize=index+m_numblocks;
+	int[][] newMap=new int[newsize][];
+	System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+	m_map=newMap;
+      }
+      int[] block=m_map[index];
+      if(null==block)
+	block=m_map[index]=new int[m_blocksize];
+      block[offset]=value;
+
+      // Cache the current row of m_map.  Next m_blocksize-1
+      // values added will go to this row.
+      m_buildCache = block;
+      m_buildCacheStartIndex = m_firstFree-offset;
+
+      ++m_firstFree;
+    }
+  }
+
+  /**
+   * Append several int values onto the vector.
+   *
+   * @param value Int to add to the list 
+   */
+  private  void addElements(int value, int numberOfElements)
+  {
+    if(m_firstFree+numberOfElements<m_blocksize)
+      for (int i = 0; i < numberOfElements; i++) 
+      {
+        m_map0[m_firstFree++]=value;
+      }
+    else
+    {
+      int index=m_firstFree>>>m_SHIFT;
+      int offset=m_firstFree&m_MASK;
+      m_firstFree+=numberOfElements;
+      while( numberOfElements>0)
+      {
+        if(index>=m_map.length)
+        {
+          int newsize=index+m_numblocks;
+          int[][] newMap=new int[newsize][];
+          System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+          m_map=newMap;
+        }
+        int[] block=m_map[index];
+        if(null==block)
+          block=m_map[index]=new int[m_blocksize];
+        int copied=(m_blocksize-offset < numberOfElements)
+          ? m_blocksize-offset : numberOfElements;
+        numberOfElements-=copied;
+        while(copied-- > 0)
+          block[offset++]=value;
+
+        ++index;offset=0;
+      }
+    }
+  }
+  
+  /**
+   * Append several slots onto the vector, but do not set the values.
+   * Note: "Not Set" means the value is unspecified.
+   *
+   * @param numberOfElements Int to add to the list 
+   */
+  private  void addElements(int numberOfElements)
+  {
+    int newlen=m_firstFree+numberOfElements;
+    if(newlen>m_blocksize)
+    {
+      int index=m_firstFree>>>m_SHIFT;
+      int newindex=(m_firstFree+numberOfElements)>>>m_SHIFT;
+      for(int i=index+1;i<=newindex;++i)
+        m_map[i]=new int[m_blocksize];
+    }
+    m_firstFree=newlen;
+  }
+  
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * Insertion may be an EXPENSIVE operation!
+   *
+   * @param value Int to insert
+   * @param at Index of where to insert 
+   */
+  private  void insertElementAt(int value, int at)
+  {
+    if(at==m_firstFree)
+      addElement(value);
+    else if (at>m_firstFree)
+    {
+      int index=at>>>m_SHIFT;
+      if(index>=m_map.length)
+      {
+        int newsize=index+m_numblocks;
+        int[][] newMap=new int[newsize][];
+        System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+        m_map=newMap;
+      }
+      int[] block=m_map[index];
+      if(null==block)
+        block=m_map[index]=new int[m_blocksize];
+      int offset=at&m_MASK;
+          block[offset]=value;
+          m_firstFree=offset+1;
+        }
+    else
+    {
+      int index=at>>>m_SHIFT;
+      int maxindex=m_firstFree>>>m_SHIFT; // %REVIEW% (m_firstFree+1?)
+      ++m_firstFree;
+      int offset=at&m_MASK;
+      int push;
+      
+      // ***** Easier to work down from top?
+      while(index<=maxindex)
+      {
+        int copylen=m_blocksize-offset-1;
+        int[] block=m_map[index];
+        if(null==block)
+        {
+          push=0;
+          block=m_map[index]=new int[m_blocksize];
+        }
+        else
+        {
+          push=block[m_blocksize-1];
+          System.arraycopy(block, offset , block, offset+1, copylen);
+        }
+        block[offset]=value;
+        value=push;
+        offset=0;
+        ++index;
+      }
+    }
+  }
+
+  /**
+   * Wipe it out. Currently defined as equivalent to setSize(0).
+   */
+  public void removeAllElements()
+  {
+    m_firstFree = 0;
+    m_buildCache = m_map0;
+    m_buildCacheStartIndex = 0;
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s Int to remove from array
+   *
+   * @return True if the int was removed, false if it was not found
+   */
+  private  boolean removeElement(int s)
+  {
+    int at=indexOf(s,0);
+    if(at<0)
+      return false;
+    removeElementAt(at);
+    return true;
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i index of where to remove and int
+   */
+  private  void removeElementAt(int at)
+  {
+        // No point in removing elements that "don't exist"...  
+    if(at<m_firstFree)
+    {
+      int index=at>>>m_SHIFT;
+      int maxindex=m_firstFree>>>m_SHIFT;
+      int offset=at&m_MASK;
+      
+      while(index<=maxindex)
+      {
+        int copylen=m_blocksize-offset-1;
+        int[] block=m_map[index];
+        if(null==block)
+          block=m_map[index]=new int[m_blocksize];
+        else
+          System.arraycopy(block, offset+1, block, offset, copylen);
+        if(index<maxindex)
+        {
+          int[] next=m_map[index+1];
+          if(next!=null)
+            block[m_blocksize-1]=(next!=null) ? next[0] : 0;
+        }
+        else
+          block[m_blocksize-1]=0;
+        offset=0;
+        ++index;
+      }
+    }
+    --m_firstFree;
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param value object to set
+   * @param at    Index of where to set the object
+   */
+  public void setElementAt(int value, int at)
+  {
+    if(at<m_blocksize)
+      m_map0[at]=value;
+    else
+    {
+      int index=at>>>m_SHIFT;
+      int offset=at&m_MASK;
+        
+      if(index>=m_map.length)
+      {
+	int newsize=index+m_numblocks;
+	int[][] newMap=new int[newsize][];
+	System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+	m_map=newMap;
+      }
+
+      int[] block=m_map[index];
+      if(null==block)
+	block=m_map[index]=new int[m_blocksize];
+      block[offset]=value;
+    }
+
+    if(at>=m_firstFree)
+      m_firstFree=at+1;
+  }
+  
+
+  /**
+   * Get the nth element. This is often at the innermost loop of an
+   * application, so performance is critical.
+   *
+   * @param i index of value to get
+   *
+   * @return value at given index. If that value wasn't previously set,
+   * the result is undefined for performance reasons. It may throw an
+   * exception (see below), may return zero, or (if setSize has previously
+   * been used) may return stale data.
+   *
+   * @throws ArrayIndexOutOfBoundsException if the index was _clearly_
+   * unreasonable (negative, or past the highest block).
+   *
+   * @throws NullPointerException if the index points to a block that could
+   * have existed (based on the highest index used) but has never had anything
+   * set into it.
+   * %REVIEW% Could add a catch to create the block in that case, or return 0.
+   * Try/Catch is _supposed_ to be nearly free when not thrown to. Do we
+   * believe that? Should we have a separate safeElementAt?
+   */
+  public int elementAt(int i)
+  {
+    // This is actually a significant optimization!
+    if(i<m_blocksize)
+      return m_map0[i];
+
+    return m_map[i>>>m_SHIFT][i&m_MASK];
+  }
+
+  /**
+   * Tell if the table contains the given node.
+   *
+   * @param s object to look for
+   *
+   * @return true if the object is in the list
+   */
+  private  boolean contains(int s)
+  {
+    return (indexOf(s,0) >= 0);
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @param index Index of where to begin search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem, int index)
+  {
+        if(index>=m_firstFree)
+                return -1;
+          
+    int bindex=index>>>m_SHIFT;
+    int boffset=index&m_MASK;
+    int maxindex=m_firstFree>>>m_SHIFT;
+    int[] block;
+    
+    for(;bindex<maxindex;++bindex)
+    {
+      block=m_map[bindex];
+      if(block!=null)
+        for(int offset=boffset;offset<m_blocksize;++offset)
+          if(block[offset]==elem)
+            return offset+bindex*m_blocksize;
+      boffset=0; // after first
+    }
+    // Last block may need to stop before end
+    int maxoffset=m_firstFree&m_MASK;
+    block=m_map[maxindex];
+    for(int offset=boffset;offset<maxoffset;++offset)
+      if(block[offset]==elem)
+        return offset+maxindex*m_blocksize;
+
+    return -1;    
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem)
+  {
+    return indexOf(elem,0);
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Object to look for
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  private  int lastIndexOf(int elem)
+  {
+    int boffset=m_firstFree&m_MASK;
+    for(int index=m_firstFree>>>m_SHIFT;
+        index>=0;
+        --index)
+    {
+      int[] block=m_map[index];
+      if(block!=null)
+        for(int offset=boffset; offset>=0; --offset)
+          if(block[offset]==elem)
+            return offset+index*m_blocksize;
+      boffset=0; // after first
+    }
+    return -1;
+  }
+  
+  /**
+   * Return the internal m_map0 array
+   * @return the m_map0 array
+   */
+  public final int[] getMap0()
+  {
+    return m_map0;
+  }
+  
+  /**
+   * Return the m_map double array
+   * @return the internal map of array of arrays 
+   */
+  public final int[][] getMap()
+  {
+    return m_map;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/utils/SystemIDResolver.java b/src/main/java/org/apache/xml/utils/SystemIDResolver.java
new file mode 100644
index 0000000..7fe63f5
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/SystemIDResolver.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SystemIDResolver.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.File;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.utils.URI.MalformedURIException;
+
+/**
+ * This class is used to resolve relative URIs and SystemID 
+ * strings into absolute URIs.
+ *
+ * <p>This is a generic utility for resolving URIs, other than the 
+ * fact that it's declared to throw TransformerException.  Please 
+ * see code comments for details on how resolution is performed.</p>
+ * @xsl.usage internal
+ */
+public class SystemIDResolver
+{
+
+  /**
+   * Get an absolute URI from a given relative URI (local path). 
+   * 
+   * <p>The relative URI is a local filesystem path. The path can be
+   * absolute or relative. If it is a relative path, it is resolved relative 
+   * to the system property "user.dir" if it is available; if not (i.e. in an 
+   * Applet perhaps which throws SecurityException) then we just return the
+   * relative path. The space and backslash characters are also replaced to
+   * generate a good absolute URI.</p>
+   *
+   * @param localPath The relative URI to resolve
+   *
+   * @return Resolved absolute URI
+   */
+  public static String getAbsoluteURIFromRelative(String localPath)
+  {
+    if (localPath == null || localPath.length() == 0)
+      return "";
+      
+    // If the local path is a relative path, then it is resolved against
+    // the "user.dir" system property.
+    String absolutePath = localPath;
+    if (!isAbsolutePath(localPath))
+    {
+      try 
+      {
+        absolutePath = getAbsolutePathFromRelativePath(localPath);
+      }
+      // user.dir not accessible from applet
+      catch (SecurityException se) 
+      {
+        return "file:" + localPath;
+      }
+    }
+
+    String urlString;
+    if (null != absolutePath)
+    {
+      if (absolutePath.startsWith(File.separator))
+        urlString = "file://" + absolutePath;
+      else
+        urlString = "file:///" + absolutePath;        
+    }
+    else
+      urlString = "file:" + localPath;
+    
+    return replaceChars(urlString);
+  }
+  
+  /**
+   * Return an absolute path from a relative path.
+   *
+   * @param relativePath A relative path
+   * @return The absolute path
+   */
+  private static String getAbsolutePathFromRelativePath(String relativePath)
+  {
+    return new File(relativePath).getAbsolutePath();
+  }
+  
+  /**
+   * Return true if the systemId denotes an absolute URI .
+   *
+   * @param systemId The systemId string
+   * @return true if the systemId is an an absolute URI
+   */
+  public static boolean isAbsoluteURI(String systemId)
+  {
+     /** http://www.ietf.org/rfc/rfc2396.txt
+      *   Authors should be aware that a path segment which contains a colon
+      * character cannot be used as the first segment of a relative URI path
+      * (e.g., "this:that"), because it would be mistaken for a scheme name.
+     **/
+     /** 
+      * %REVIEW% Can we assume here that systemId is a valid URI?
+      * It looks like we cannot ( See discussion of this common problem in 
+      * Bugzilla Bug 22777 ). 
+     **/
+     //"fix" for Bugzilla Bug 22777
+    if(isWindowsAbsolutePath(systemId)){
+        return false;
+     }
+    
+    final int fragmentIndex = systemId.indexOf('#');
+    final int queryIndex = systemId.indexOf('?');
+    final int slashIndex = systemId.indexOf('/');
+    final int colonIndex = systemId.indexOf(':');
+    
+    //finding substring  before '#', '?', and '/' 
+    int index = systemId.length() -1;
+    if(fragmentIndex > 0) 
+        index = fragmentIndex;
+    if((queryIndex > 0) && (queryIndex <index)) 
+        index = queryIndex;
+    if((slashIndex > 0) && (slashIndex <index))
+        index = slashIndex; 
+    // return true if there is ':' before '#', '?', and '/'
+    return ((colonIndex >0) && (colonIndex<index));
+    
+  }
+  
+  /**
+   * Return true if the local path is an absolute path.
+   *
+   * @param systemId The path string
+   * @return true if the path is absolute
+   */
+  public static boolean isAbsolutePath(String systemId)
+  {
+    if(systemId == null)
+        return false;
+    final File file = new File(systemId);
+    return file.isAbsolute();
+    
+  }
+  
+   /**
+   * Return true if the local path is a Windows absolute path.
+   *
+   * @param systemId The path string
+   * @return true if the path is a Windows absolute path
+   */
+    private static boolean isWindowsAbsolutePath(String systemId)
+  {
+    if(!isAbsolutePath(systemId))
+      return false;
+    // On Windows, an absolute path starts with "[drive_letter]:\".
+    if (systemId.length() > 2 
+        && systemId.charAt(1) == ':'
+        && Character.isLetter(systemId.charAt(0))
+        && (systemId.charAt(2) == '\\' || systemId.charAt(2) == '/'))
+      return true;
+    else
+      return false;
+  }
+  
+  /**
+   * Replace spaces with "%20" and backslashes with forward slashes in 
+   * the input string to generate a well-formed URI string.
+   *
+   * @param str The input string
+   * @return The string after conversion
+   */
+  private static String replaceChars(String str)
+  {
+    StringBuffer buf = new StringBuffer(str);
+    int length = buf.length();
+    for (int i = 0; i < length; i++)
+    {
+      char currentChar = buf.charAt(i);
+      // Replace space with "%20"
+      if (currentChar == ' ')
+      {
+        buf.setCharAt(i, '%');
+        buf.insert(i+1, "20");
+        length = length + 2;
+        i = i + 2;
+      }
+      // Replace backslash with forward slash
+      else if (currentChar == '\\')
+      {
+        buf.setCharAt(i, '/');
+      }
+    }
+    
+    return buf.toString();
+  }
+  
+  /**
+   * Take a SystemID string and try to turn it into a good absolute URI.
+   *
+   * @param systemId A URI string, which may be absolute or relative.
+   *
+   * @return The resolved absolute URI
+   */
+  public static String getAbsoluteURI(String systemId)
+  {
+    String absoluteURI = systemId;
+    if (isAbsoluteURI(systemId))
+    {
+      // Only process the systemId if it starts with "file:".
+      if (systemId.startsWith("file:"))
+      {
+        String str = systemId.substring(5);
+        
+        // Resolve the absolute path if the systemId starts with "file:///"
+        // or "file:/". Don't do anything if it only starts with "file://".
+        if (str != null && str.startsWith("/"))
+        {
+          if (str.startsWith("///") || !str.startsWith("//"))
+          {
+            // A Windows path containing a drive letter can be relative.
+            // A Unix path starting with "file:/" is always absolute.
+            int secondColonIndex = systemId.indexOf(':', 5);
+            if (secondColonIndex > 0)
+            {
+              String localPath = systemId.substring(secondColonIndex-1);
+              try {
+                if (!isAbsolutePath(localPath))
+                  absoluteURI = systemId.substring(0, secondColonIndex-1) + 
+                                getAbsolutePathFromRelativePath(localPath);
+              }
+              catch (SecurityException se) {
+                return systemId;
+              }
+            }
+          }          
+        }
+        else
+        {
+          return getAbsoluteURIFromRelative(systemId.substring(5));
+        }
+                
+        return replaceChars(absoluteURI);
+      }
+      else
+        return systemId;
+    }
+    else
+      return getAbsoluteURIFromRelative(systemId);
+    
+  }
+
+
+  /**
+   * Take a SystemID string and try to turn it into a good absolute URI.
+   *
+   * @param urlString SystemID string
+   * @param base The URI string used as the base for resolving the systemID
+   *
+   * @return The resolved absolute URI
+   * @throws TransformerException thrown if the string can't be turned into a URI.
+   */
+  public static String getAbsoluteURI(String urlString, String base)
+          throws TransformerException
+  {    
+    if (base == null)
+      return getAbsoluteURI(urlString);
+    
+    String absoluteBase = getAbsoluteURI(base);
+    URI uri = null;
+    try 
+    {
+      URI baseURI = new URI(absoluteBase);
+      uri = new URI(baseURI, urlString);
+    }
+    catch (MalformedURIException mue)
+    {
+      throw new TransformerException(mue);
+    }
+    
+    return replaceChars(uri.toString());
+  }
+  
+}
diff --git a/src/main/java/org/apache/xml/utils/ThreadControllerWrapper.java b/src/main/java/org/apache/xml/utils/ThreadControllerWrapper.java
new file mode 100644
index 0000000..4a314ea
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/ThreadControllerWrapper.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ThreadControllerWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A utility class that wraps the ThreadController, which is used
+ * by IncrementalSAXSource for the incremental building of DTM.
+ */
+public class ThreadControllerWrapper
+{
+  
+  /** The ThreadController pool   */
+  private static ThreadController m_tpool = new ThreadController();
+  
+  public static Thread runThread(Runnable runnable, int priority)
+  {
+    return m_tpool.run(runnable, priority);
+  }
+  
+  public static void waitThread(Thread worker, Runnable task)
+    throws InterruptedException
+  {
+    m_tpool.waitThread(worker, task);
+  }
+  
+  /**
+   * Thread controller utility class for incremental SAX source. Must 
+   * be overriden with a derived class to support thread pooling.
+   *
+   * All thread-related stuff is in this class.
+   */
+  public static class ThreadController
+  {
+
+    /**
+     * Will get a thread from the pool, execute the task
+     *  and return the thread to the pool.
+     *
+     *  The return value is used only to wait for completion
+     *
+     *
+     * NEEDSDOC @param task
+     * @param priority if >0 the task will run with the given priority
+     *  ( doesn't seem to be used in xalan, since it's allways the default )
+     * @return  The thread that is running the task, can be used
+     *          to wait for completion
+     */
+    public Thread run(Runnable task, int priority)
+    {
+
+      Thread t = new Thread(task);
+
+      t.start();
+
+      //       if( priority > 0 )
+      //      t.setPriority( priority );
+      return t;
+    }
+
+    /**
+     *  Wait until the task is completed on the worker
+     *  thread.
+     *
+     * NEEDSDOC @param worker
+     * NEEDSDOC @param task
+     *
+     * @throws InterruptedException
+     */
+    public void waitThread(Thread worker, Runnable task)
+            throws InterruptedException
+    {
+
+      // This should wait until the transformThread is considered not alive.
+      worker.join();
+    }
+  }
+ 
+}
diff --git a/src/main/java/org/apache/xml/utils/TreeWalker.java b/src/main/java/org/apache/xml/utils/TreeWalker.java
new file mode 100644
index 0000000..2ebfe63
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/TreeWalker.java
@@ -0,0 +1,508 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: TreeWalker.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.File;
+
+import org.w3c.dom.Comment;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * This class does a pre-order walk of the DOM tree, calling a ContentHandler
+ * interface as it goes.
+ * @xsl.usage advanced
+ */
+
+public class TreeWalker
+{
+
+  /** Local reference to a ContentHandler          */
+  private ContentHandler m_contentHandler = null;
+
+  // ARGHH!!  JAXP Uses Xerces without setting the namespace processing to ON!
+  // DOM2Helper m_dh = new DOM2Helper();
+
+  /** DomHelper for this TreeWalker          */
+  protected DOMHelper m_dh;
+        
+        /** Locator object for this TreeWalker          */
+        private LocatorImpl m_locator = new LocatorImpl();
+
+  /**
+   * Get the ContentHandler used for the tree walk.
+   *
+   * @return the ContentHandler used for the tree walk
+   */
+  public ContentHandler getContentHandler()
+  {
+    return m_contentHandler;
+  }
+
+  /**
+   * Get the ContentHandler used for the tree walk.
+   *
+   * @return the ContentHandler used for the tree walk
+   */
+  public void setContentHandler(ContentHandler ch)
+  {
+    m_contentHandler = ch;
+  }
+        
+        /**
+   * Constructor.
+   * @param   contentHandler The implemention of the
+   * @param   systemId System identifier for the document.
+   * contentHandler operation (toXMLString, digest, ...)
+   */
+  public TreeWalker(ContentHandler contentHandler, DOMHelper dh, String systemId)
+  {
+    this.m_contentHandler = contentHandler;
+    m_contentHandler.setDocumentLocator(m_locator);
+    if (systemId != null)
+        m_locator.setSystemId(systemId);
+    else {
+        try {
+          // Bug see Bugzilla  26741
+          m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
+         }
+         catch (SecurityException se) {// user.dir not accessible from applet             
+         }
+    }
+    m_dh = dh;
+  }
+
+  /**
+   * Constructor.
+   * @param   contentHandler The implemention of the
+   * contentHandler operation (toXMLString, digest, ...)
+   */
+  public TreeWalker(ContentHandler contentHandler, DOMHelper dh)
+  {
+    this.m_contentHandler = contentHandler;
+    m_contentHandler.setDocumentLocator(m_locator);
+    try {
+       // Bug see Bugzilla  26741
+      m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
+    } 
+    catch (SecurityException se){// user.dir not accessible from applet      
+    }
+    m_dh = dh;
+  }
+  
+  /**
+   * Constructor.
+   * @param   contentHandler The implemention of the
+   * contentHandler operation (toXMLString, digest, ...)
+   */
+  public TreeWalker(ContentHandler contentHandler)
+  {
+    this.m_contentHandler = contentHandler;
+                if (m_contentHandler != null)
+                        m_contentHandler.setDocumentLocator(m_locator);
+                try {
+                   // Bug see Bugzilla  26741
+                  m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
+                } 
+                catch (SecurityException se){// user.dir not accessible from applet
+                  
+    }
+    m_dh = new DOM2Helper();
+  }
+
+  /**
+   * Perform a pre-order traversal non-recursive style.  
+   *
+   * Note that TreeWalker assumes that the subtree is intended to represent 
+   * a complete (though not necessarily well-formed) document and, during a 
+   * traversal, startDocument and endDocument will always be issued to the 
+   * SAX listener.
+   *  
+   * @param pos Node in the tree where to start traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverse(Node pos) throws org.xml.sax.SAXException
+  {
+        this.m_contentHandler.startDocument();
+        
+        traverseFragment(pos);
+
+        this.m_contentHandler.endDocument();
+  }
+    
+  /**
+   * Perform a pre-order traversal non-recursive style.  
+   *
+   * In contrast to the traverse() method this method will not issue 
+   * startDocument() and endDocument() events to the SAX listener.
+   *  
+   * @param pos Node in the tree where to start traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverseFragment(Node pos) throws org.xml.sax.SAXException
+  {
+    Node top = pos;
+
+    while (null != pos)
+    {
+      startNode(pos);
+
+      Node nextNode = pos.getFirstChild();
+
+      while (null == nextNode)
+      {
+        endNode(pos);
+
+        if (top.equals(pos))
+          break;
+
+        nextNode = pos.getNextSibling();
+
+        if (null == nextNode)
+        {
+          pos = pos.getParentNode();
+
+          if ((null == pos) || (top.equals(pos)))
+          {
+            if (null != pos)
+              endNode(pos);
+
+            nextNode = null;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+  }
+
+  /**
+   * Perform a pre-order traversal non-recursive style.
+
+   * Note that TreeWalker assumes that the subtree is intended to represent 
+   * a complete (though not necessarily well-formed) document and, during a 
+   * traversal, startDocument and endDocument will always be issued to the 
+   * SAX listener.
+   *
+   * @param pos Node in the tree where to start traversal
+   * @param top Node in the tree where to end traversal
+   *
+   * @throws TransformerException
+   */
+  public void traverse(Node pos, Node top) throws org.xml.sax.SAXException
+  {
+
+	this.m_contentHandler.startDocument();
+	
+    while (null != pos)
+    {
+      startNode(pos);
+
+      Node nextNode = pos.getFirstChild();
+
+      while (null == nextNode)
+      {
+        endNode(pos);
+
+        if ((null != top) && top.equals(pos))
+          break;
+
+        nextNode = pos.getNextSibling();
+
+        if (null == nextNode)
+        {
+          pos = pos.getParentNode();
+
+          if ((null == pos) || ((null != top) && top.equals(pos)))
+          {
+            nextNode = null;
+
+            break;
+          }
+        }
+      }
+
+      pos = nextNode;
+    }
+    this.m_contentHandler.endDocument();
+  }
+
+  /** Flag indicating whether following text to be processed is raw text          */
+  boolean nextIsRaw = false;
+  
+  /**
+   * Optimized dispatch of characters.
+   */
+  private final void dispatachChars(Node node)
+     throws org.xml.sax.SAXException
+  {
+    if(m_contentHandler instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTM.CharacterNodeHandler)
+    {
+      ((org.apache.xml.dtm.ref.dom2dtm.DOM2DTM.CharacterNodeHandler)m_contentHandler).characters(node);
+    }
+    else
+    {
+      String data = ((Text) node).getData();
+      this.m_contentHandler.characters(data.toCharArray(), 0, data.length());
+    }
+  }
+
+  /**
+   * Start processing given node
+   *
+   *
+   * @param node Node to process
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void startNode(Node node) throws org.xml.sax.SAXException
+  {
+
+    if (m_contentHandler instanceof NodeConsumer)
+    {
+      ((NodeConsumer) m_contentHandler).setOriginatingNode(node);
+    }
+                
+                if (node instanceof Locator)
+                {
+                        Locator loc = (Locator)node;
+                        m_locator.setColumnNumber(loc.getColumnNumber());
+                        m_locator.setLineNumber(loc.getLineNumber());
+                        m_locator.setPublicId(loc.getPublicId());
+                        m_locator.setSystemId(loc.getSystemId());
+                }
+                else
+                {
+                        m_locator.setColumnNumber(0);
+      m_locator.setLineNumber(0);
+                }
+
+    switch (node.getNodeType())
+    {
+    case Node.COMMENT_NODE :
+    {
+      String data = ((Comment) node).getData();
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+
+        lh.comment(data.toCharArray(), 0, data.length());
+      }
+    }
+    break;
+    case Node.DOCUMENT_FRAGMENT_NODE :
+
+      // ??;
+      break;
+    case Node.DOCUMENT_NODE :
+    
+      break;
+    case Node.ELEMENT_NODE :
+      NamedNodeMap atts = ((Element) node).getAttributes();
+      int nAttrs = atts.getLength();
+      // System.out.println("TreeWalker#startNode: "+node.getNodeName());
+
+      for (int i = 0; i < nAttrs; i++)
+      {
+        Node attr = atts.item(i);
+        String attrName = attr.getNodeName();
+
+        // System.out.println("TreeWalker#startNode: attr["+i+"] = "+attrName+", "+attr.getNodeValue());
+        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
+        {
+          // System.out.println("TreeWalker#startNode: attr["+i+"] = "+attrName+", "+attr.getNodeValue());
+          int index;
+          // Use "" instead of null, as Xerces likes "" for the 
+          // name of the default namespace.  Fix attributed 
+          // to "Steven Murray" <smurray@ebt.com>.
+          String prefix = (index = attrName.indexOf(":")) < 0
+                          ? "" : attrName.substring(index + 1);
+
+          this.m_contentHandler.startPrefixMapping(prefix,
+                                                   attr.getNodeValue());
+        }
+        
+      }
+
+      // System.out.println("m_dh.getNamespaceOfNode(node): "+m_dh.getNamespaceOfNode(node));
+      // System.out.println("m_dh.getLocalNameOfNode(node): "+m_dh.getLocalNameOfNode(node));
+      String ns = m_dh.getNamespaceOfNode(node);
+      if(null == ns)
+        ns = "";
+      this.m_contentHandler.startElement(ns,
+                                         m_dh.getLocalNameOfNode(node),
+                                         node.getNodeName(),
+                                         new AttList(atts, m_dh));
+      break;
+    case Node.PROCESSING_INSTRUCTION_NODE :
+    {
+      ProcessingInstruction pi = (ProcessingInstruction) node;
+      String name = pi.getNodeName();
+
+      // String data = pi.getData();
+      if (name.equals("xslt-next-is-raw"))
+      {
+        nextIsRaw = true;
+      }
+      else
+      {
+        this.m_contentHandler.processingInstruction(pi.getNodeName(),
+                                                    pi.getData());
+      }
+    }
+    break;
+    case Node.CDATA_SECTION_NODE :
+    {
+      boolean isLexH = (m_contentHandler instanceof LexicalHandler);
+      LexicalHandler lh = isLexH
+                          ? ((LexicalHandler) this.m_contentHandler) : null;
+
+      if (isLexH)
+      {
+        lh.startCDATA();
+      }
+      
+      dispatachChars(node);
+
+      {
+        if (isLexH)
+        {
+          lh.endCDATA();
+        }
+      }
+    }
+    break;
+    case Node.TEXT_NODE :
+    {
+      //String data = ((Text) node).getData();
+
+      if (nextIsRaw)
+      {
+        nextIsRaw = false;
+
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
+        dispatachChars(node);
+        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
+      }
+      else
+      {
+        dispatachChars(node);
+      }
+    }
+    break;
+    case Node.ENTITY_REFERENCE_NODE :
+    {
+      EntityReference eref = (EntityReference) node;
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        ((LexicalHandler) this.m_contentHandler).startEntity(
+          eref.getNodeName());
+      }
+      else
+      {
+
+        // warning("Can not output entity to a pure SAX ContentHandler");
+      }
+    }
+    break;
+    default :
+    }
+  }
+
+  /**
+   * End processing of given node 
+   *
+   *
+   * @param node Node we just finished processing
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  protected void endNode(Node node) throws org.xml.sax.SAXException
+  {
+
+    switch (node.getNodeType())
+    {
+    case Node.DOCUMENT_NODE :
+      break;
+      
+    case Node.ELEMENT_NODE :
+      String ns = m_dh.getNamespaceOfNode(node);
+      if(null == ns)
+        ns = "";
+      this.m_contentHandler.endElement(ns,
+                                         m_dh.getLocalNameOfNode(node),
+                                         node.getNodeName());
+
+      NamedNodeMap atts = ((Element) node).getAttributes();
+      int nAttrs = atts.getLength();
+
+      for (int i = 0; i < nAttrs; i++)
+      {
+        Node attr = atts.item(i);
+        String attrName = attr.getNodeName();
+
+        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
+        {
+          int index;
+          // Use "" instead of null, as Xerces likes "" for the 
+          // name of the default namespace.  Fix attributed 
+          // to "Steven Murray" <smurray@ebt.com>.
+          String prefix = (index = attrName.indexOf(":")) < 0
+                          ? "" : attrName.substring(index + 1);
+
+          this.m_contentHandler.endPrefixMapping(prefix);
+        }
+      }
+      break;
+    case Node.CDATA_SECTION_NODE :
+      break;
+    case Node.ENTITY_REFERENCE_NODE :
+    {
+      EntityReference eref = (EntityReference) node;
+
+      if (m_contentHandler instanceof LexicalHandler)
+      {
+        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
+
+        lh.endEntity(eref.getNodeName());
+      }
+    }
+    break;
+    default :
+    }
+  }
+}  //TreeWalker
+
diff --git a/src/main/java/org/apache/xml/utils/URI.java b/src/main/java/org/apache/xml/utils/URI.java
new file mode 100644
index 0000000..4bee2d1
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/URI.java
@@ -0,0 +1,1673 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: URI.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+/**
+ * A class to represent a Uniform Resource Identifier (URI). This class
+ * is designed to handle the parsing of URIs and provide access to
+ * the various components (scheme, host, port, userinfo, path, query
+ * string and fragment) that may constitute a URI.
+ * <p>
+ * Parsing of a URI specification is done according to the URI
+ * syntax described in RFC 2396
+ * <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists
+ * of a scheme, followed by a colon (':'), followed by a scheme-specific
+ * part. For URIs that follow the "generic URI" syntax, the scheme-
+ * specific part begins with two slashes ("//") and may be followed
+ * by an authority segment (comprised of user information, host, and
+ * port), path segment, query segment and fragment. Note that RFC 2396
+ * no longer specifies the use of the parameters segment and excludes
+ * the "user:password" syntax as part of the authority segment. If
+ * "user:password" appears in a URI, the entire user/password string
+ * is stored as userinfo.
+ * <p>
+ * For URIs that do not follow the "generic URI" syntax (e.g. mailto),
+ * the entire scheme-specific part is treated as the "path" portion
+ * of the URI.
+ * <p>
+ * Note that, unlike the java.net.URL class, this class does not provide
+ * any built-in network access functionality nor does it provide any
+ * scheme-specific functionality (for example, it does not know a
+ * default port for a specific scheme). Rather, it only knows the
+ * grammar and basic set of operations that can be applied to a URI.
+ *
+ *
+ */
+public class URI implements Serializable
+{
+    static final long serialVersionUID = 7096266377907081897L;
+
+  /**
+   * MalformedURIExceptions are thrown in the process of building a URI
+   * or setting fields on a URI when an operation would result in an
+   * invalid URI specification.
+   *
+   */
+  public static class MalformedURIException extends IOException
+  {
+
+    /**
+     * Constructs a <code>MalformedURIException</code> with no specified
+     * detail message.
+     */
+    public MalformedURIException()
+    {
+      super();
+    }
+
+    /**
+     * Constructs a <code>MalformedURIException</code> with the
+     * specified detail message.
+     *
+     * @param p_msg the detail message.
+     */
+    public MalformedURIException(String p_msg)
+    {
+      super(p_msg);
+    }
+  }
+
+  /** reserved characters */
+  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";
+
+  /**
+   * URI punctuation mark characters - these, combined with
+   *   alphanumerics, constitute the "unreserved" characters 
+   */
+  private static final String MARK_CHARACTERS = "-_.!~*'() ";
+
+  /** scheme can be composed of alphanumerics and these characters */
+  private static final String SCHEME_CHARACTERS = "+-.";
+
+  /**
+   * userinfo can be composed of unreserved, escaped and these
+   *   characters 
+   */
+  private static final String USERINFO_CHARACTERS = ";:&=+$,";
+
+  /** Stores the scheme (usually the protocol) for this URI.
+   *  @serial */
+  private String m_scheme = null;
+
+  /** If specified, stores the userinfo for this URI; otherwise null.
+   *  @serial */
+  private String m_userinfo = null;
+
+  /** If specified, stores the host for this URI; otherwise null.
+   *  @serial */
+  private String m_host = null;
+
+  /** If specified, stores the port for this URI; otherwise -1.
+   *  @serial */
+  private int m_port = -1;
+
+  /** If specified, stores the path for this URI; otherwise null.
+   *  @serial */
+  private String m_path = null;
+
+  /**
+   * If specified, stores the query string for this URI; otherwise
+   *   null. 
+   * @serial 
+   */
+  private String m_queryString = null;
+
+  /** If specified, stores the fragment for this URI; otherwise null.
+   *  @serial */
+  private String m_fragment = null;
+
+  /** Indicate whether in DEBUG mode          */
+  private static boolean DEBUG = false;
+
+  /**
+   * Construct a new and uninitialized URI.
+   */
+  public URI(){}
+
+  /**
+   * Construct a new URI from another URI. All fields for this URI are
+   * set equal to the fields of the URI passed in.
+   *
+   * @param p_other the URI to copy (cannot be null)
+   */
+  public URI(URI p_other)
+  {
+    initialize(p_other);
+  }
+
+  /**
+   * Construct a new URI from a URI specification string. If the
+   * specification follows the "generic URI" syntax, (two slashes
+   * following the first colon), the specification will be parsed
+   * accordingly - setting the scheme, userinfo, host,port, path, query
+   * string and fragment fields as necessary. If the specification does
+   * not follow the "generic URI" syntax, the specification is parsed
+   * into a scheme and scheme-specific part (stored as the path) only.
+   *
+   * @param p_uriSpec the URI specification string (cannot be null or
+   *                  empty)
+   *
+   * @throws MalformedURIException if p_uriSpec violates any syntax
+   *                                   rules
+   */
+  public URI(String p_uriSpec) throws MalformedURIException
+  {
+    this((URI) null, p_uriSpec);
+  }
+
+  /**
+   * Construct a new URI from a base URI and a URI specification string.
+   * The URI specification string may be a relative URI.
+   *
+   * @param p_base the base URI (cannot be null if p_uriSpec is null or
+   *               empty)
+   * @param p_uriSpec the URI specification string (cannot be null or
+   *                  empty if p_base is null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates any syntax
+   *                                  rules
+   */
+  public URI(URI p_base, String p_uriSpec) throws MalformedURIException
+  {
+    initialize(p_base, p_uriSpec);
+  }
+
+  /**
+   * Construct a new URI that does not follow the generic URI syntax.
+   * Only the scheme and scheme-specific part (stored as the path) are
+   * initialized.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_schemeSpecificPart the scheme-specific part (cannot be
+   *                             null or empty)
+   *
+   * @throws MalformedURIException if p_scheme violates any
+   *                                  syntax rules
+   */
+  public URI(String p_scheme, String p_schemeSpecificPart)
+          throws MalformedURIException
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      throw new MalformedURIException(
+        "Cannot construct URI with null/empty scheme!");
+    }
+
+    if (p_schemeSpecificPart == null
+            || p_schemeSpecificPart.trim().length() == 0)
+    {
+      throw new MalformedURIException(
+        "Cannot construct URI with null/empty scheme-specific part!");
+    }
+
+    setScheme(p_scheme);
+    setPath(p_schemeSpecificPart);
+  }
+
+  /**
+   * Construct a new URI that follows the generic URI syntax from its
+   * component parts. Each component is validated for syntax and some
+   * basic semantic checks are performed as well.  See the individual
+   * setter methods for specifics.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_host the hostname or IPv4 address for the URI
+   * @param p_path the URI path - if the path contains '?' or '#',
+   *               then the query string and/or fragment will be
+   *               set from the path; however, if the query and
+   *               fragment are specified both in the path and as
+   *               separate parameters, an exception is thrown
+   * @param p_queryString the URI query string (cannot be specified
+   *                      if path is null)
+   * @param p_fragment the URI fragment (cannot be specified if path
+   *                   is null)
+   *
+   * @throws MalformedURIException if any of the parameters violates
+   *                                  syntax rules or semantic rules
+   */
+  public URI(String p_scheme, String p_host, String p_path, String p_queryString, String p_fragment)
+          throws MalformedURIException
+  {
+    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
+  }
+
+  /**
+   * Construct a new URI that follows the generic URI syntax from its
+   * component parts. Each component is validated for syntax and some
+   * basic semantic checks are performed as well.  See the individual
+   * setter methods for specifics.
+   *
+   * @param p_scheme the URI scheme (cannot be null or empty)
+   * @param p_userinfo the URI userinfo (cannot be specified if host
+   *                   is null)
+   * @param p_host the hostname or IPv4 address for the URI
+   * @param p_port the URI port (may be -1 for "unspecified"; cannot
+   *               be specified if host is null)
+   * @param p_path the URI path - if the path contains '?' or '#',
+   *               then the query string and/or fragment will be
+   *               set from the path; however, if the query and
+   *               fragment are specified both in the path and as
+   *               separate parameters, an exception is thrown
+   * @param p_queryString the URI query string (cannot be specified
+   *                      if path is null)
+   * @param p_fragment the URI fragment (cannot be specified if path
+   *                   is null)
+   *
+   * @throws MalformedURIException if any of the parameters violates
+   *                                  syntax rules or semantic rules
+   */
+  public URI(String p_scheme, String p_userinfo, String p_host, int p_port, String p_path, String p_queryString, String p_fragment)
+          throws MalformedURIException
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_REQUIRED, null)); //"Scheme is required!");
+    }
+
+    if (p_host == null)
+    {
+      if (p_userinfo != null)
+      {
+        throw new MalformedURIException(
+          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_USERINFO_IF_NO_HOST, null)); //"Userinfo may not be specified if host is not specified!");
+      }
+
+      if (p_port != -1)
+      {
+        throw new MalformedURIException(
+          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_PORT_IF_NO_HOST, null)); //"Port may not be specified if host is not specified!");
+      }
+    }
+
+    if (p_path != null)
+    {
+      if (p_path.indexOf('?') != -1 && p_queryString != null)
+      {
+        throw new MalformedURIException(
+          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_QUERY_STRING_IN_PATH, null)); //"Query string cannot be specified in path and query string!");
+      }
+
+      if (p_path.indexOf('#') != -1 && p_fragment != null)
+      {
+        throw new MalformedURIException(
+          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_FRAGMENT_STRING_IN_PATH, null)); //"Fragment cannot be specified in both the path and fragment!");
+      }
+    }
+
+    setScheme(p_scheme);
+    setHost(p_host);
+    setPort(p_port);
+    setUserinfo(p_userinfo);
+    setPath(p_path);
+    setQueryString(p_queryString);
+    setFragment(p_fragment);
+  }
+
+  /**
+   * Initialize all fields of this URI from another URI.
+   *
+   * @param p_other the URI to copy (cannot be null)
+   */
+  private void initialize(URI p_other)
+  {
+
+    m_scheme = p_other.getScheme();
+    m_userinfo = p_other.getUserinfo();
+    m_host = p_other.getHost();
+    m_port = p_other.getPort();
+    m_path = p_other.getPath();
+    m_queryString = p_other.getQueryString();
+    m_fragment = p_other.getFragment();
+  }
+
+  /**
+   * Initializes this URI from a base URI and a URI specification string.
+   * See RFC 2396 Section 4 and Appendix B for specifications on parsing
+   * the URI and Section 5 for specifications on resolving relative URIs
+   * and relative paths.
+   *
+   * @param p_base the base URI (may be null if p_uriSpec is an absolute
+   *               URI)
+   * @param p_uriSpec the URI spec string which may be an absolute or
+   *                  relative URI (can only be null/empty if p_base
+   *                  is not null)
+   *
+   * @throws MalformedURIException if p_base is null and p_uriSpec
+   *                                  is not an absolute URI or if
+   *                                  p_uriSpec violates syntax rules
+   */
+  private void initialize(URI p_base, String p_uriSpec)
+          throws MalformedURIException
+  {
+
+    if (p_base == null
+            && (p_uriSpec == null || p_uriSpec.trim().length() == 0))
+    {
+      throw new MalformedURIException(
+        XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_INIT_URI_EMPTY_PARMS, null)); //"Cannot initialize URI with empty parameters.");
+    }
+
+    // just make a copy of the base if spec is empty
+    if (p_uriSpec == null || p_uriSpec.trim().length() == 0)
+    {
+      initialize(p_base);
+
+      return;
+    }
+
+    String uriSpec = p_uriSpec.trim();
+    int uriSpecLen = uriSpec.length();
+    int index = 0;
+
+    // check for scheme
+    int colonIndex = uriSpec.indexOf(':');
+    if (colonIndex < 0)
+    {
+      if (p_base == null)
+      {
+        throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_IN_URI, new Object[]{uriSpec})); //"No scheme found in URI: "+uriSpec);
+      }
+    }
+    else
+    {
+      initializeScheme(uriSpec);
+      uriSpec = uriSpec.substring(colonIndex+1);
+      // This is a fix for XALANJ-2059.
+      if(m_scheme != null && p_base != null)
+      {	  	
+        // a) If <uriSpec> starts with a slash (/), it means <uriSpec> is absolute 
+        //    and p_base can be ignored.
+        //    For example,
+        //    uriSpec = file:/myDIR/myXSLFile.xsl
+        //    p_base = file:/myWork/
+        //
+        //    Here, uriSpec has absolute path after scheme file and :
+        //    Hence p_base can be ignored.
+        // 
+        // b) Similarily, according to RFC 2396, uri is resolved for <uriSpec> relative to <p_base>
+        //    if scheme in <uriSpec> is same as scheme in <p_base>, else p_base can be ignored.
+        // 
+        // c) if <p_base> is not hierarchical, it can be ignored.
+        //
+        if(uriSpec.startsWith("/") || !m_scheme.equals(p_base.m_scheme) || !p_base.getSchemeSpecificPart().startsWith("/"))
+        {
+          p_base = null;
+        }
+      }
+      // Fix for XALANJ-2059  
+      uriSpecLen = uriSpec.length();
+    }
+
+    // two slashes means generic URI syntax, so we get the authority
+    if (uriSpec.startsWith("//"))
+    {
+      index += 2;
+
+      int startPos = index;
+
+      // get authority - everything up to path, query or fragment
+      char testChar = '\0';
+
+      while (index < uriSpecLen)
+      {
+        testChar = uriSpec.charAt(index);
+
+        if (testChar == '/' || testChar == '?' || testChar == '#')
+        {
+          break;
+        }
+
+        index++;
+      }
+
+      // if we found authority, parse it out, otherwise we set the
+      // host to empty string
+      if (index > startPos)
+      {
+        initializeAuthority(uriSpec.substring(startPos, index));
+      }
+      else
+      {
+        m_host = "";
+      }
+    }
+
+    initializePath(uriSpec.substring(index));
+
+    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
+    // In some cases, it might make more sense to throw an exception
+    // (when scheme is specified is the string spec and the base URI
+    // is also specified, for example), but we're just following the
+    // RFC specifications 
+    if (p_base != null)
+    {
+
+      // check to see if this is the current doc - RFC 2396 5.2 #2
+      // note that this is slightly different from the RFC spec in that
+      // we don't include the check for query string being null
+      // - this handles cases where the urispec is just a query
+      // string or a fragment (e.g. "?y" or "#s") - 
+      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
+      // identified this as a bug in the RFC
+      if (m_path.length() == 0 && m_scheme == null && m_host == null)
+      {
+        m_scheme = p_base.getScheme();
+        m_userinfo = p_base.getUserinfo();
+        m_host = p_base.getHost();
+        m_port = p_base.getPort();
+        m_path = p_base.getPath();
+
+        if (m_queryString == null)
+        {
+          m_queryString = p_base.getQueryString();
+        }
+
+        return;
+      }
+
+      // check for scheme - RFC 2396 5.2 #3
+      // if we found a scheme, it means absolute URI, so we're done
+      if (m_scheme == null)
+      {
+        m_scheme = p_base.getScheme();
+      }
+
+      // check for authority - RFC 2396 5.2 #4
+      // if we found a host, then we've got a network path, so we're done
+      if (m_host == null)
+      {
+        m_userinfo = p_base.getUserinfo();
+        m_host = p_base.getHost();
+        m_port = p_base.getPort();
+      }
+      else
+      {
+        return;
+      }
+
+      // check for absolute path - RFC 2396 5.2 #5
+      if (m_path.length() > 0 && m_path.startsWith("/"))
+      {
+        return;
+      }
+
+      // if we get to this point, we need to resolve relative path
+      // RFC 2396 5.2 #6
+      String path = new String();
+      String basePath = p_base.getPath();
+
+      // 6a - get all but the last segment of the base URI path
+      if (basePath != null)
+      {
+        int lastSlash = basePath.lastIndexOf('/');
+
+        if (lastSlash != -1)
+        {
+          path = basePath.substring(0, lastSlash + 1);
+        }
+      }
+
+      // 6b - append the relative URI path
+      path = path.concat(m_path);
+
+      // 6c - remove all "./" where "." is a complete path segment
+      index = -1;
+
+      while ((index = path.indexOf("/./")) != -1)
+      {
+        path = path.substring(0, index + 1).concat(path.substring(index + 3));
+      }
+
+      // 6d - remove "." if path ends with "." as a complete path segment
+      if (path.endsWith("/."))
+      {
+        path = path.substring(0, path.length() - 1);
+      }
+
+      // 6e - remove all "<segment>/../" where "<segment>" is a complete 
+      // path segment not equal to ".."
+      index = -1;
+
+      int segIndex = -1;
+      String tempString = null;
+
+      while ((index = path.indexOf("/../")) > 0)
+      {
+        tempString = path.substring(0, path.indexOf("/../"));
+        segIndex = tempString.lastIndexOf('/');
+
+        if (segIndex != -1)
+        {
+          if (!tempString.substring(segIndex++).equals(".."))
+          {
+            path = path.substring(0, segIndex).concat(path.substring(index
+                    + 4));
+          }
+        }
+      }
+
+      // 6f - remove ending "<segment>/.." where "<segment>" is a 
+      // complete path segment
+      if (path.endsWith("/.."))
+      {
+        tempString = path.substring(0, path.length() - 3);
+        segIndex = tempString.lastIndexOf('/');
+
+        if (segIndex != -1)
+        {
+          path = path.substring(0, segIndex + 1);
+        }
+      }
+
+      m_path = path;
+    }
+  }
+
+  /**
+   * Initialize the scheme for this URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if URI does not have a conformant
+   *                                  scheme
+   */
+  private void initializeScheme(String p_uriSpec) throws MalformedURIException
+  {
+
+    int uriSpecLen = p_uriSpec.length();
+    int index = 0;
+    String scheme = null;
+    char testChar = '\0';
+
+    while (index < uriSpecLen)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == ':' || testChar == '/' || testChar == '?'
+              || testChar == '#')
+      {
+        break;
+      }
+
+      index++;
+    }
+
+    scheme = p_uriSpec.substring(0, index);
+
+    if (scheme.length() == 0)
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_INURI, null)); //"No scheme found in URI.");
+    }
+    else
+    {
+      setScheme(scheme);
+    }
+  }
+
+  /**
+   * Initialize the authority (userinfo, host and port) for this
+   * URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates syntax rules
+   */
+  private void initializeAuthority(String p_uriSpec)
+          throws MalformedURIException
+  {
+
+    int index = 0;
+    int start = 0;
+    int end = p_uriSpec.length();
+    char testChar = '\0';
+    String userinfo = null;
+
+    // userinfo is everything up @
+    if (p_uriSpec.indexOf('@', start) != -1)
+    {
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '@')
+        {
+          break;
+        }
+
+        index++;
+      }
+
+      userinfo = p_uriSpec.substring(start, index);
+
+      index++;
+    }
+
+    // host is everything up to ':'
+    String host = null;
+
+    start = index;
+
+    while (index < end)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == ':')
+      {
+        break;
+      }
+
+      index++;
+    }
+
+    host = p_uriSpec.substring(start, index);
+
+    int port = -1;
+
+    if (host.length() > 0)
+    {
+
+      // port
+      if (testChar == ':')
+      {
+        index++;
+
+        start = index;
+
+        while (index < end)
+        {
+          index++;
+        }
+
+        String portStr = p_uriSpec.substring(start, index);
+
+        if (portStr.length() > 0)
+        {
+          for (int i = 0; i < portStr.length(); i++)
+          {
+            if (!isDigit(portStr.charAt(i)))
+            {
+              throw new MalformedURIException(
+                portStr + " is invalid. Port should only contain digits!");
+            }
+          }
+
+          try
+          {
+            port = Integer.parseInt(portStr);
+          }
+          catch (NumberFormatException nfe)
+          {
+
+            // can't happen
+          }
+        }
+      }
+    }
+
+    setHost(host);
+    setPort(port);
+    setUserinfo(userinfo);
+  }
+
+  /**
+   * Initialize the path for this URI from a URI string spec.
+   *
+   * @param p_uriSpec the URI specification (cannot be null)
+   *
+   * @throws MalformedURIException if p_uriSpec violates syntax rules
+   */
+  private void initializePath(String p_uriSpec) throws MalformedURIException
+  {
+
+    if (p_uriSpec == null)
+    {
+      throw new MalformedURIException(
+        "Cannot initialize path from null string!");
+    }
+
+    int index = 0;
+    int start = 0;
+    int end = p_uriSpec.length();
+    char testChar = '\0';
+
+    // path - everything up to query string or fragment
+    while (index < end)
+    {
+      testChar = p_uriSpec.charAt(index);
+
+      if (testChar == '?' || testChar == '#')
+      {
+        break;
+      }
+
+      // check for valid escape sequence
+      if (testChar == '%')
+      {
+        if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                ||!isHex(p_uriSpec.charAt(index + 2)))
+        {
+          throw new MalformedURIException(
+            XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE, null)); //"Path contains invalid escape sequence!");
+        }
+      }
+      else if (!isReservedCharacter(testChar)
+               &&!isUnreservedCharacter(testChar))
+      {
+        if ('\\' != testChar)
+          throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{String.valueOf(testChar)})); //"Path contains invalid character: "
+                                          //+ testChar);
+      }
+
+      index++;
+    }
+
+    m_path = p_uriSpec.substring(start, index);
+
+    // query - starts with ? and up to fragment or end
+    if (testChar == '?')
+    {
+      index++;
+
+      start = index;
+
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '#')
+        {
+          break;
+        }
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                  ||!isHex(p_uriSpec.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Query string contains invalid escape sequence!");
+          }
+        }
+        else if (!isReservedCharacter(testChar)
+                 &&!isUnreservedCharacter(testChar))
+        {
+          throw new MalformedURIException(
+            "Query string contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+
+      m_queryString = p_uriSpec.substring(start, index);
+    }
+
+    // fragment - starts with #
+    if (testChar == '#')
+    {
+      index++;
+
+      start = index;
+
+      while (index < end)
+      {
+        testChar = p_uriSpec.charAt(index);
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
+                  ||!isHex(p_uriSpec.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Fragment contains invalid escape sequence!");
+          }
+        }
+        else if (!isReservedCharacter(testChar)
+                 &&!isUnreservedCharacter(testChar))
+        {
+          throw new MalformedURIException(
+            "Fragment contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+
+      m_fragment = p_uriSpec.substring(start, index);
+    }
+  }
+
+  /**
+   * Get the scheme for this URI.
+   *
+   * @return the scheme for this URI
+   */
+  public String getScheme()
+  {
+    return m_scheme;
+  }
+
+  /**
+   * Get the scheme-specific part for this URI (everything following the
+   * scheme and the first colon). See RFC 2396 Section 5.2 for spec.
+   *
+   * @return the scheme-specific part for this URI
+   */
+  public String getSchemeSpecificPart()
+  {
+
+    StringBuffer schemespec = new StringBuffer();
+
+    if (m_userinfo != null || m_host != null || m_port != -1)
+    {
+      schemespec.append("//");
+    }
+
+    if (m_userinfo != null)
+    {
+      schemespec.append(m_userinfo);
+      schemespec.append('@');
+    }
+
+    if (m_host != null)
+    {
+      schemespec.append(m_host);
+    }
+
+    if (m_port != -1)
+    {
+      schemespec.append(':');
+      schemespec.append(m_port);
+    }
+
+    if (m_path != null)
+    {
+      schemespec.append((m_path));
+    }
+
+    if (m_queryString != null)
+    {
+      schemespec.append('?');
+      schemespec.append(m_queryString);
+    }
+
+    if (m_fragment != null)
+    {
+      schemespec.append('#');
+      schemespec.append(m_fragment);
+    }
+
+    return schemespec.toString();
+  }
+
+  /**
+   * Get the userinfo for this URI.
+   *
+   * @return the userinfo for this URI (null if not specified).
+   */
+  public String getUserinfo()
+  {
+    return m_userinfo;
+  }
+
+  /**
+   * Get the host for this URI.
+   *
+   * @return the host for this URI (null if not specified).
+   */
+  public String getHost()
+  {
+    return m_host;
+  }
+
+  /**
+   * Get the port for this URI.
+   *
+   * @return the port for this URI (-1 if not specified).
+   */
+  public int getPort()
+  {
+    return m_port;
+  }
+
+  /**
+   * Get the path for this URI (optionally with the query string and
+   * fragment).
+   *
+   * @param p_includeQueryString if true (and query string is not null),
+   *                             then a "?" followed by the query string
+   *                             will be appended
+   * @param p_includeFragment if true (and fragment is not null),
+   *                             then a "#" followed by the fragment
+   *                             will be appended
+   *
+   * @return the path for this URI possibly including the query string
+   *         and fragment
+   */
+  public String getPath(boolean p_includeQueryString,
+                        boolean p_includeFragment)
+  {
+
+    StringBuffer pathString = new StringBuffer(m_path);
+
+    if (p_includeQueryString && m_queryString != null)
+    {
+      pathString.append('?');
+      pathString.append(m_queryString);
+    }
+
+    if (p_includeFragment && m_fragment != null)
+    {
+      pathString.append('#');
+      pathString.append(m_fragment);
+    }
+
+    return pathString.toString();
+  }
+
+  /**
+   * Get the path for this URI. Note that the value returned is the path
+   * only and does not include the query string or fragment.
+   *
+   * @return the path for this URI.
+   */
+  public String getPath()
+  {
+    return m_path;
+  }
+
+  /**
+   * Get the query string for this URI.
+   *
+   * @return the query string for this URI. Null is returned if there
+   *         was no "?" in the URI spec, empty string if there was a
+   *         "?" but no query string following it.
+   */
+  public String getQueryString()
+  {
+    return m_queryString;
+  }
+
+  /**
+   * Get the fragment for this URI.
+   *
+   * @return the fragment for this URI. Null is returned if there
+   *         was no "#" in the URI spec, empty string if there was a
+   *         "#" but no fragment following it.
+   */
+  public String getFragment()
+  {
+    return m_fragment;
+  }
+
+  /**
+   * Set the scheme for this URI. The scheme is converted to lowercase
+   * before it is set.
+   *
+   * @param p_scheme the scheme for this URI (cannot be null)
+   *
+   * @throws MalformedURIException if p_scheme is not a conformant
+   *                                  scheme name
+   */
+  public void setScheme(String p_scheme) throws MalformedURIException
+  {
+
+    if (p_scheme == null)
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_FROM_NULL_STRING, null)); //"Cannot set scheme from null string!");
+    }
+
+    if (!isConformantSchemeName(p_scheme))
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_NOT_CONFORMANT, null)); //"The scheme is not conformant.");
+    }
+
+    m_scheme = p_scheme.toLowerCase();
+  }
+
+  /**
+   * Set the userinfo for this URI. If a non-null value is passed in and
+   * the host value is null, then an exception is thrown.
+   *
+   * @param p_userinfo the userinfo for this URI
+   *
+   * @throws MalformedURIException if p_userinfo contains invalid
+   *                                  characters
+   */
+  public void setUserinfo(String p_userinfo) throws MalformedURIException
+  {
+
+    if (p_userinfo == null)
+    {
+      m_userinfo = null;
+    }
+    else
+    {
+      if (m_host == null)
+      {
+        throw new MalformedURIException(
+          "Userinfo cannot be set when host is null!");
+      }
+
+      // userinfo can contain alphanumerics, mark characters, escaped
+      // and ';',':','&','=','+','$',','
+      int index = 0;
+      int end = p_userinfo.length();
+      char testChar = '\0';
+
+      while (index < end)
+      {
+        testChar = p_userinfo.charAt(index);
+
+        if (testChar == '%')
+        {
+          if (index + 2 >= end ||!isHex(p_userinfo.charAt(index + 1))
+                  ||!isHex(p_userinfo.charAt(index + 2)))
+          {
+            throw new MalformedURIException(
+              "Userinfo contains invalid escape sequence!");
+          }
+        }
+        else if (!isUnreservedCharacter(testChar)
+                 && USERINFO_CHARACTERS.indexOf(testChar) == -1)
+        {
+          throw new MalformedURIException(
+            "Userinfo contains invalid character:" + testChar);
+        }
+
+        index++;
+      }
+    }
+
+    m_userinfo = p_userinfo;
+  }
+
+  /**
+   * Set the host for this URI. If null is passed in, the userinfo
+   * field is also set to null and the port is set to -1.
+   *
+   * @param p_host the host for this URI
+   *
+   * @throws MalformedURIException if p_host is not a valid IP
+   *                                  address or DNS hostname.
+   */
+  public void setHost(String p_host) throws MalformedURIException
+  {
+
+    if (p_host == null || p_host.trim().length() == 0)
+    {
+      m_host = p_host;
+      m_userinfo = null;
+      m_port = -1;
+    }
+    else if (!isWellFormedAddress(p_host))
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_HOST_ADDRESS_NOT_WELLFORMED, null)); //"Host is not a well formed address!");
+    }
+
+    m_host = p_host;
+  }
+
+  /**
+   * Set the port for this URI. -1 is used to indicate that the port is
+   * not specified, otherwise valid port numbers are  between 0 and 65535.
+   * If a valid port number is passed in and the host field is null,
+   * an exception is thrown.
+   *
+   * @param p_port the port number for this URI
+   *
+   * @throws MalformedURIException if p_port is not -1 and not a
+   *                                  valid port number
+   */
+  public void setPort(int p_port) throws MalformedURIException
+  {
+
+    if (p_port >= 0 && p_port <= 65535)
+    {
+      if (m_host == null)
+      {
+        throw new MalformedURIException(
+          XMLMessages.createXMLMessage(XMLErrorResources.ER_PORT_WHEN_HOST_NULL, null)); //"Port cannot be set when host is null!");
+      }
+    }
+    else if (p_port != -1)
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INVALID_PORT, null)); //"Invalid port number!");
+    }
+
+    m_port = p_port;
+  }
+
+  /**
+   * Set the path for this URI. If the supplied path is null, then the
+   * query string and fragment are set to null as well. If the supplied
+   * path includes a query string and/or fragment, these fields will be
+   * parsed and set as well. Note that, for URIs following the "generic
+   * URI" syntax, the path specified should start with a slash.
+   * For URIs that do not follow the generic URI syntax, this method
+   * sets the scheme-specific part.
+   *
+   * @param p_path the path for this URI (may be null)
+   *
+   * @throws MalformedURIException if p_path contains invalid
+   *                                  characters
+   */
+  public void setPath(String p_path) throws MalformedURIException
+  {
+
+    if (p_path == null)
+    {
+      m_path = null;
+      m_queryString = null;
+      m_fragment = null;
+    }
+    else
+    {
+      initializePath(p_path);
+    }
+  }
+
+  /**
+   * Append to the end of the path of this URI. If the current path does
+   * not end in a slash and the path to be appended does not begin with
+   * a slash, a slash will be appended to the current path before the
+   * new segment is added. Also, if the current path ends in a slash
+   * and the new segment begins with a slash, the extra slash will be
+   * removed before the new segment is appended.
+   *
+   * @param p_addToPath the new segment to be added to the current path
+   *
+   * @throws MalformedURIException if p_addToPath contains syntax
+   *                                  errors
+   */
+  public void appendPath(String p_addToPath) throws MalformedURIException
+  {
+
+    if (p_addToPath == null || p_addToPath.trim().length() == 0)
+    {
+      return;
+    }
+
+    if (!isURIString(p_addToPath))
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{p_addToPath})); //"Path contains invalid character!");
+    }
+
+    if (m_path == null || m_path.trim().length() == 0)
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = p_addToPath;
+      }
+      else
+      {
+        m_path = "/" + p_addToPath;
+      }
+    }
+    else if (m_path.endsWith("/"))
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = m_path.concat(p_addToPath.substring(1));
+      }
+      else
+      {
+        m_path = m_path.concat(p_addToPath);
+      }
+    }
+    else
+    {
+      if (p_addToPath.startsWith("/"))
+      {
+        m_path = m_path.concat(p_addToPath);
+      }
+      else
+      {
+        m_path = m_path.concat("/" + p_addToPath);
+      }
+    }
+  }
+
+  /**
+   * Set the query string for this URI. A non-null value is valid only
+   * if this is an URI conforming to the generic URI syntax and
+   * the path value is not null.
+   *
+   * @param p_queryString the query string for this URI
+   *
+   * @throws MalformedURIException if p_queryString is not null and this
+   *                                  URI does not conform to the generic
+   *                                  URI syntax or if the path is null
+   */
+  public void setQueryString(String p_queryString)
+          throws MalformedURIException
+  {
+
+    if (p_queryString == null)
+    {
+      m_queryString = null;
+    }
+    else if (!isGenericURI())
+    {
+      throw new MalformedURIException(
+        "Query string can only be set for a generic URI!");
+    }
+    else if (getPath() == null)
+    {
+      throw new MalformedURIException(
+        "Query string cannot be set when path is null!");
+    }
+    else if (!isURIString(p_queryString))
+    {
+      throw new MalformedURIException(
+        "Query string contains invalid character!");
+    }
+    else
+    {
+      m_queryString = p_queryString;
+    }
+  }
+
+  /**
+   * Set the fragment for this URI. A non-null value is valid only
+   * if this is a URI conforming to the generic URI syntax and
+   * the path value is not null.
+   *
+   * @param p_fragment the fragment for this URI
+   *
+   * @throws MalformedURIException if p_fragment is not null and this
+   *                                  URI does not conform to the generic
+   *                                  URI syntax or if the path is null
+   */
+  public void setFragment(String p_fragment) throws MalformedURIException
+  {
+
+    if (p_fragment == null)
+    {
+      m_fragment = null;
+    }
+    else if (!isGenericURI())
+    {
+      throw new MalformedURIException(
+        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_FOR_GENERIC_URI, null)); //"Fragment can only be set for a generic URI!");
+    }
+    else if (getPath() == null)
+    {
+      throw new MalformedURIException(
+        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_WHEN_PATH_NULL, null)); //"Fragment cannot be set when path is null!");
+    }
+    else if (!isURIString(p_fragment))
+    {
+      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_INVALID_CHAR, null)); //"Fragment contains invalid character!");
+    }
+    else
+    {
+      m_fragment = p_fragment;
+    }
+  }
+
+  /**
+   * Determines if the passed-in Object is equivalent to this URI.
+   *
+   * @param p_test the Object to test for equality.
+   *
+   * @return true if p_test is a URI with all values equal to this
+   *         URI, false otherwise
+   */
+  public boolean equals(Object p_test)
+  {
+
+    if (p_test instanceof URI)
+    {
+      URI testURI = (URI) p_test;
+
+      if (((m_scheme == null && testURI.m_scheme == null) || (m_scheme != null && testURI.m_scheme != null && m_scheme.equals(
+              testURI.m_scheme))) && ((m_userinfo == null && testURI.m_userinfo == null) || (m_userinfo != null && testURI.m_userinfo != null && m_userinfo.equals(
+              testURI.m_userinfo))) && ((m_host == null && testURI.m_host == null) || (m_host != null && testURI.m_host != null && m_host.equals(
+              testURI.m_host))) && m_port == testURI.m_port && ((m_path == null && testURI.m_path == null) || (m_path != null && testURI.m_path != null && m_path.equals(
+              testURI.m_path))) && ((m_queryString == null && testURI.m_queryString == null) || (m_queryString != null && testURI.m_queryString != null && m_queryString.equals(
+              testURI.m_queryString))) && ((m_fragment == null && testURI.m_fragment == null) || (m_fragment != null && testURI.m_fragment != null && m_fragment.equals(
+              testURI.m_fragment))))
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Get the URI as a string specification. See RFC 2396 Section 5.2.
+   *
+   * @return the URI string specification
+   */
+  public String toString()
+  {
+
+    StringBuffer uriSpecString = new StringBuffer();
+
+    if (m_scheme != null)
+    {
+      uriSpecString.append(m_scheme);
+      uriSpecString.append(':');
+    }
+
+    uriSpecString.append(getSchemeSpecificPart());
+
+    return uriSpecString.toString();
+  }
+
+  /**
+   * Get the indicator as to whether this URI uses the "generic URI"
+   * syntax.
+   *
+   * @return true if this URI uses the "generic URI" syntax, false
+   *         otherwise
+   */
+  public boolean isGenericURI()
+  {
+
+    // presence of the host (whether valid or empty) means 
+    // double-slashes which means generic uri
+    return (m_host != null);
+  }
+
+  /**
+   * Determine whether a scheme conforms to the rules for a scheme name.
+   * A scheme is conformant if it starts with an alphanumeric, and
+   * contains only alphanumerics, '+','-' and '.'.
+   *
+   *
+   * @param p_scheme The sheme name to check
+   * @return true if the scheme is conformant, false otherwise
+   */
+  public static boolean isConformantSchemeName(String p_scheme)
+  {
+
+    if (p_scheme == null || p_scheme.trim().length() == 0)
+    {
+      return false;
+    }
+
+    if (!isAlpha(p_scheme.charAt(0)))
+    {
+      return false;
+    }
+
+    char testChar;
+
+    for (int i = 1; i < p_scheme.length(); i++)
+    {
+      testChar = p_scheme.charAt(i);
+
+      if (!isAlphanum(testChar) && SCHEME_CHARACTERS.indexOf(testChar) == -1)
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Determine whether a string is syntactically capable of representing
+   * a valid IPv4 address or the domain name of a network host. A valid
+   * IPv4 address consists of four decimal digit groups separated by a
+   * '.'. A hostname consists of domain labels (each of which must
+   * begin and end with an alphanumeric but may contain '-') separated
+   * & by a '.'. See RFC 2396 Section 3.2.2.
+   *
+   *
+   * @param p_address The address string to check
+   * @return true if the string is a syntactically valid IPv4 address
+   *              or hostname
+   */
+  public static boolean isWellFormedAddress(String p_address)
+  {
+
+    if (p_address == null)
+    {
+      return false;
+    }
+
+    String address = p_address.trim();
+    int addrLength = address.length();
+
+    if (addrLength == 0 || addrLength > 255)
+    {
+      return false;
+    }
+
+    if (address.startsWith(".") || address.startsWith("-"))
+    {
+      return false;
+    }
+
+    // rightmost domain label starting with digit indicates IP address
+    // since top level domain label can only start with an alpha
+    // see RFC 2396 Section 3.2.2
+    int index = address.lastIndexOf('.');
+
+    if (address.endsWith("."))
+    {
+      index = address.substring(0, index).lastIndexOf('.');
+    }
+
+    if (index + 1 < addrLength && isDigit(p_address.charAt(index + 1)))
+    {
+      char testChar;
+      int numDots = 0;
+
+      // make sure that 1) we see only digits and dot separators, 2) that
+      // any dot separator is preceded and followed by a digit and 
+      // 3) that we find 3 dots
+      for (int i = 0; i < addrLength; i++)
+      {
+        testChar = address.charAt(i);
+
+        if (testChar == '.')
+        {
+          if (!isDigit(address.charAt(i - 1))
+                  || (i + 1 < addrLength &&!isDigit(address.charAt(i + 1))))
+          {
+            return false;
+          }
+
+          numDots++;
+        }
+        else if (!isDigit(testChar))
+        {
+          return false;
+        }
+      }
+
+      if (numDots != 3)
+      {
+        return false;
+      }
+    }
+    else
+    {
+
+      // domain labels can contain alphanumerics and '-"
+      // but must start and end with an alphanumeric
+      char testChar;
+
+      for (int i = 0; i < addrLength; i++)
+      {
+        testChar = address.charAt(i);
+
+        if (testChar == '.')
+        {
+          if (!isAlphanum(address.charAt(i - 1)))
+          {
+            return false;
+          }
+
+          if (i + 1 < addrLength &&!isAlphanum(address.charAt(i + 1)))
+          {
+            return false;
+          }
+        }
+        else if (!isAlphanum(testChar) && testChar != '-')
+        {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Determine whether a char is a digit.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is betweeen '0' and '9', false otherwise
+   */
+  private static boolean isDigit(char p_char)
+  {
+    return p_char >= '0' && p_char <= '9';
+  }
+
+  /**
+   * Determine whether a character is a hexadecimal character.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is betweeen '0' and '9', 'a' and 'f'
+   *         or 'A' and 'F', false otherwise
+   */
+  private static boolean isHex(char p_char)
+  {
+    return (isDigit(p_char) || (p_char >= 'a' && p_char <= 'f')
+            || (p_char >= 'A' && p_char <= 'F'));
+  }
+
+  /**
+   * Determine whether a char is an alphabetic character: a-z or A-Z
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is alphabetic, false otherwise
+   */
+  private static boolean isAlpha(char p_char)
+  {
+    return ((p_char >= 'a' && p_char <= 'z')
+            || (p_char >= 'A' && p_char <= 'Z'));
+  }
+
+  /**
+   * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is alphanumeric, false otherwise
+   */
+  private static boolean isAlphanum(char p_char)
+  {
+    return (isAlpha(p_char) || isDigit(p_char));
+  }
+
+  /**
+   * Determine whether a character is a reserved character:
+   * ';', '/', '?', ':', '@', '&', '=', '+', '$' or ','
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the string contains any reserved characters
+   */
+  private static boolean isReservedCharacter(char p_char)
+  {
+    return RESERVED_CHARACTERS.indexOf(p_char) != -1;
+  }
+
+  /**
+   * Determine whether a char is an unreserved character.
+   *
+   *
+   * @param p_char the character to check
+   * @return true if the char is unreserved, false otherwise
+   */
+  private static boolean isUnreservedCharacter(char p_char)
+  {
+    return (isAlphanum(p_char) || MARK_CHARACTERS.indexOf(p_char) != -1);
+  }
+
+  /**
+   * Determine whether a given string contains only URI characters (also
+   * called "uric" in RFC 2396). uric consist of all reserved
+   * characters, unreserved characters and escaped characters.
+   *
+   *
+   * @param p_uric URI string
+   * @return true if the string is comprised of uric, false otherwise
+   */
+  private static boolean isURIString(String p_uric)
+  {
+
+    if (p_uric == null)
+    {
+      return false;
+    }
+
+    int end = p_uric.length();
+    char testChar = '\0';
+
+    for (int i = 0; i < end; i++)
+    {
+      testChar = p_uric.charAt(i);
+
+      if (testChar == '%')
+      {
+        if (i + 2 >= end ||!isHex(p_uric.charAt(i + 1))
+                ||!isHex(p_uric.charAt(i + 2)))
+        {
+          return false;
+        }
+        else
+        {
+          i += 2;
+
+          continue;
+        }
+      }
+
+      if (isReservedCharacter(testChar) || isUnreservedCharacter(testChar))
+      {
+        continue;
+      }
+      else
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/UnImplNode.java b/src/main/java/org/apache/xml/utils/UnImplNode.java
new file mode 100644
index 0000000..88ed983
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/UnImplNode.java
@@ -0,0 +1,1977 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: UnImplNode.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import org.apache.xml.res.XMLErrorResources;
+import org.apache.xml.res.XMLMessages;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+import org.w3c.dom.UserDataHandler;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.TypeInfo;
+/**
+ * To be subclassed by classes that wish to fake being nodes.
+ * @xsl.usage internal
+ */
+public class UnImplNode implements Node, Element, NodeList, Document
+{
+
+  /**
+   * Constructor UnImplNode
+   *
+   */
+  public UnImplNode(){}
+
+  /**
+   * Throw an error.
+   *
+   * @param msg Message Key for the error
+   */
+  public void error(String msg)
+  {
+
+    System.out.println("DOM ERROR! class: " + this.getClass().getName());
+
+    throw new RuntimeException(XMLMessages.createXMLMessage(msg, null));
+  }
+
+  /**
+   * Throw an error.
+   *
+   * @param msg Message Key for the error
+   * @param args Array of arguments to be used in the error message
+   */
+  public void error(String msg, Object[] args)
+  {
+
+    System.out.println("DOM ERROR! class: " + this.getClass().getName());
+
+    throw new RuntimeException(XMLMessages.createXMLMessage(msg, args));  //"UnImplNode error: "+msg);
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param newChild New node to append to the list of this node's children
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node appendChild(Node newChild) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"appendChild not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return false
+   */
+  public boolean hasChildNodes()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"hasChildNodes not supported!");
+
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return 0
+   */
+  public short getNodeType()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getNodeType not supported!");
+
+    return 0;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Node getParentNode()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getParentNode not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public NodeList getChildNodes()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getChildNodes not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Node getFirstChild()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getFirstChild not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Node getLastChild()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getLastChild not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Node getNextSibling()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getNextSibling not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.NodeList
+   *
+   * @return 0
+   */
+  public int getLength()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getLength not supported!");
+
+    return 0;
+  }  // getLength():int
+
+  /**
+   * Unimplemented. See org.w3c.dom.NodeList
+   *
+   * @param index index of a child of this node in its list of children
+   *
+   * @return null
+   */
+  public Node item(int index)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"item not supported!");
+
+    return null;
+  }  // item(int):Node
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Document getOwnerDocument()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getOwnerDocument not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public String getTagName()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getTagName not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public String getNodeName()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getNodeName not supported!");
+
+    return null;
+  }
+
+  /** Unimplemented. See org.w3c.dom.Node */
+  public void normalize()
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"normalize not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param name Name of the element
+   *
+   * @return null
+   */
+  public NodeList getElementsByTagName(String name)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getElementsByTagName not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param oldAttr Attribute to be removed from this node's list of attributes
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Attr removeAttributeNode(Attr oldAttr) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"removeAttributeNode not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param newAttr Attribute node to be added to this node's list of attributes
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Attr setAttributeNode(Attr newAttr) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setAttributeNode not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   *
+   * @param name Name of an attribute
+   *
+   * @return false
+   */
+  public boolean hasAttribute(String name)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"hasAttribute not supported!");
+
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   *
+   * @param name
+   * @param x
+   *
+   * @return false
+   */
+  public boolean hasAttributeNS(String name, String x)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"hasAttributeNS not supported!");
+
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   *
+   * @param name Attribute node name
+   *
+   * @return null
+   */
+  public Attr getAttributeNode(String name)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getAttributeNode not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param name Attribute node name to remove from list of attributes
+   *
+   * @throws DOMException
+   */
+  public void removeAttribute(String name) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"removeAttribute not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param name Name of attribute to set
+   * @param value Value of attribute
+   *
+   * @throws DOMException
+   */
+  public void setAttribute(String name, String value) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setAttribute not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param name Name of attribute to get
+   *
+   * @return null
+   */
+  public String getAttribute(String name)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getAttribute not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. Introduced in DOM Level 2.
+   *
+   * @return false
+   */
+  public boolean hasAttributes()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"hasAttributes not supported!");
+
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param namespaceURI Namespace URI of the element
+   * @param localName Local part of qualified name of the element
+   *
+   * @return null
+   */
+  public NodeList getElementsByTagNameNS(String namespaceURI,
+                                         String localName)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getElementsByTagNameNS not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param newAttr Attribute to set
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Attr setAttributeNodeNS(Attr newAttr) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setAttributeNodeNS not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param namespaceURI Namespace URI of attribute node to get
+   * @param localName Local part of qualified name of attribute node to get
+   *
+   * @return null
+   */
+  public Attr getAttributeNodeNS(String namespaceURI, String localName)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getAttributeNodeNS not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param namespaceURI Namespace URI of attribute node to remove
+   * @param localName Local part of qualified name of attribute node to remove
+   *
+   * @throws DOMException
+   */
+  public void removeAttributeNS(String namespaceURI, String localName)
+          throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"removeAttributeNS not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param namespaceURI Namespace URI of attribute node to set
+   * NEEDSDOC @param qualifiedName
+   * @param value value of attribute
+   *
+   * @throws DOMException
+   */
+  public void setAttributeNS(
+          String namespaceURI, String qualifiedName, String value)
+            throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setAttributeNS not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Element
+   *
+   * @param namespaceURI Namespace URI of attribute node to get
+   * @param localName Local part of qualified name of attribute node to get
+   *
+   * @return null
+   */
+  public String getAttributeNS(String namespaceURI, String localName)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getAttributeNS not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Node getPreviousSibling()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getPreviousSibling not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param deep Flag indicating whether to clone deep (clone member variables)
+   *
+   * @return null
+   */
+  public Node cloneNode(boolean deep)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"cloneNode not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public String getNodeValue() throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getNodeValue not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param nodeValue Value to set this node to
+   *
+   * @throws DOMException
+   */
+  public void setNodeValue(String nodeValue) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setNodeValue not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   *
+   * NEEDSDOC @param value
+   * @return value Node value
+   *
+   * @throws DOMException
+   */
+
+  // public String getValue ()
+  // {      
+  //  error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED); //"getValue not supported!");
+  //  return null;
+  // } 
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param value Value to set this node to
+   *
+   * @throws DOMException
+   */
+  public void setValue(String value) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setValue not supported!");
+  }
+
+  /**
+   *  Returns the name of this attribute.
+   *
+   * @return the name of this attribute.
+   */
+
+  // public String getName()
+  // {
+  //  return this.getNodeName();
+  // }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public Element getOwnerElement()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getOwnerElement not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return False
+   */
+  public boolean getSpecified()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setValue not supported!");
+
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public NamedNodeMap getAttributes()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getAttributes not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param newChild New child node to insert
+   * @param refChild Insert in front of this child
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node insertBefore(Node newChild, Node refChild) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"insertBefore not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param newChild Replace existing child with this one
+   * @param oldChild Existing child to be replaced
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node replaceChild(Node newChild, Node oldChild) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"replaceChild not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param oldChild Child to be removed
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node removeChild(Node oldChild) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"replaceChild not supported!");
+
+    return null;
+  }
+
+  /**
+   * Tests whether the DOM implementation implements a specific feature and
+   * that feature is supported by this node.
+   * @param feature The name of the feature to test. This is the same name
+   *   which can be passed to the method <code>hasFeature</code> on
+   *   <code>DOMImplementation</code>.
+   * @param version This is the version number of the feature to test. In
+   *   Level 2, version 1, this is the string "2.0". If the version is not
+   *   specified, supporting any version of the feature will cause the
+   *   method to return <code>true</code>.
+   *
+   * @return Returns <code>false</code>
+   * @since DOM Level 2
+   */
+  public boolean isSupported(String feature, String version)
+  {
+    return false;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public String getNamespaceURI()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getNamespaceURI not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public String getPrefix()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getPrefix not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @param prefix Prefix to set for this node
+   *
+   * @throws DOMException
+   */
+  public void setPrefix(String prefix) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"setPrefix not supported!");
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Node
+   *
+   * @return null
+   */
+  public String getLocalName()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);  //"getLocalName not supported!");
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @return null
+   */
+  public DocumentType getDoctype()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @return null
+   */
+  public DOMImplementation getImplementation()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @return null
+   */
+  public Element getDocumentElement()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param tagName Element tag name
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Element createElement(String tagName) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @return null
+   */
+  public DocumentFragment createDocumentFragment()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param data Data for text node
+   *
+   * @return null
+   */
+  public Text createTextNode(String data)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param data Data for comment
+   *
+   * @return null
+   */
+  public Comment createComment(String data)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param data Data for CDATA section
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public CDATASection createCDATASection(String data) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param target Target for Processing instruction
+   * @param data Data for Processing instruction
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public ProcessingInstruction createProcessingInstruction(
+          String target, String data) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param name Attribute name
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Attr createAttribute(String name) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param name Entity Reference name
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public EntityReference createEntityReference(String name)
+          throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param importedNode The node to import.
+   * @param deep         If <code>true</code>, recursively import the subtree under
+   *   the specified node; if <code>false</code>, import only the node
+   *   itself, as explained above. This has no effect on <code>Attr</code>
+   *   , <code>EntityReference</code>, and <code>Notation</code> nodes.
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Node importNode(Node importedNode, boolean deep) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param namespaceURI Namespace URI for the element
+   * @param qualifiedName Qualified name of the element
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Element createElementNS(String namespaceURI, String qualifiedName)
+          throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param namespaceURI Namespace URI of the attribute
+   * @param qualifiedName Qualified name of the attribute
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public Attr createAttributeNS(String namespaceURI, String qualifiedName)
+          throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented. See org.w3c.dom.Document
+   *
+   * @param elementId ID of the element to get
+   *
+   * @return null
+   */
+  public Element getElementById(String elementId)
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Set Node data
+   *
+   *
+   * @param data data to set for this node
+   *
+   * @throws DOMException
+   */
+  public void setData(String data) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param offset Start offset of substring to extract.
+   * @param count The length of the substring to extract.
+   *
+   * @return null
+   *
+   * @throws DOMException
+   */
+  public String substringData(int offset, int count) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param arg String data to append
+   *
+   * @throws DOMException
+   */
+  public void appendData(String arg) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param offset Start offset of substring to insert.
+   * NEEDSDOC @param arg
+   *
+   * @throws DOMException
+   */
+  public void insertData(int offset, String arg) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param offset Start offset of substring to delete.
+   * @param count The length of the substring to delete.
+   *
+   * @throws DOMException
+   */
+  public void deleteData(int offset, int count) throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param offset Start offset of substring to replace.
+   * @param count The length of the substring to replace.
+   * @param arg substring to replace with
+   *
+   * @throws DOMException
+   */
+  public void replaceData(int offset, int count, String arg)
+          throws DOMException
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * Unimplemented.
+   *
+   * @param offset Offset into text to split
+   *
+   * @return null, unimplemented
+   *
+   * @throws DOMException
+   */
+  public Text splitText(int offset) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * NEEDSDOC Method adoptNode 
+   *
+   *
+   * NEEDSDOC @param source
+   *
+   * NEEDSDOC (adoptNode) @return
+   *
+   * @throws DOMException
+   */
+  public Node adoptNode(Node source) throws DOMException
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying, as part of the XML declaration, the encoding
+   * of this document. This is <code>null</code> when unspecified.
+   * @since DOM Level 3
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public String getInputEncoding()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return null;
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying, as part of the XML declaration, the encoding
+   * of this document. This is <code>null</code> when unspecified.
+   * @since DOM Level 3
+   *
+   * NEEDSDOC @param encoding
+   */
+  public void setInputEncoding(String encoding)
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying whether errors checking is enforced or not.
+   * When set to <code>false</code>, the implementation is free to not
+   * test every possible error case normally defined on DOM operations,
+   * and not raise any <code>DOMException</code>. In case of error, the
+   * behavior is undefined. This attribute is <code>true</code> by
+   * defaults.
+   * @since DOM Level 3
+   *
+   * NEEDSDOC ($objectName$) @return
+   */
+  public boolean getStrictErrorChecking()
+  {
+
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+
+    return false;
+  }
+
+  /**
+   * <p>Based on the <a
+   * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
+   * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
+   * <p>
+   * An attribute specifying whether errors checking is enforced or not.
+   * When set to <code>false</code>, the implementation is free to not
+   * test every possible error case normally defined on DOM operations,
+   * and not raise any <code>DOMException</code>. In case of error, the
+   * behavior is undefined. This attribute is <code>true</code> by
+   * defaults.
+   * @since DOM Level 3
+   *
+   * NEEDSDOC @param strictErrorChecking
+   */
+  public void setStrictErrorChecking(boolean strictErrorChecking)
+  {
+    error(XMLErrorResources.ER_FUNCTION_NOT_SUPPORTED);
+  }
+
+    // RAMESH : Pending proper implementation of DOM Level 3    
+    public Object setUserData(String key,
+                              Object data,
+                              UserDataHandler handler) {
+        return getOwnerDocument().setUserData( key, data, handler);
+    }
+
+    /**
+     * Retrieves the object associated to a key on a this node. The object
+     * must first have been set to this node by calling
+     * <code>setUserData</code> with the same key.
+     * @param key The key the object is associated to.
+     * @return Returns the <code>DOMObject</code> associated to the given key
+     *   on this node, or <code>null</code> if there was none.
+     * @since DOM Level 3
+     */
+    public Object getUserData(String key) {
+        return getOwnerDocument().getUserData( key);
+    } 
+
+      /**
+     *  This method returns a specialized object which implements the
+     * specialized APIs of the specified feature and version. The
+     * specialized object may also be obtained by using binding-specific
+     * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
+     * @param feature The name of the feature requested (case-insensitive).
+     * @param version  This is the version number of the feature to test. If
+     *   the version is <code>null</code> or the empty string, supporting
+     *   any version of the feature will cause the method to return an
+     *   object that supports at least one version of the feature.
+     * @return  Returns an object which implements the specialized APIs of
+     *   the specified feature and version, if any, or <code>null</code> if
+     *   there is no object which implements interfaces associated with that
+     *   feature. If the <code>DOMObject</code> returned by this method
+     *   implements the <code>Node</code> interface, it must delegate to the
+     *   primary core <code>Node</code> and not return results inconsistent
+     *   with the primary core <code>Node</code> such as attributes,
+     *   childNodes, etc.
+     * @since DOM Level 3
+     */
+    public Object getFeature(String feature, String version) {
+        // we don't have any alternate node, either this node does the job
+        // or we don't have anything that does
+        return isSupported(feature, version) ? this : null;
+    }
+
+    /**
+     * Tests whether two nodes are equal.
+     * <br>This method tests for equality of nodes, not sameness (i.e.,
+     * whether the two nodes are references to the same object) which can be
+     * tested with <code>Node.isSameNode</code>. All nodes that are the same
+     * will also be equal, though the reverse may not be true.
+     * <br>Two nodes are equal if and only if the following conditions are
+     * satisfied: The two nodes are of the same type.The following string
+     * attributes are equal: <code>nodeName</code>, <code>localName</code>,
+     * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
+     * , <code>baseURI</code>. This is: they are both <code>null</code>, or
+     * they have the same length and are character for character identical.
+     * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
+     * This is: they are both <code>null</code>, or they have the same
+     * length and for each node that exists in one map there is a node that
+     * exists in the other map and is equal, although not necessarily at the
+     * same index.The <code>childNodes</code> <code>NodeLists</code> are
+     * equal. This is: they are both <code>null</code>, or they have the
+     * same length and contain equal nodes at the same index. This is true
+     * for <code>Attr</code> nodes as for any other type of node. Note that
+     * normalization can affect equality; to avoid this, nodes should be
+     * normalized before being compared.
+     * <br>For two <code>DocumentType</code> nodes to be equal, the following
+     * conditions must also be satisfied: The following string attributes
+     * are equal: <code>publicId</code>, <code>systemId</code>,
+     * <code>internalSubset</code>.The <code>entities</code>
+     * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
+     * <code>NamedNodeMaps</code> are equal.
+     * <br>On the other hand, the following do not affect equality: the
+     * <code>ownerDocument</code> attribute, the <code>specified</code>
+     * attribute for <code>Attr</code> nodes, the
+     * <code>isWhitespaceInElementContent</code> attribute for
+     * <code>Text</code> nodes, as well as any user data or event listeners
+     * registered on the nodes.
+     * @param arg The node to compare equality with.
+     * @param deep If <code>true</code>, recursively compare the subtrees; if
+     *   <code>false</code>, compare only the nodes themselves (and its
+     *   attributes, if it is an <code>Element</code>).
+     * @return If the nodes, and possibly subtrees are equal,
+     *   <code>true</code> otherwise <code>false</code>.
+     * @since DOM Level 3
+     */
+    public boolean isEqualNode(Node arg) {
+        if (arg == this) {
+            return true;
+        }
+        if (arg.getNodeType() != getNodeType()) {
+            return false;
+        }
+        // in theory nodeName can't be null but better be careful
+        // who knows what other implementations may be doing?...
+        if (getNodeName() == null) {
+            if (arg.getNodeName() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeName().equals(arg.getNodeName())) {
+            return false;
+        }
+
+        if (getLocalName() == null) {
+            if (arg.getLocalName() != null) {
+                return false;
+            }
+        }
+        else if (!getLocalName().equals(arg.getLocalName())) {
+            return false;
+        }
+
+        if (getNamespaceURI() == null) {
+            if (arg.getNamespaceURI() != null) {
+                return false;
+            }
+        }
+        else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
+            return false;
+        }
+
+        if (getPrefix() == null) {
+            if (arg.getPrefix() != null) {
+                return false;
+            }
+        }
+        else if (!getPrefix().equals(arg.getPrefix())) {
+            return false;
+        }
+
+        if (getNodeValue() == null) {
+            if (arg.getNodeValue() != null) {
+                return false;
+            }
+        }
+        else if (!getNodeValue().equals(arg.getNodeValue())) {
+            return false;
+        }
+    /*
+        if (getBaseURI() == null) {
+            if (((NodeImpl) arg).getBaseURI() != null) {
+                return false;
+            }
+        }
+        else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
+            return false;
+        }
+*/
+
+             return true;
+    }
+
+    /**
+     * DOM Level 3:
+     * Look up the namespace URI associated to the given prefix, starting from this node.
+     * Use lookupNamespaceURI(null) to lookup the default namespace
+     *
+     * @param namespaceURI
+     * @return th URI for the namespace
+     * @since DOM Level 3
+     */
+    public String lookupNamespaceURI(String specifiedPrefix) {
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE : {
+
+                String namespace = this.getNamespaceURI();
+                String prefix = this.getPrefix();
+                if (namespace !=null) {
+                    // REVISIT: is it possible that prefix is empty string?
+                    if (specifiedPrefix== null && prefix==specifiedPrefix) {
+                        // looking for default namespace
+                        return namespace;
+                    } else if (prefix != null && prefix.equals(specifiedPrefix)) {
+                        // non default namespace
+                        return namespace;
+                    }
+                }
+                if (this.hasAttributes()) {
+                    NamedNodeMap map = this.getAttributes();
+                    int length = map.getLength();
+                    for (int i=0;i<length;i++) {
+                        Node attr = map.item(i);
+                        String attrPrefix = attr.getPrefix();
+                        String value = attr.getNodeValue();
+                        namespace = attr.getNamespaceURI();
+                        if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
+                            // at this point we are dealing with DOM Level 2 nodes only
+                            if (specifiedPrefix == null &&
+                                attr.getNodeName().equals("xmlns")) {
+                                // default namespace
+                                return value;
+                            } else if (attrPrefix !=null &&
+                                       attrPrefix.equals("xmlns") &&
+                                       attr.getLocalName().equals(specifiedPrefix)) {
+                 // non default namespace
+                                return value;
+                            }
+                        }
+                    }
+                }
+		/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+		*/
+
+                return null;
+
+
+            }
+/*
+        case Node.DOCUMENT_NODE : {
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
+
+                }
+                return null;
+            }
+        default:{
+	   /*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupNamespaceURI(specifiedPrefix);
+                }
+             */
+                return null;
+            }
+
+        }
+    }
+    
+    /**
+     *  DOM Level 3:
+     *  This method checks if the specified <code>namespaceURI</code> is the
+     *  default namespace or not.
+     *  @param namespaceURI The namespace URI to look for.
+     *  @return  <code>true</code> if the specified <code>namespaceURI</code>
+     *   is the default namespace, <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isDefaultNamespace(String namespaceURI){
+       /*
+        // REVISIT: remove casts when DOM L3 becomes REC.
+        short type = this.getNodeType();
+        switch (type) {
+        case Node.ELEMENT_NODE: {
+            String namespace = this.getNamespaceURI();
+            String prefix = this.getPrefix();
+
+            // REVISIT: is it possible that prefix is empty string?
+            if (prefix == null || prefix.length() == 0) {
+                if (namespaceURI == null) {
+                    return (namespace == namespaceURI);
+                }
+                return namespaceURI.equals(namespace);
+            }
+            if (this.hasAttributes()) {
+                ElementImpl elem = (ElementImpl)this;
+                NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
+                if (attr != null) {
+                    String value = attr.getNodeValue();
+                    if (namespaceURI == null) {
+                        return (namespace == value);
+                    }
+                    return namespaceURI.equals(value);
+                }
+            }
+
+            NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+            if (ancestor != null) {
+                return ancestor.isDefaultNamespace(namespaceURI);
+            }
+            return false;
+        }
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
+            }
+
+        case Node.ENTITY_NODE :
+          case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return false;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
+                    return ownerNode.isDefaultNamespace(namespaceURI);
+
+                }
+                return false;
+            }
+        default:{  
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.isDefaultNamespace(namespaceURI);
+                }
+                return false;
+            }
+
+        }
+*/
+        return false;
+
+
+    }
+
+    /**
+     *
+     * DOM Level 3:
+     * Look up the prefix associated to the given namespace URI, starting from this node.
+     *
+     * @param namespaceURI
+     * @return the prefix for the namespace
+     */
+    public String lookupPrefix(String namespaceURI){
+
+        // REVISIT: When Namespaces 1.1 comes out this may not be true
+        // Prefix can't be bound to null namespace
+        if (namespaceURI == null) {
+            return null;
+        }
+
+        short type = this.getNodeType();
+
+        switch (type) {
+/*
+        case Node.ELEMENT_NODE: {
+
+                String namespace = this.getNamespaceURI(); // to flip out children
+                return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
+            }
+
+        case Node.DOCUMENT_NODE:{
+                return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
+            }
+*/
+        case Node.ENTITY_NODE :
+        case Node.NOTATION_NODE:
+        case Node.DOCUMENT_FRAGMENT_NODE:
+        case Node.DOCUMENT_TYPE_NODE:
+            // type is unknown
+            return null;
+        case Node.ATTRIBUTE_NODE:{
+                if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
+                    return getOwnerElement().lookupPrefix(namespaceURI);
+
+                }
+                return null;
+            }
+        default:{ 
+/*
+                NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
+                if (ancestor != null) {
+                    return ancestor.lookupPrefix(namespaceURI);
+                }
+*/
+                return null;
+            }
+         }
+    }
+
+    /**
+     * Returns whether this node is the same node as the given one.
+     * <br>This method provides a way to determine whether two
+     * <code>Node</code> references returned by the implementation reference
+     * the same object. When two <code>Node</code> references are references
+     * to the same object, even if through a proxy, the references may be
+     * used completely interchangably, such that all attributes have the
+     * same values and calling the same DOM method on either reference
+     * always has exactly the same effect.
+     * @param other The node to test against.
+     * @return Returns <code>true</code> if the nodes are the same,
+     *   <code>false</code> otherwise.
+     * @since DOM Level 3
+     */
+    public boolean isSameNode(Node other) {
+        // we do not use any wrapper so the answer is obvious
+        return this == other;
+    }
+
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public void setTextContent(String textContent)
+        throws DOMException {
+        setNodeValue(textContent);
+    }
+    
+    /**
+     * This attribute returns the text content of this node and its
+     * descendants. When it is defined to be null, setting it has no effect.
+     * When set, any possible children this node may have are removed and
+     * replaced by a single <code>Text</code> node containing the string
+     * this attribute is set to. On getting, no serialization is performed,
+     * the returned string does not contain any markup. No whitespace
+     * normalization is performed, the returned string does not contain the
+     * element content whitespaces . Similarly, on setting, no parsing is
+     * performed either, the input string is taken as pure textual content.
+     * <br>The string returned is made of the text content of this node
+     * depending on its type, as defined below:
+     * <table border='1'>
+     * <tr>
+     * <th>Node type</th>
+     * <th>Content</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
+     * DOCUMENT_FRAGMENT_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
+     * attribute value of every child node, excluding COMMENT_NODE and
+     * PROCESSING_INSTRUCTION_NODE nodes</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
+     * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * <code>nodeValue</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     * null</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     * @since DOM Level 3
+     */
+    public String getTextContent() throws DOMException {
+        return getNodeValue();  // overriden in some subclasses
+    }
+
+    /**
+     * Compares a node with this node with regard to their position in the
+     * document.
+     * @param other The node to compare against this node.
+     * @return Returns how the given node is positioned relatively to this
+     *   node.
+     * @since DOM Level 3
+     */
+    public short compareDocumentPosition(Node other) throws DOMException {
+        return 0;
+    }
+
+    /**
+     * The absolute base URI of this node or <code>null</code> if undefined.
+     * This value is computed according to . However, when the
+     * <code>Document</code> supports the feature "HTML" , the base URI is
+     * computed using first the value of the href attribute of the HTML BASE
+     * element if any, and the value of the <code>documentURI</code>
+     * attribute from the <code>Document</code> interface otherwise.
+     * <br> When the node is an <code>Element</code>, a <code>Document</code>
+     * or a a <code>ProcessingInstruction</code>, this attribute represents
+     * the properties [base URI] defined in . When the node is a
+     * <code>Notation</code>, an <code>Entity</code>, or an
+     * <code>EntityReference</code>, this attribute represents the
+     * properties [declaration base URI] in the . How will this be affected
+     * by resolution of relative namespace URIs issue?It's not.Should this
+     * only be on Document, Element, ProcessingInstruction, Entity, and
+     * Notation nodes, according to the infoset? If not, what is it equal to
+     * on other nodes? Null? An empty string? I think it should be the
+     * parent's.No.Should this be read-only and computed or and actual
+     * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
+     * teleconference 30 May 2001).If the base HTML element is not yet
+     * attached to a document, does the insert change the Document.baseURI?
+     * Yes. (F2F 26 Sep 2001)
+     * @since DOM Level 3
+     */
+    public String getBaseURI() {
+        return null;
+    }
+
+    /**
+     * DOM Level 3
+     * Renaming node
+     */
+    public Node renameNode(Node n,
+                           String namespaceURI,
+                           String name)
+                           throws DOMException{
+        return n;
+    }
+    
+    /**
+     *  DOM Level 3
+     *  Normalize document.
+     */
+    public void normalizeDocument(){   
+
+    }
+    
+    /**
+     *  The configuration used when <code>Document.normalizeDocument</code> is
+     * invoked.
+     * @since DOM Level 3
+     */
+    public DOMConfiguration getDomConfig(){
+       return null;
+    }
+
+    
+    /** DOM Level 3 feature: documentURI */
+    protected String fDocumentURI;
+
+    /**
+     * DOM Level 3
+     */
+    public void setDocumentURI(String documentURI){
+        
+        fDocumentURI= documentURI;
+    }
+
+    /**
+     * DOM Level 3
+     * The location of the document or <code>null</code> if undefined.
+     * <br>Beware that when the <code>Document</code> supports the feature
+     * "HTML" , the href attribute of the HTML BASE element takes precedence
+     * over this attribute.
+     * @since DOM Level 3
+     */
+    public String getDocumentURI(){
+        return fDocumentURI;
+    }
+
+    /** DOM Level 3 feature: Document actualEncoding */
+    protected String actualEncoding;
+
+    /**
+     * DOM Level 3
+     * An attribute specifying the actual encoding of this document. This is
+     * <code>null</code> otherwise.
+     * <br> This attribute represents the property [character encoding scheme]
+     * defined in .
+     * @since DOM Level 3
+     */
+    public String getActualEncoding() {
+        return actualEncoding;
+    }
+
+    /**
+     * DOM Level 3
+     * An attribute specifying the actual encoding of this document. This is
+     * <code>null</code> otherwise.
+     * <br> This attribute represents the property [character encoding scheme]
+     * defined in .
+     * @since DOM Level 3
+     */
+    public void setActualEncoding(String value) {
+        actualEncoding = value;
+    }
+
+    /**
+     * DOM Level 3
+     */
+    public Text replaceWholeText(String content)
+                                 throws DOMException{
+/*
+
+        if (needsSyncData()) {
+            synchronizeData();
+        }
+
+        // make sure we can make the replacement
+        if (!canModify(nextSibling)) {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
+        }
+
+        Node parent = this.getParentNode();
+        if (content == null || content.length() == 0) {
+            // remove current node
+            if (parent !=null) { // check if node in the tree
+                parent.removeChild(this);
+                return null;
+            }
+        }
+        Text currentNode = null;
+        if (isReadOnly()){
+            Text newNode = this.ownerDocument().createTextNode(content);
+            if (parent !=null) { // check if node in the tree
+                parent.insertBefore(newNode, this);
+                parent.removeChild(this);
+                currentNode = newNode;
+            } else {
+                return newNode;
+            }
+        }  else {
+            this.setData(content);
+            currentNode = this;
+        }
+        Node sibling =  currentNode.getNextSibling();
+        while ( sibling !=null) {
+            parent.removeChild(sibling);
+            sibling = currentNode.getNextSibling();
+        }
+
+        return currentNode;
+*/
+        return null; //Pending
+    }
+
+    /**
+     * DOM Level 3
+     * Returns all text of <code>Text</code> nodes logically-adjacent text
+     * nodes to this node, concatenated in document order.
+     * @since DOM Level 3
+     */
+    public String getWholeText(){
+
+/*
+        if (needsSyncData()) {
+            synchronizeData();
+        }
+        if (nextSibling == null) {
+            return data;
+        }
+        StringBuffer buffer = new StringBuffer();
+        if (data != null && data.length() != 0) {
+            buffer.append(data);
+        }
+        getWholeText(nextSibling, buffer);
+        return buffer.toString();
+*/
+        return null; // PENDING
+
+    }
+
+    /**
+     * DOM Level 3
+     * Returns whether this text node contains whitespace in element content,
+     * often abusively called "ignorable whitespace".
+     */
+    public boolean isWhitespaceInElementContent(){
+        return false;
+    }
+
+    /**
+     * NON-DOM: set the type of this attribute to be ID type.
+     *
+     * @param id
+     */
+    public void setIdAttribute(boolean id){
+        //PENDING
+    }
+
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttribute(String name, boolean makeId) {
+        //PENDING
+    }
+       
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttributeNode(Attr at, boolean makeId) {
+        //PENDING
+    }
+
+    /**
+     * DOM Level 3: register the given attribute node as an ID attribute
+     */
+    public void setIdAttributeNS(String namespaceURI, String localName,
+                                    boolean makeId) {
+        //PENDING
+    }
+    
+    /**
+     * Method getSchemaTypeInfo.
+     * @return TypeInfo
+     */
+    public TypeInfo getSchemaTypeInfo(){
+        return null; //PENDING
+    }
+
+    public boolean isId() {
+        return false; //PENDING
+    }
+  
+    private String xmlEncoding;
+    public String getXmlEncoding ( ) {
+        return xmlEncoding;
+    }
+    public void setXmlEncoding ( String xmlEncoding ) {
+        this.xmlEncoding = xmlEncoding;
+    }
+  
+    private boolean xmlStandalone;
+    public boolean getXmlStandalone() {
+        return xmlStandalone;
+    }
+
+    public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
+        this.xmlStandalone = xmlStandalone;
+    }
+
+    private String xmlVersion;
+    public String getXmlVersion() {
+        return xmlVersion;
+    }
+
+    public void setXmlVersion(String xmlVersion) throws DOMException {
+        this.xmlVersion = xmlVersion;
+    }
+
+}
diff --git a/src/main/java/org/apache/xml/utils/WrappedRuntimeException.java b/src/main/java/org/apache/xml/utils/WrappedRuntimeException.java
new file mode 100644
index 0000000..ded920c
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/WrappedRuntimeException.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WrappedRuntimeException.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * This class is for throwing important checked exceptions
+ * over non-checked methods.  It should be used with care,
+ * and in limited circumstances.
+ */
+public class WrappedRuntimeException extends RuntimeException
+{
+    static final long serialVersionUID = 7140414456714658073L;
+
+  /** Primary checked exception.
+   *  @serial          */
+  private Exception m_exception;
+
+  /**
+   * Construct a WrappedRuntimeException from a
+   * checked exception.
+   *
+   * @param e Primary checked exception
+   */
+  public WrappedRuntimeException(Exception e)
+  {
+
+    super(e.getMessage());
+
+    m_exception = e;
+  }
+
+  /**
+   * Constructor WrappedRuntimeException
+   *
+   *
+   * @param msg Exception information.
+   * @param e Primary checked exception
+   */
+  public WrappedRuntimeException(String msg, Exception e)
+  {
+
+    super(msg);
+
+    m_exception = e;
+  }
+  
+  /**
+   * Get the checked exception that this runtime exception wraps.
+   *
+   * @return The primary checked exception
+   */
+  public Exception getException()
+  {
+    return m_exception;
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/XML11Char.java b/src/main/java/org/apache/xml/utils/XML11Char.java
new file mode 100644
index 0000000..950d485
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XML11Char.java
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xml.utils;
+
+import java.util.Arrays;
+
+
+/**
+ * THIS IS A COPY OF THE XERCES-2J CLASS org.apache.xerces.utls.XMLChar
+ *  
+ * This class defines the basic properties of characters in XML 1.1. The data
+ * in this class can be used to verify that a character is a valid
+ * XML 1.1 character or if the character is a space, name start, or name
+ * character.
+ * <p>
+ * A series of convenience methods are supplied to ease the burden
+ * of the developer.  Using the character as an index into the <code>XML11CHARS</code>
+ * array and applying the appropriate mask flag (e.g.
+ * <code>MASK_VALID</code>), yields the same results as calling the
+ * convenience methods. There is one exception: check the comments
+ * for the <code>isValid</code> method for details.
+ *
+ * @version $Id: XML11Char.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+public class XML11Char {
+
+    //
+    // Constants
+    //
+
+    /** Character flags for XML 1.1. */
+    private static final byte XML11CHARS [] = new byte [1 << 16];
+
+    /** XML 1.1 Valid character mask. */
+    public static final int MASK_XML11_VALID = 0x01;
+
+    /** XML 1.1 Space character mask. */
+    public static final int MASK_XML11_SPACE = 0x02;
+
+    /** XML 1.1 Name start character mask. */
+    public static final int MASK_XML11_NAME_START = 0x04;
+
+    /** XML 1.1 Name character mask. */
+    public static final int MASK_XML11_NAME = 0x08;
+
+    /** XML 1.1 control character mask */
+    public static final int MASK_XML11_CONTROL = 0x10;
+
+    /** XML 1.1 content for external entities (valid - "special" chars - control chars) */
+    public static final int MASK_XML11_CONTENT = 0x20;
+
+    /** XML namespaces 1.1 NCNameStart */
+    public static final int MASK_XML11_NCNAME_START = 0x40;
+
+    /** XML namespaces 1.1 NCName */
+    public static final int MASK_XML11_NCNAME = 0x80;
+    
+    /** XML 1.1 content for internal entities (valid - "special" chars) */
+    public static final int MASK_XML11_CONTENT_INTERNAL = MASK_XML11_CONTROL | MASK_XML11_CONTENT; 
+
+    //
+    // Static initialization
+    //
+
+    static {
+    	
+        // Initializing the Character Flag Array
+        // Code generated by: XML11CharGenerator.
+        
+        Arrays.fill(XML11CHARS, 1, 9, (byte) 17 ); // Fill 8 of value (byte) 17
+        XML11CHARS[9] = 35;
+        XML11CHARS[10] = 3;
+        Arrays.fill(XML11CHARS, 11, 13, (byte) 17 ); // Fill 2 of value (byte) 17
+        XML11CHARS[13] = 3;
+        Arrays.fill(XML11CHARS, 14, 32, (byte) 17 ); // Fill 18 of value (byte) 17
+        XML11CHARS[32] = 35;
+        Arrays.fill(XML11CHARS, 33, 38, (byte) 33 ); // Fill 5 of value (byte) 33
+        XML11CHARS[38] = 1;
+        Arrays.fill(XML11CHARS, 39, 45, (byte) 33 ); // Fill 6 of value (byte) 33
+        Arrays.fill(XML11CHARS, 45, 47, (byte) -87 ); // Fill 2 of value (byte) -87
+        XML11CHARS[47] = 33;
+        Arrays.fill(XML11CHARS, 48, 58, (byte) -87 ); // Fill 10 of value (byte) -87
+        XML11CHARS[58] = 45;
+        XML11CHARS[59] = 33;
+        XML11CHARS[60] = 1;
+        Arrays.fill(XML11CHARS, 61, 65, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(XML11CHARS, 65, 91, (byte) -19 ); // Fill 26 of value (byte) -19
+        Arrays.fill(XML11CHARS, 91, 93, (byte) 33 ); // Fill 2 of value (byte) 33
+        XML11CHARS[93] = 1;
+        XML11CHARS[94] = 33;
+        XML11CHARS[95] = -19;
+        XML11CHARS[96] = 33;
+        Arrays.fill(XML11CHARS, 97, 123, (byte) -19 ); // Fill 26 of value (byte) -19
+        Arrays.fill(XML11CHARS, 123, 127, (byte) 33 ); // Fill 4 of value (byte) 33
+        Arrays.fill(XML11CHARS, 127, 133, (byte) 17 ); // Fill 6 of value (byte) 17
+        XML11CHARS[133] = 35;
+        Arrays.fill(XML11CHARS, 134, 160, (byte) 17 ); // Fill 26 of value (byte) 17
+        Arrays.fill(XML11CHARS, 160, 183, (byte) 33 ); // Fill 23 of value (byte) 33
+        XML11CHARS[183] = -87;
+        Arrays.fill(XML11CHARS, 184, 192, (byte) 33 ); // Fill 8 of value (byte) 33
+        Arrays.fill(XML11CHARS, 192, 215, (byte) -19 ); // Fill 23 of value (byte) -19
+        XML11CHARS[215] = 33;
+        Arrays.fill(XML11CHARS, 216, 247, (byte) -19 ); // Fill 31 of value (byte) -19
+        XML11CHARS[247] = 33;
+        Arrays.fill(XML11CHARS, 248, 768, (byte) -19 ); // Fill 520 of value (byte) -19
+        Arrays.fill(XML11CHARS, 768, 880, (byte) -87 ); // Fill 112 of value (byte) -87
+        Arrays.fill(XML11CHARS, 880, 894, (byte) -19 ); // Fill 14 of value (byte) -19
+        XML11CHARS[894] = 33;
+        Arrays.fill(XML11CHARS, 895, 8192, (byte) -19 ); // Fill 7297 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8192, 8204, (byte) 33 ); // Fill 12 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8204, 8206, (byte) -19 ); // Fill 2 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8206, 8232, (byte) 33 ); // Fill 26 of value (byte) 33
+        XML11CHARS[8232] = 35;
+        Arrays.fill(XML11CHARS, 8233, 8255, (byte) 33 ); // Fill 22 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8255, 8257, (byte) -87 ); // Fill 2 of value (byte) -87
+        Arrays.fill(XML11CHARS, 8257, 8304, (byte) 33 ); // Fill 47 of value (byte) 33
+        Arrays.fill(XML11CHARS, 8304, 8592, (byte) -19 ); // Fill 288 of value (byte) -19
+        Arrays.fill(XML11CHARS, 8592, 11264, (byte) 33 ); // Fill 2672 of value (byte) 33
+        Arrays.fill(XML11CHARS, 11264, 12272, (byte) -19 ); // Fill 1008 of value (byte) -19
+        Arrays.fill(XML11CHARS, 12272, 12289, (byte) 33 ); // Fill 17 of value (byte) 33
+        Arrays.fill(XML11CHARS, 12289, 55296, (byte) -19 ); // Fill 43007 of value (byte) -19
+        Arrays.fill(XML11CHARS, 57344, 63744, (byte) 33 ); // Fill 6400 of value (byte) 33
+        Arrays.fill(XML11CHARS, 63744, 64976, (byte) -19 ); // Fill 1232 of value (byte) -19
+        Arrays.fill(XML11CHARS, 64976, 65008, (byte) 33 ); // Fill 32 of value (byte) 33
+        Arrays.fill(XML11CHARS, 65008, 65534, (byte) -19 ); // Fill 526 of value (byte) -19
+
+    } // <clinit>()
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Returns true if the specified character is a space character
+     * as amdended in the XML 1.1 specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Space(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_SPACE) != 0);
+    } // isXML11Space(int):boolean
+
+    /**
+     * Returns true if the specified character is valid. This method
+     * also checks the surrogate character range from 0x10000 to 0x10FFFF.
+     * <p>
+     * If the program chooses to apply the mask directly to the
+     * <code>XML11CHARS</code> array, then they are responsible for checking
+     * the surrogate character range.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Valid(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_VALID) != 0) 
+                || (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11Valid(int):boolean
+
+    /**
+     * Returns true if the specified character is invalid.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Invalid(int c) {
+        return !isXML11Valid(c);
+    } // isXML11Invalid(int):boolean
+
+    /**
+     * Returns true if the specified character is valid and permitted outside
+     * of a character reference.  
+     * That is, this method will return false for the same set as
+     * isXML11Valid, except it also reports false for "control characters".
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11ValidLiteral(int c) {
+        return ((c < 0x10000 && ((XML11CHARS[c] & MASK_XML11_VALID) != 0 && (XML11CHARS[c] & MASK_XML11_CONTROL) == 0))
+            || (0x10000 <= c && c <= 0x10FFFF)); 
+    } // isXML11ValidLiteral(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered 
+     * content in an external parsed entity.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Content(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_CONTENT) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11Content(int):boolean
+    
+    /**
+     * Returns true if the specified character can be considered 
+     * content in an internal parsed entity.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11InternalEntityContent(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_CONTENT_INTERNAL) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isXML11InternalEntityContent(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name start
+     * character as defined by production [4] in the XML 1.1
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NameStart(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NAME_START) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name
+     * character as defined by production [4a] in the XML 1.1
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11Name(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NAME) != 0) 
+            || (c >= 0x10000 && c < 0xF0000);
+    } // isXML11Name(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName start
+     * character as defined by production [4] in Namespaces in XML
+     * 1.1 recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NCNameStart(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NCNAME_START) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NCNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName
+     * character as defined by production [5] in Namespaces in XML
+     * 1.1 recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NCName(int c) {
+        return (c < 0x10000 && (XML11CHARS[c] & MASK_XML11_NCNAME) != 0)
+            || (0x10000 <= c && c < 0xF0000);
+    } // isXML11NCName(int):boolean
+    
+    /**
+     * Returns whether the given character is a valid 
+     * high surrogate for a name character. This includes
+     * all high surrogates for characters [0x10000-0xEFFFF].
+     * In other words everything excluding planes 15 and 16.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isXML11NameHighSurrogate(int c) {
+        return (0xD800 <= c && c <= 0xDB7F);
+    }
+
+    /*
+     * [5] Name ::= NameStartChar NameChar*
+     */
+    /**
+     * Check to see if a string is a valid Name according to [5]
+     * in the XML 1.1 Recommendation
+     *
+     * @param name string to check
+     * @return true if name is a valid Name
+     */
+    public static boolean isXML11ValidName(String name) {
+        int length = name.length();
+        if (length == 0)
+            return false;
+        int i = 1;
+        char ch = name.charAt(0);
+        if( !isXML11NameStart(ch) ) {
+            if ( length > 1 && isXML11NameHighSurrogate(ch) ) {
+                char ch2 = name.charAt(1);
+                if ( !XMLChar.isLowSurrogate(ch2) || 
+                     !isXML11NameStart(XMLChar.supplemental(ch, ch2)) ) {
+                    return false;
+                }
+                i = 2;
+            }
+            else {
+                return false;
+            }
+        }
+        while (i < length) {
+            ch = name.charAt(i);
+            if ( !isXML11Name(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = name.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+            ++i;
+        }
+        return true;
+    } // isXML11ValidName(String):boolean
+    
+
+    /*
+     * from the namespace 1.1 rec
+     * [4] NCName ::= NCNameStartChar NCNameChar*
+     */
+    /**
+     * Check to see if a string is a valid NCName according to [4]
+     * from the XML Namespaces 1.1 Recommendation
+     *
+     * @param ncName string to check
+     * @return true if name is a valid NCName
+     */
+    public static boolean isXML11ValidNCName(String ncName) {
+        int length = ncName.length();
+        if (length == 0)
+            return false;
+        int i = 1;
+        char ch = ncName.charAt(0);
+        if( !isXML11NCNameStart(ch) ) {
+            if ( length > 1 && isXML11NameHighSurrogate(ch) ) {
+                char ch2 = ncName.charAt(1);
+                if ( !XMLChar.isLowSurrogate(ch2) || 
+                     !isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) {
+                    return false;
+                }
+                i = 2;
+            }
+            else {
+                return false;
+            }
+        }
+        while (i < length) {
+            ch = ncName.charAt(i);
+            if ( !isXML11NCName(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = ncName.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11NCName(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+            ++i;
+        }
+        return true;
+    } // isXML11ValidNCName(String):boolean
+
+    /*
+     * [7] Nmtoken ::= (NameChar)+
+     */
+    /**
+     * Check to see if a string is a valid Nmtoken according to [7]
+     * in the XML 1.1 Recommendation
+     *
+     * @param nmtoken string to check
+     * @return true if nmtoken is a valid Nmtoken 
+     */
+    public static boolean isXML11ValidNmtoken(String nmtoken) {
+        int length = nmtoken.length();
+        if (length == 0)
+            return false;
+        for (int i = 0; i < length; ++i ) {
+            char ch = nmtoken.charAt(i);
+            if( !isXML11Name(ch) ) {
+                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
+                    char ch2 = nmtoken.charAt(i);
+                    if ( !XMLChar.isLowSurrogate(ch2) || 
+                         !isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
+                        return false;
+                    }
+                }
+                else {
+                    return false;
+                }
+            }
+        }
+        return true;
+    } // isXML11ValidName(String):boolean
+    
+    /**
+      * Simple check to determine if qname is legal. If it returns false
+      * then <param>str</param> is illegal; if it returns true then 
+      * <param>str</param> is legal.
+      */
+     public static boolean isXML11ValidQName(String str) {
+
+        final int colon = str.indexOf(':');
+
+        if (colon == 0 || colon == str.length() - 1) {
+            return false;
+        }
+       
+        if (colon > 0) {
+            final String prefix = str.substring(0,colon);
+            final String localPart = str.substring(colon+1);
+            return isXML11ValidNCName(prefix) && isXML11ValidNCName(localPart);
+        }
+        else {
+            return isXML11ValidNCName(str);
+        }
+     }
+
+} // class XML11Char
+
diff --git a/src/main/java/org/apache/xml/utils/XMLChar.java b/src/main/java/org/apache/xml/utils/XMLChar.java
new file mode 100644
index 0000000..779a4c0
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLChar.java
@@ -0,0 +1,668 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.utils;
+
+/**
+ * This class defines the basic XML character properties. The data
+ * in this class can be used to verify that a character is a valid
+ * XML character or if the character is a space, name start, or name
+ * character.
+ * <p>
+ * A series of convenience methods are supplied to ease the burden
+ * of the developer. Because inlining the checks can improve per
+ * character performance, the tables of character properties are
+ * public. Using the character as an index into the <code>CHARS</code>
+ * array and applying the appropriate mask flag (e.g.
+ * <code>MASK_VALID</code>), yields the same results as calling the
+ * convenience methods. There is one exception: check the comments
+ * for the <code>isValid</code> method for details.
+ *
+ * @author Glenn Marcy, IBM
+ * @author Andy Clark, IBM
+ * @author Eric Ye, IBM
+ * @author Arnaud  Le Hors, IBM
+ * @author Rahul Srivastava, Sun Microsystems Inc.
+ *
+ * @version $Id: XMLChar.java,v 1.7 2002/01/29 01:15:18 lehors Exp $
+ */
+public class XMLChar {
+
+    //
+    // Constants
+    //
+
+    /** Character flags. */
+    private static final byte[] CHARS = new byte[1 << 16];
+
+    /** Valid character mask. */
+    public static final int MASK_VALID = 0x01;
+
+    /** Space character mask. */
+    public static final int MASK_SPACE = 0x02;
+
+    /** Name start character mask. */
+    public static final int MASK_NAME_START = 0x04;
+
+    /** Name character mask. */
+    public static final int MASK_NAME = 0x08;
+
+    /** Pubid character mask. */
+    public static final int MASK_PUBID = 0x10;
+    
+    /** 
+     * Content character mask. Special characters are those that can
+     * be considered the start of markup, such as '&lt;' and '&amp;'. 
+     * The various newline characters are considered special as well.
+     * All other valid XML characters can be considered content.
+     * <p>
+     * This is an optimization for the inner loop of character scanning.
+     */
+    public static final int MASK_CONTENT = 0x20;
+
+    /** NCName start character mask. */
+    public static final int MASK_NCNAME_START = 0x40;
+
+    /** NCName character mask. */
+    public static final int MASK_NCNAME = 0x80;
+
+    //
+    // Static initialization
+    //
+
+    static {
+        
+        //
+        // [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] |
+        //              [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+        //
+
+        int charRange[] = { 
+            0x0009, 0x000A, 0x000D, 0x000D, 0x0020, 0xD7FF, 0xE000, 0xFFFD,
+        };
+
+        //
+        // [3] S ::= (#x20 | #x9 | #xD | #xA)+
+        //
+
+        int spaceChar[] = { 
+            0x0020, 0x0009, 0x000D, 0x000A,
+        };
+
+        //
+        // [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+        //                  CombiningChar | Extender
+        //
+
+        int nameChar[] = { 
+            0x002D, 0x002E, // '-' and '.'
+        };
+
+        //
+        // [5] Name ::= (Letter | '_' | ':') (NameChar)*
+        //
+
+        int nameStartChar[] = { 
+            0x003A, 0x005F, // ':' and '_'
+        };
+
+        //
+        // [13] PubidChar ::= #x20 | 0xD | 0xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+        //
+
+        int pubidChar[] = {
+            0x000A, 0x000D, 0x0020, 0x0021, 0x0023, 0x0024, 0x0025, 0x003D,
+            0x005F
+        };
+
+        int pubidRange[] = {
+            0x0027, 0x003B, 0x003F, 0x005A, 0x0061, 0x007A
+        };
+
+        //
+        // [84] Letter ::= BaseChar | Ideographic
+        //
+
+        int letterRange[] = {
+            // BaseChar
+            0x0041, 0x005A, 0x0061, 0x007A, 0x00C0, 0x00D6, 0x00D8, 0x00F6,
+            0x00F8, 0x0131, 0x0134, 0x013E, 0x0141, 0x0148, 0x014A, 0x017E,
+            0x0180, 0x01C3, 0x01CD, 0x01F0, 0x01F4, 0x01F5, 0x01FA, 0x0217,
+            0x0250, 0x02A8, 0x02BB, 0x02C1, 0x0388, 0x038A, 0x038E, 0x03A1,
+            0x03A3, 0x03CE, 0x03D0, 0x03D6, 0x03E2, 0x03F3, 0x0401, 0x040C,
+            0x040E, 0x044F, 0x0451, 0x045C, 0x045E, 0x0481, 0x0490, 0x04C4,
+            0x04C7, 0x04C8, 0x04CB, 0x04CC, 0x04D0, 0x04EB, 0x04EE, 0x04F5,
+            0x04F8, 0x04F9, 0x0531, 0x0556, 0x0561, 0x0586, 0x05D0, 0x05EA,
+            0x05F0, 0x05F2, 0x0621, 0x063A, 0x0641, 0x064A, 0x0671, 0x06B7,
+            0x06BA, 0x06BE, 0x06C0, 0x06CE, 0x06D0, 0x06D3, 0x06E5, 0x06E6,
+            0x0905, 0x0939, 0x0958, 0x0961, 0x0985, 0x098C, 0x098F, 0x0990,
+            0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B6, 0x09B9, 0x09DC, 0x09DD,
+            0x09DF, 0x09E1, 0x09F0, 0x09F1, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10,
+            0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36,
+            0x0A38, 0x0A39, 0x0A59, 0x0A5C, 0x0A72, 0x0A74, 0x0A85, 0x0A8B,
+            0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3,
+            0x0AB5, 0x0AB9, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28,
+            0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B5C, 0x0B5D,
+            0x0B5F, 0x0B61, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95,
+            0x0B99, 0x0B9A, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA,
+            0x0BAE, 0x0BB5, 0x0BB7, 0x0BB9, 0x0C05, 0x0C0C, 0x0C0E, 0x0C10,
+            0x0C12, 0x0C28, 0x0C2A, 0x0C33, 0x0C35, 0x0C39, 0x0C60, 0x0C61,
+            0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3,
+            0x0CB5, 0x0CB9, 0x0CE0, 0x0CE1, 0x0D05, 0x0D0C, 0x0D0E, 0x0D10,
+            0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D60, 0x0D61, 0x0E01, 0x0E2E,
+            0x0E32, 0x0E33, 0x0E40, 0x0E45, 0x0E81, 0x0E82, 0x0E87, 0x0E88,
+            0x0E94, 0x0E97, 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EAA, 0x0EAB,
+            0x0EAD, 0x0EAE, 0x0EB2, 0x0EB3, 0x0EC0, 0x0EC4, 0x0F40, 0x0F47,
+            0x0F49, 0x0F69, 0x10A0, 0x10C5, 0x10D0, 0x10F6, 0x1102, 0x1103,
+            0x1105, 0x1107, 0x110B, 0x110C, 0x110E, 0x1112, 0x1154, 0x1155,
+            0x115F, 0x1161, 0x116D, 0x116E, 0x1172, 0x1173, 0x11AE, 0x11AF,
+            0x11B7, 0x11B8, 0x11BC, 0x11C2, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9,
+            0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D,
+            0x1F50, 0x1F57, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC,
+            0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, 0x1FD6, 0x1FDB,
+            0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, 0x212A, 0x212B,
+            0x2180, 0x2182, 0x3041, 0x3094, 0x30A1, 0x30FA, 0x3105, 0x312C,
+            0xAC00, 0xD7A3,
+            // Ideographic
+            0x3021, 0x3029, 0x4E00, 0x9FA5,
+        };
+        int letterChar[] = {
+            // BaseChar
+            0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5,
+            0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D, 0x0B9C,
+            0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5, 0x0EA7, 0x0EB0,
+            0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E, 0x1140, 0x114C, 0x114E,
+            0x1150, 0x1159, 0x1163, 0x1165, 0x1167, 0x1169, 0x1175, 0x119E,
+            0x11A8, 0x11AB, 0x11BA, 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B,
+            0x1F5D, 0x1FBE, 0x2126, 0x212E,
+            // Ideographic
+            0x3007,
+        };
+
+        //
+        // [87] CombiningChar ::= ...
+        //
+
+        int combiningCharRange[] = {
+            0x0300, 0x0345, 0x0360, 0x0361, 0x0483, 0x0486, 0x0591, 0x05A1,
+            0x05A3, 0x05B9, 0x05BB, 0x05BD, 0x05C1, 0x05C2, 0x064B, 0x0652,
+            0x06D6, 0x06DC, 0x06DD, 0x06DF, 0x06E0, 0x06E4, 0x06E7, 0x06E8,
+            0x06EA, 0x06ED, 0x0901, 0x0903, 0x093E, 0x094C, 0x0951, 0x0954,
+            0x0962, 0x0963, 0x0981, 0x0983, 0x09C0, 0x09C4, 0x09C7, 0x09C8,
+            0x09CB, 0x09CD, 0x09E2, 0x09E3, 0x0A40, 0x0A42, 0x0A47, 0x0A48,
+            0x0A4B, 0x0A4D, 0x0A70, 0x0A71, 0x0A81, 0x0A83, 0x0ABE, 0x0AC5,
+            0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0B01, 0x0B03, 0x0B3E, 0x0B43,
+            0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B56, 0x0B57, 0x0B82, 0x0B83,
+            0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0C01, 0x0C03,
+            0x0C3E, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56,
+            0x0C82, 0x0C83, 0x0CBE, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD,
+            0x0CD5, 0x0CD6, 0x0D02, 0x0D03, 0x0D3E, 0x0D43, 0x0D46, 0x0D48,
+            0x0D4A, 0x0D4D, 0x0E34, 0x0E3A, 0x0E47, 0x0E4E, 0x0EB4, 0x0EB9,
+            0x0EBB, 0x0EBC, 0x0EC8, 0x0ECD, 0x0F18, 0x0F19, 0x0F71, 0x0F84,
+            0x0F86, 0x0F8B, 0x0F90, 0x0F95, 0x0F99, 0x0FAD, 0x0FB1, 0x0FB7,
+            0x20D0, 0x20DC, 0x302A, 0x302F,
+        };
+
+        int combiningCharChar[] = {
+            0x05BF, 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF,
+            0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C, 0x0BD7,
+            0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39, 0x0F3E, 0x0F3F,
+            0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A,
+        };
+
+        //
+        // [88] Digit ::= ...
+        //
+
+        int digitRange[] = {
+            0x0030, 0x0039, 0x0660, 0x0669, 0x06F0, 0x06F9, 0x0966, 0x096F,
+            0x09E6, 0x09EF, 0x0A66, 0x0A6F, 0x0AE6, 0x0AEF, 0x0B66, 0x0B6F,
+            0x0BE7, 0x0BEF, 0x0C66, 0x0C6F, 0x0CE6, 0x0CEF, 0x0D66, 0x0D6F,
+            0x0E50, 0x0E59, 0x0ED0, 0x0ED9, 0x0F20, 0x0F29,
+        };
+
+        //
+        // [89] Extender ::= ...
+        //
+
+        int extenderRange[] = {
+            0x3031, 0x3035, 0x309D, 0x309E, 0x30FC, 0x30FE,
+        };
+
+        int extenderChar[] = {
+            0x00B7, 0x02D0, 0x02D1, 0x0387, 0x0640, 0x0E46, 0x0EC6, 0x3005,
+        };
+
+        //
+        // SpecialChar ::= '<', '&', '\n', '\r', ']'
+        //
+
+        int specialChar[] = {
+            '<', '&', '\n', '\r', ']',
+        };
+
+        //
+        // Initialize
+        //
+
+        // set valid characters
+        for (int i = 0; i < charRange.length; i += 2) {
+            for (int j = charRange[i]; j <= charRange[i + 1]; j++) {
+                CHARS[j] |= MASK_VALID | MASK_CONTENT;
+            }
+        }
+
+        // remove special characters
+        for (int i = 0; i < specialChar.length; i++) {
+            CHARS[specialChar[i]] = (byte)(CHARS[specialChar[i]] & ~MASK_CONTENT);
+        }
+
+        // set space characters
+        for (int i = 0; i < spaceChar.length; i++) {
+            CHARS[spaceChar[i]] |= MASK_SPACE;
+        }
+
+        // set name start characters
+        for (int i = 0; i < nameStartChar.length; i++) {
+            CHARS[nameStartChar[i]] |= MASK_NAME_START | MASK_NAME | 
+                                       MASK_NCNAME_START | MASK_NCNAME;
+        }
+        for (int i = 0; i < letterRange.length; i += 2) {
+            for (int j = letterRange[i]; j <= letterRange[i + 1]; j++) {
+                CHARS[j] |= MASK_NAME_START | MASK_NAME |
+                            MASK_NCNAME_START | MASK_NCNAME;
+            }
+        }
+        for (int i = 0; i < letterChar.length; i++) {
+            CHARS[letterChar[i]] |= MASK_NAME_START | MASK_NAME |
+                                    MASK_NCNAME_START | MASK_NCNAME;
+        }
+
+        // set name characters
+        for (int i = 0; i < nameChar.length; i++) {
+            CHARS[nameChar[i]] |= MASK_NAME | MASK_NCNAME;
+        }
+        for (int i = 0; i < digitRange.length; i += 2) {
+            for (int j = digitRange[i]; j <= digitRange[i + 1]; j++) {
+                CHARS[j] |= MASK_NAME | MASK_NCNAME;
+            }
+        }
+        for (int i = 0; i < combiningCharRange.length; i += 2) {
+            for (int j = combiningCharRange[i]; j <= combiningCharRange[i + 1]; j++) {
+                CHARS[j] |= MASK_NAME | MASK_NCNAME;
+            }
+        }
+        for (int i = 0; i < combiningCharChar.length; i++) {
+            CHARS[combiningCharChar[i]] |= MASK_NAME | MASK_NCNAME;
+        }
+        for (int i = 0; i < extenderRange.length; i += 2) {
+            for (int j = extenderRange[i]; j <= extenderRange[i + 1]; j++) {
+                CHARS[j] |= MASK_NAME | MASK_NCNAME;
+            }
+        }
+        for (int i = 0; i < extenderChar.length; i++) {
+            CHARS[extenderChar[i]] |= MASK_NAME | MASK_NCNAME;
+        }
+
+        // remove ':' from allowable MASK_NCNAME_START and MASK_NCNAME chars
+        CHARS[':'] &= ~(MASK_NCNAME_START | MASK_NCNAME);
+
+        // set Pubid characters
+        for (int i = 0; i < pubidChar.length; i++) {
+            CHARS[pubidChar[i]] |= MASK_PUBID;
+        }
+        for (int i = 0; i < pubidRange.length; i += 2) {
+            for (int j = pubidRange[i]; j <= pubidRange[i + 1]; j++) {
+                CHARS[j] |= MASK_PUBID;
+            }
+        }
+
+    } // <clinit>()
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Returns true if the specified character is a supplemental character.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isSupplemental(int c) {
+        return (c >= 0x10000 && c <= 0x10FFFF);
+    }
+
+    /**
+     * Returns true the supplemental character corresponding to the given
+     * surrogates.
+     *
+     * @param h The high surrogate.
+     * @param l The low surrogate.
+     */
+    public static int supplemental(char h, char l) {
+        return (h - 0xD800) * 0x400 + (l - 0xDC00) + 0x10000;
+    }
+
+    /**
+     * Returns the high surrogate of a supplemental character
+     *
+     * @param c The supplemental character to "split".
+     */
+    public static char highSurrogate(int c) {
+        return (char) (((c - 0x00010000) >> 10) + 0xD800);
+    }
+
+    /**
+     * Returns the low surrogate of a supplemental character
+     *
+     * @param c The supplemental character to "split".
+     */
+    public static char lowSurrogate(int c) {
+        return (char) (((c - 0x00010000) & 0x3FF) + 0xDC00);
+    }
+
+    /**
+     * Returns whether the given character is a high surrogate
+     *
+     * @param c The character to check.
+     */
+    public static boolean isHighSurrogate(int c) {
+        return (0xD800 <= c && c <= 0xDBFF);
+    }
+
+    /**
+     * Returns whether the given character is a low surrogate
+     *
+     * @param c The character to check.
+     */
+    public static boolean isLowSurrogate(int c) {
+        return (0xDC00 <= c && c <= 0xDFFF);
+    }
+
+
+    /**
+     * Returns true if the specified character is valid. This method
+     * also checks the surrogate character range from 0x10000 to 0x10FFFF.
+     * <p>
+     * If the program chooses to apply the mask directly to the
+     * <code>CHARS</code> array, then they are responsible for checking
+     * the surrogate character range.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isValid(int c) {
+        return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isValid(int):boolean
+
+    /**
+     * Returns true if the specified character is invalid.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isInvalid(int c) {
+        return !isValid(c);
+    } // isInvalid(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered content.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isContent(int c) {
+        return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0) ||
+               (0x10000 <= c && c <= 0x10FFFF);
+    } // isContent(int):boolean
+
+    /**
+     * Returns true if the specified character can be considered markup.
+     * Markup characters include '&lt;', '&amp;', and '%'.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isMarkup(int c) {
+        return c == '<' || c == '&' || c == '%';
+    } // isMarkup(int):boolean
+
+    /**
+     * Returns true if the specified character is a space character
+     * as defined by production [3] in the XML 1.0 specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isSpace(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_SPACE) != 0;
+    } // isSpace(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name start
+     * character as defined by production [5] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNameStart(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NAME_START) != 0;
+    } // isNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid name
+     * character as defined by production [4] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isName(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NAME) != 0;
+    } // isName(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName start
+     * character as defined by production [4] in Namespaces in XML
+     * recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNCNameStart(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NCNAME_START) != 0;
+    } // isNCNameStart(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid NCName
+     * character as defined by production [5] in Namespaces in XML
+     * recommendation.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isNCName(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_NCNAME) != 0;
+    } // isNCName(int):boolean
+
+    /**
+     * Returns true if the specified character is a valid Pubid
+     * character as defined by production [13] in the XML 1.0
+     * specification.
+     *
+     * @param c The character to check.
+     */
+    public static boolean isPubid(int c) {
+        return c < 0x10000 && (CHARS[c] & MASK_PUBID) != 0;
+    } // isPubid(int):boolean
+
+    /*
+     * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+     */
+    /**
+     * Check to see if a string is a valid Name according to [5]
+     * in the XML 1.0 Recommendation
+     *
+     * @param name string to check
+     * @return true if name is a valid Name
+     */
+    public static boolean isValidName(String name) {
+        if (name.length() == 0)
+            return false;
+        char ch = name.charAt(0);
+        if( isNameStart(ch) == false)
+           return false;
+        for (int i = 1; i < name.length(); i++ ) {
+           ch = name.charAt(i);
+           if( isName( ch ) == false ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidName(String):boolean
+    
+
+    /*
+     * from the namespace rec
+     * [4] NCName ::= (Letter | '_') (NCNameChar)*
+     */
+    /**
+     * Check to see if a string is a valid NCName according to [4]
+     * from the XML Namespaces 1.0 Recommendation
+     *
+     * @param ncName string to check
+     * @return true if name is a valid NCName
+     */
+    public static boolean isValidNCName(String ncName) {
+        if (ncName.length() == 0)
+            return false;
+        char ch = ncName.charAt(0);
+        if( isNCNameStart(ch) == false)
+           return false;
+        for (int i = 1; i < ncName.length(); i++ ) {
+           ch = ncName.charAt(i);
+           if( isNCName( ch ) == false ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidNCName(String):boolean
+
+    /*
+     * [7] Nmtoken ::= (NameChar)+
+     */
+    /**
+     * Check to see if a string is a valid Nmtoken according to [7]
+     * in the XML 1.0 Recommendation
+     *
+     * @param nmtoken string to check
+     * @return true if nmtoken is a valid Nmtoken 
+     */
+    public static boolean isValidNmtoken(String nmtoken) {
+        if (nmtoken.length() == 0)
+            return false;
+        for (int i = 0; i < nmtoken.length(); i++ ) {
+           char ch = nmtoken.charAt(i);
+           if(  ! isName( ch ) ){
+              return false;
+           }
+        }
+        return true;
+    } // isValidName(String):boolean
+
+
+
+
+
+    // encodings
+
+    /**
+     * Returns true if the encoding name is a valid IANA encoding.
+     * This method does not verify that there is a decoder available
+     * for this encoding, only that the characters are valid for an
+     * IANA encoding name.
+     *
+     * @param ianaEncoding The IANA encoding name.
+     */
+    public static boolean isValidIANAEncoding(String ianaEncoding) {
+        if (ianaEncoding != null) {
+            int length = ianaEncoding.length();
+            if (length > 0) {
+                char c = ianaEncoding.charAt(0);
+                if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+                    for (int i = 1; i < length; i++) {
+                        c = ianaEncoding.charAt(i);
+                        if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+                            (c < '0' || c > '9') && c != '.' && c != '_' &&
+                            c != '-') {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    } // isValidIANAEncoding(String):boolean
+
+    /**
+     * Returns true if the encoding name is a valid Java encoding.
+     * This method does not verify that there is a decoder available
+     * for this encoding, only that the characters are valid for an
+     * Java encoding name.
+     *
+     * @param javaEncoding The Java encoding name.
+     */
+    public static boolean isValidJavaEncoding(String javaEncoding) {
+        if (javaEncoding != null) {
+            int length = javaEncoding.length();
+            if (length > 0) {
+                for (int i = 1; i < length; i++) {
+                    char c = javaEncoding.charAt(i);
+                    if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+                        (c < '0' || c > '9') && c != '.' && c != '_' &&
+                        c != '-') {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    } // isValidIANAEncoding(String):boolean
+    
+   /**
+     * Simple check to determine if qname is legal. If it returns false
+     * then <param>str</param> is illegal; if it returns true then 
+     * <param>str</param> is legal.
+     */
+    public static boolean isValidQName(String str) {
+       
+       final int colon = str.indexOf(':');
+       
+       if (colon == 0 || colon == str.length() - 1) {
+           return false;
+       }       
+       
+       if (colon > 0) {
+           final String prefix = str.substring(0,colon);
+           final String localPart = str.substring(colon+1);
+           return isValidNCName(prefix) && isValidNCName(localPart);
+       }
+       else {
+           return isValidNCName(str);
+       }       
+    }      
+
+} // class XMLChar
diff --git a/src/main/java/org/apache/xml/utils/XMLCharacterRecognizer.java b/src/main/java/org/apache/xml/utils/XMLCharacterRecognizer.java
new file mode 100644
index 0000000..9d879cb
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLCharacterRecognizer.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLCharacterRecognizer.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * Class used to verify whether the specified <var>ch</var> 
+ * conforms to the XML 1.0 definition of whitespace. 
+ * @xsl.usage internal
+ */
+public class XMLCharacterRecognizer
+{
+
+  /**
+   * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition
+   * of whitespace.  Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
+   * the definition of <CODE>S</CODE></A> for details.
+   * @param ch Character to check as XML whitespace.
+   * @return =true if <var>ch</var> is XML whitespace; otherwise =false.
+   */
+  public static boolean isWhiteSpace(char ch)
+  {
+    return (ch == 0x20) || (ch == 0x09) || (ch == 0xD) || (ch == 0xA);
+  }
+
+  /**
+   * Tell if the string is whitespace.
+   *
+   * @param ch Character array to check as XML whitespace.
+   * @param start Start index of characters in the array
+   * @param length Number of characters in the array 
+   * @return True if the characters in the array are 
+   * XML whitespace; otherwise, false.
+   */
+  public static boolean isWhiteSpace(char ch[], int start, int length)
+  {
+
+    int end = start + length;
+
+    for (int s = start; s < end; s++)
+    {
+      if (!isWhiteSpace(ch[s]))
+        return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * Tell if the string is whitespace.
+   *
+   * @param buf StringBuffer to check as XML whitespace.
+   * @return True if characters in buffer are XML whitespace, false otherwise
+   */
+  public static boolean isWhiteSpace(StringBuffer buf)
+  {
+
+    int n = buf.length();
+
+    for (int i = 0; i < n; i++)
+    {
+      if (!isWhiteSpace(buf.charAt(i)))
+        return false;
+    }
+
+    return true;
+  }
+  
+  /**
+   * Tell if the string is whitespace.
+   *
+   * @param s String to check as XML whitespace.
+   * @return True if characters in buffer are XML whitespace, false otherwise
+   */
+  public static boolean isWhiteSpace(String s)
+  {
+
+    if(null != s)
+    {
+      int n = s.length();
+  
+      for (int i = 0; i < n; i++)
+      {
+        if (!isWhiteSpace(s.charAt(i)))
+          return false;
+      }
+    }
+
+    return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xml/utils/XMLReaderManager.java b/src/main/java/org/apache/xml/utils/XMLReaderManager.java
new file mode 100644
index 0000000..8cc2d33
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLReaderManager.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLReaderManager.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+import java.util.Hashtable;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * Creates XMLReader objects and caches them for re-use.
+ * This class follows the singleton pattern.
+ */
+public class XMLReaderManager {
+
+    private static final String NAMESPACES_FEATURE =
+                             "http://xml.org/sax/features/namespaces";
+    private static final String NAMESPACE_PREFIXES_FEATURE =
+                             "http://xml.org/sax/features/namespace-prefixes";
+    private static final XMLReaderManager m_singletonManager =
+                                                     new XMLReaderManager();
+
+    /**
+     * Parser factory to be used to construct XMLReader objects
+     */
+    private static SAXParserFactory m_parserFactory;
+
+    /**
+     * Cache of XMLReader objects
+     */
+    private ThreadLocal m_readers;
+
+    /**
+     * Keeps track of whether an XMLReader object is in use.
+     */
+    private Hashtable m_inUse;
+
+    /**
+     * Hidden constructor
+     */
+    private XMLReaderManager() {
+    }
+
+    /**
+     * Retrieves the singleton reader manager
+     */
+    public static XMLReaderManager getInstance() {
+        return m_singletonManager;
+    }
+
+    /**
+     * Retrieves a cached XMLReader for this thread, or creates a new
+     * XMLReader, if the existing reader is in use.  When the caller no
+     * longer needs the reader, it must release it with a call to
+     * {@link #releaseXMLReader}.
+     */
+    public synchronized XMLReader getXMLReader() throws SAXException {
+        XMLReader reader;
+        boolean readerInUse;
+
+        if (m_readers == null) {
+            // When the m_readers.get() method is called for the first time
+            // on a thread, a new XMLReader will automatically be created.
+            m_readers = new ThreadLocal();
+        }
+
+        if (m_inUse == null) {
+            m_inUse = new Hashtable();
+        }
+
+        // If the cached reader for this thread is in use, construct a new
+        // one; otherwise, return the cached reader.
+        reader = (XMLReader) m_readers.get();
+        boolean threadHasReader = (reader != null);
+        if (!threadHasReader || m_inUse.get(reader) == Boolean.TRUE) {
+            try {
+                try {
+                    // According to JAXP 1.2 specification, if a SAXSource
+                    // is created using a SAX InputSource the Transformer or
+                    // TransformerFactory creates a reader via the
+                    // XMLReaderFactory if setXMLReader is not used
+                    reader = XMLReaderFactory.createXMLReader();
+                } catch (Exception e) {
+                   try {
+                        // If unable to create an instance, let's try to use
+                        // the XMLReader from JAXP
+                        if (m_parserFactory == null) {
+                            m_parserFactory = SAXParserFactory.newInstance();
+                            m_parserFactory.setNamespaceAware(true);
+                        }
+
+                        reader = m_parserFactory.newSAXParser().getXMLReader();
+                   } catch (ParserConfigurationException pce) {
+                       throw pce;   // pass along pce
+                   }
+                }
+                try {
+                    reader.setFeature(NAMESPACES_FEATURE, true);
+                    reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
+                } catch (SAXException se) {
+                    // Try to carry on if we've got a parser that
+                    // doesn't know about namespace prefixes.
+                }
+            } catch (ParserConfigurationException ex) {
+                throw new SAXException(ex);
+            } catch (FactoryConfigurationError ex1) {
+                throw new SAXException(ex1.toString());
+            } catch (NoSuchMethodError ex2) {
+            } catch (AbstractMethodError ame) {
+            }
+
+            // Cache the XMLReader if this is the first time we've created
+            // a reader for this thread.
+            if (!threadHasReader) {
+                m_readers.set(reader);
+                m_inUse.put(reader, Boolean.TRUE);
+            }
+        } else {
+            m_inUse.put(reader, Boolean.TRUE);
+        }
+
+        return reader;
+    }
+
+    /**
+     * Mark the cached XMLReader as available.  If the reader was not
+     * actually in the cache, do nothing.
+     *
+     * @param reader The XMLReader that's being released.
+     */
+    public synchronized void releaseXMLReader(XMLReader reader) {
+        // If the reader that's being released is the cached reader
+        // for this thread, remove it from the m_isUse list.
+        if (m_readers.get() == reader && reader != null) {
+            m_inUse.remove(reader);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xml/utils/XMLString.java b/src/main/java/org/apache/xml/utils/XMLString.java
new file mode 100644
index 0000000..c968d80
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLString.java
@@ -0,0 +1,689 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLString.java 570109 2007-08-27 13:31:35Z zongaro $
+ */
+package org.apache.xml.utils;
+
+import java.util.Locale;
+
+/**
+ * This class is meant to be an interface to character strings, whether they
+ * be java Strings or <code>org.apache.xml.utils.FastStringBuffer</code>s, or
+ * other character data.  By using XMLString, character copies can be reduced
+ * in the XML pipeline.
+ */
+public interface XMLString
+{
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public abstract void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+    throws org.xml.sax.SAXException;
+
+  /**
+   * Directly call the
+   * comment method on the passed LexicalHandler for the
+   * string-value.
+   *
+   * @param lh A non-null reference to a LexicalHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public abstract void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
+    throws org.xml.sax.SAXException;
+    
+  /**
+   * Conditionally trim all leading and trailing whitespace in the specified String.
+   * All strings of white space are
+   * replaced by a single space character (#x20), except spaces after punctuation which
+   * receive double spaces if doublePunctuationSpaces is true.
+   * This function may be useful to a formatter, but to get first class
+   * results, the formatter should probably do it's own white space handling
+   * based on the semantics of the formatting object.
+   * 
+   * @param   trimHead    Trim leading whitespace?
+   * @param   trimTail    Trim trailing whitespace?
+   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
+   * @return              The trimmed string.
+   */
+  public XMLString fixWhiteSpace(boolean trimHead,
+                                 boolean trimTail,
+                                 boolean doublePunctuationSpaces);
+
+  /**
+   * Returns the length of this string.
+   *
+   * @return  the length of the sequence of characters represented by this
+   *          object.
+   */
+  public abstract int length();
+
+  /**
+   * Returns the character at the specified index. An index ranges
+   * from <code>0</code> to <code>length() - 1</code>. The first character
+   * of the sequence is at index <code>0</code>, the next at index
+   * <code>1</code>, and so on, as for array indexing.
+   *
+   * @param      index   the index of the character.
+   * @return     the character at the specified index of this string.
+   *             The first character is at index <code>0</code>.
+   * @exception  IndexOutOfBoundsException  if the <code>index</code>
+   *             argument is negative or not less than the length of this
+   *             string.
+   */
+  public abstract char charAt(int index);
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  public abstract void getChars(int srcBegin, int srcEnd, char dst[],
+                                int dstBegin);
+                                
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is an <code>XMLString</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   anObject   the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public abstract boolean equals(XMLString anObject);
+
+  /**
+   * Compares this string to the specified <code>String</code>.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   anotherString   the object to compare this <code>String</code>
+   *                          against.
+   * @return  <code>true</code> if the <code>String</code>s are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public abstract boolean equals(String anotherString);
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   anObject   the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public abstract boolean equals(Object anObject);
+
+  /**
+   * Compares this <code>String</code> to another <code>String</code>,
+   * ignoring case considerations.  Two strings are considered equal
+   * ignoring case if they are of the same length, and corresponding
+   * characters in the two strings are equal ignoring case.
+   *
+   * @param   anotherString   the <code>String</code> to compare this
+   *                          <code>String</code> against.
+   * @return  <code>true</code> if the argument is not <code>null</code>
+   *          and the <code>String</code>s are equal,
+   *          ignoring case; <code>false</code> otherwise.
+   * @see     #equals(Object)
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see java.lang.Character#toUpperCase(char)
+   */
+  public abstract boolean equalsIgnoreCase(String anotherString);
+
+  /**
+   * Compares two strings lexicographically.
+   *
+   * @param   anotherString   the <code>String</code> to be compared.
+   * @return  the value <code>0</code> if the argument string is equal to
+   *          this string; a value less than <code>0</code> if this string
+   *          is lexicographically less than the string argument; and a
+   *          value greater than <code>0</code> if this string is
+   *          lexicographically greater than the string argument.
+   * @exception java.lang.NullPointerException if <code>anotherString</code>
+   *          is <code>null</code>.
+   */
+  public abstract int compareTo(XMLString anotherString);
+
+  /**
+   * Compares two strings lexicographically, ignoring case considerations.
+   * This method returns an integer whose sign is that of
+   * <code>this.toUpperCase().toLowerCase().compareTo(
+   * str.toUpperCase().toLowerCase())</code>.
+   * <p>
+   * Note that this method does <em>not</em> take locale into account,
+   * and will result in an unsatisfactory ordering for certain locales.
+   * The java.text package provides <em>collators</em> to allow
+   * locale-sensitive ordering.
+   *
+   * @param   str   the <code>String</code> to be compared.
+   * @return  a negative integer, zero, or a positive integer as the
+   *          the specified String is greater than, equal to, or less
+   *          than this String, ignoring case considerations.
+   * @see     java.text.Collator#compare(String, String)
+   * @since   1.2
+   */
+  public abstract int compareToIgnoreCase(XMLString str);
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public abstract boolean startsWith(String prefix, int toffset);
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public abstract boolean startsWith(XMLString prefix, int toffset);
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   * @since   JDK1. 0
+   */
+  public abstract boolean startsWith(String prefix);
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   * @since   JDK1. 0
+   */
+  public abstract boolean startsWith(XMLString prefix);
+
+  /**
+   * Tests if this string ends with the specified suffix.
+   *
+   * @param   suffix   the suffix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a suffix of the character sequence represented by
+   *          this object; <code>false</code> otherwise. Note that the
+   *          result will be <code>true</code> if the argument is the
+   *          empty string or is equal to this <code>String</code> object
+   *          as determined by the {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>suffix</code> is
+   *          <code>null</code>.
+   */
+  public abstract boolean endsWith(String suffix);
+
+  /**
+   * Returns a hashcode for this string. The hashcode for a
+   * <code>String</code> object is computed as
+   * <blockquote><pre>
+   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+   * </pre></blockquote>
+   * using <code>int</code> arithmetic, where <code>s[i]</code> is the
+   * <i>i</i>th character of the string, <code>n</code> is the length of
+   * the string, and <code>^</code> indicates exponentiation.
+   * (The hash value of the empty string is zero.)
+   *
+   * @return  a hash code value for this object.
+   */
+  public abstract int hashCode();
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character. If a character with value <code>ch</code> occurs
+   * in the character sequence represented by this <code>String</code>
+   * object, then the index of the first such occurrence is returned --
+   * that is, the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is <code>true</code>. If no such character occurs in this string,
+   * then <code>-1</code> is returned.
+   *
+   * @param   ch   a character.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public abstract int indexOf(int ch);
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character, starting the search at the specified index.
+   * <p>
+   * If a character with value <code>ch</code> occurs in the character
+   * sequence represented by this <code>String</code> object at an index
+   * no smaller than <code>fromIndex</code>, then the index of the first
+   * such occurrence is returned--that is, the smallest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is true. If no such character occurs in this string at or after
+   * position <code>fromIndex</code>, then <code>-1</code> is returned.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If it
+   * is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object that is greater
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur.
+   */
+  public abstract int indexOf(int ch, int fromIndex);
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character. That is, the index returned is the largest
+   * value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is true.
+   * The String is searched backwards starting at the last character.
+   *
+   * @param   ch   a character.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public abstract int lastIndexOf(int ch);
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character, searching backward starting at the specified
+   * index. That is, the index returned is the largest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * this.charAt(k) == ch) && (k <= fromIndex)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of <code>fromIndex</code>. If it is
+   *          greater than or equal to the length of this string, it has
+   *          the same effect as if it were equal to one less than the
+   *          length of this string: this entire string may be searched.
+   *          If it is negative, it has the same effect as if it were -1:
+   *          -1 is returned.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object that is less
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur before that point.
+   */
+  public abstract int lastIndexOf(int ch, int fromIndex);
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public abstract int indexOf(String str);
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public abstract int indexOf(XMLString str);
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring, starting at the specified index. The integer
+   * returned is the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If
+   * it is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from.
+   * @return  If the string argument occurs as a substring within this
+   *          object at a starting index no smaller than
+   *          <code>fromIndex</code>, then the index of the first character
+   *          of the first such substring is returned. If it does not occur
+   *          as a substring starting at <code>fromIndex</code> or beyond,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>
+   */
+  public abstract int indexOf(String str, int fromIndex);
+
+  /**
+   * Returns the index within this string of the rightmost occurrence
+   * of the specified substring.  The rightmost empty string "" is
+   * considered to occur at the index value <code>this.length()</code>.
+   * The returned index is the largest value <i>k</i> such that
+   * <blockquote><pre>
+   * this.startsWith(str, k)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   str   the substring to search for.
+   * @return  if the string argument occurs one or more times as a substring
+   *          within this object, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as
+   *          a substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException  if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public abstract int lastIndexOf(String str);
+
+  /**
+   * Returns the index within this string of the last occurrence of
+   * the specified substring.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of fromIndex. If it is greater than
+   *          the length of this string, it has the same effect as if it
+   *          were equal to the length of this string: this entire string
+   *          may be searched. If it is negative, it has the same effect
+   *          as if it were -1: -1 is returned.
+   * @return  If the string argument occurs one or more times as a substring
+   *          within this object at a starting index no greater than
+   *          <code>fromIndex</code>, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as a
+   *          substring starting at <code>fromIndex</code> or earlier,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public abstract int lastIndexOf(String str, int fromIndex);
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins with the character at the specified index and
+   * extends to the end of this string. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "unhappy".substring(2) returns "happy"
+   * "Harbison".substring(3) returns "bison"
+   * "emptiness".substring(9) returns "" (an empty string)
+   * </pre></blockquote>
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if
+   *             <code>beginIndex</code> is negative or larger than the
+   *             length of this <code>String</code> object.
+   */
+  public abstract XMLString substring(int beginIndex);
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins at the specified <code>beginIndex</code> and
+   * extends to the character at index <code>endIndex - 1</code>.
+   * Thus the length of the substring is <code>endIndex-beginIndex</code>.
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @param      endIndex     the ending index, exclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if the
+   *             <code>beginIndex</code> is negative, or
+   *             <code>endIndex</code> is larger than the length of
+   *             this <code>String</code> object, or
+   *             <code>beginIndex</code> is larger than
+   *             <code>endIndex</code>.
+   */
+  public abstract XMLString substring(int beginIndex, int endIndex);
+
+  /**
+   * Concatenates the specified string to the end of this string.
+   *
+   * @param   str   the <code>String</code> that is concatenated to the end
+   *                of this <code>String</code>.
+   * @return  a string that represents the concatenation of this object's
+   *          characters followed by the string argument's characters.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public abstract XMLString concat(String str);
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the given <code>Locale</code>.
+   *
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public abstract XMLString toLowerCase(Locale locale);
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   * <p>
+   *
+   * @return  the string, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public abstract XMLString toLowerCase();
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the given locale.
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public abstract XMLString toUpperCase(Locale locale);
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   *
+   * <p>
+   * If no character in this string has a different uppercase version,
+   * based on calling the <code>toUpperCase</code> method defined by
+   * <code>Character</code>, then the original string is returned.
+   * <p>
+   * Otherwise, this method creates a new <code>String</code> object
+   * representing a character sequence identical in length to the
+   * character sequence represented by this <code>String</code> object and
+   * with every character equal to the result of applying the method
+   * <code>Character.toUpperCase</code> to the corresponding character of
+   * this <code>String</code> object. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "Fahrvergn&uuml;gen".toUpperCase() returns "FAHRVERGN&Uuml;GEN"
+   * "Visit Ljubinje!".toUpperCase() returns "VISIT LJUBINJE!"
+   * </pre></blockquote>
+   *
+   * @return  the string, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public abstract XMLString toUpperCase();
+
+  /**
+   * Removes white space from both ends of this string.
+   * <p>
+   * If this <code>String</code> object represents an empty character
+   * sequence, or the first and last characters of character sequence
+   * represented by this <code>String</code> object both have codes
+   * greater than <code>'&#92;u0020'</code> (the space character), then a
+   * reference to this <code>String</code> object is returned.
+   * <p>
+   * Otherwise, if there is no character with a code greater than
+   * <code>'&#92;u0020'</code> in the string, then a new
+   * <code>String</code> object representing an empty string is created
+   * and returned.
+   * <p>
+   * Otherwise, let <i>k</i> be the index of the first character in the
+   * string whose code is greater than <code>'&#92;u0020'</code>, and let
+   * <i>m</i> be the index of the last character in the string whose code
+   * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
+   * object is created, representing the substring of this string that
+   * begins with the character at index <i>k</i> and ends with the
+   * character at index <i>m</i>-that is, the result of
+   * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
+   * <p>
+   * This method may be used to trim
+   * {@link Character#isSpace(char) whitespace} from the beginning and end
+   * of a string; in fact, it trims all ASCII control characters as well.
+   *
+   * @return  this string, with white space removed from the front and end.
+   */
+  public abstract XMLString trim();
+
+  /**
+   * This object (which is already a string!) is itself returned.
+   *
+   * @return  the string itself.
+   */
+  public abstract String toString();
+  
+  /**
+   * Tell if this object contains a java String object.
+   * 
+   * @return true if this XMLString can return a string without creating one.
+   */
+  public abstract boolean hasString();
+  
+  /**
+   * Convert a string to a double -- Allowed input is in fixed
+   * notation ddd.fff.
+   *
+   * @return A double value representation of the string, or return Double.NaN 
+   * if the string can not be converted.
+   */
+  public double toDouble();
+}
diff --git a/src/main/java/org/apache/xml/utils/XMLStringDefault.java b/src/main/java/org/apache/xml/utils/XMLStringDefault.java
new file mode 100644
index 0000000..746d25a
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLStringDefault.java
@@ -0,0 +1,818 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLStringDefault.java 570109 2007-08-27 13:31:35Z zongaro $
+ */
+package org.apache.xml.utils;
+
+import java.util.Locale;
+
+/**
+ * The default implementation of the XMLString interface,
+ * which is just a simple wrapper of a String object.
+ */
+public class XMLStringDefault implements XMLString
+{
+
+  private String m_str;
+  
+  /**
+   * Create a XMLStringDefault object from a String
+   */
+  public XMLStringDefault(String str)
+  {
+    m_str = str;
+  }
+  
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+    throws org.xml.sax.SAXException
+  {
+  }
+
+  /**
+   * Directly call the
+   * comment method on the passed LexicalHandler for the
+   * string-value.
+   *
+   * @param lh A non-null reference to a LexicalHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
+    throws org.xml.sax.SAXException
+  {
+  }
+    
+  /**
+   * Conditionally trim all leading and trailing whitespace in the specified String.
+   * All strings of white space are
+   * replaced by a single space character (#x20), except spaces after punctuation which
+   * receive double spaces if doublePunctuationSpaces is true.
+   * This function may be useful to a formatter, but to get first class
+   * results, the formatter should probably do it's own white space handling
+   * based on the semantics of the formatting object.
+   * 
+   * @param   trimHead    Trim leading whitespace?
+   * @param   trimTail    Trim trailing whitespace?
+   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
+   * @return              The trimmed string.
+   */
+  public XMLString fixWhiteSpace(boolean trimHead,
+                                 boolean trimTail,
+                                 boolean doublePunctuationSpaces)
+  {
+    return new XMLStringDefault(m_str.trim());
+  }
+
+  /**
+   * Returns the length of this string.
+   *
+   * @return  the length of the sequence of characters represented by this
+   *          object.
+   */
+  public int length()
+  {
+    return m_str.length();
+  }
+
+  /**
+   * Returns the character at the specified index. An index ranges
+   * from <code>0</code> to <code>length() - 1</code>. The first character
+   * of the sequence is at index <code>0</code>, the next at index
+   * <code>1</code>, and so on, as for array indexing.
+   *
+   * @param      index   the index of the character.
+   * @return     the character at the specified index of this string.
+   *             The first character is at index <code>0</code>.
+   * @exception  IndexOutOfBoundsException  if the <code>index</code>
+   *             argument is negative or not less than the length of this
+   *             string.
+   */
+  public char charAt(int index)
+  {
+    return m_str.charAt(index);
+  }
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  public void getChars(int srcBegin, int srcEnd, char dst[],
+                                int dstBegin)
+  {
+    int destIndex = dstBegin;
+    for (int i = srcBegin; i < srcEnd; i++)
+    {
+      dst[destIndex++] = m_str.charAt(i);
+    }
+  }
+
+  /**
+   * Compares this string to the specified <code>String</code>.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   obj2   the object to compare this <code>String</code> against.
+   * @return  <code>true</code> if the <code>String</code>s are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(String obj2) {
+      return m_str.equals(obj2);
+  }
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   anObject   the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(XMLString anObject)
+  {
+    return m_str.equals(anObject.toString());
+  }
+
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   anObject   the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(Object anObject)
+  {
+    return m_str.equals(anObject);
+  }
+
+  /**
+   * Compares this <code>String</code> to another <code>String</code>,
+   * ignoring case considerations.  Two strings are considered equal
+   * ignoring case if they are of the same length, and corresponding
+   * characters in the two strings are equal ignoring case.
+   *
+   * @param   anotherString   the <code>String</code> to compare this
+   *                          <code>String</code> against.
+   * @return  <code>true</code> if the argument is not <code>null</code>
+   *          and the <code>String</code>s are equal,
+   *          ignoring case; <code>false</code> otherwise.
+   * @see     #equals(Object)
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see java.lang.Character#toUpperCase(char)
+   */
+  public boolean equalsIgnoreCase(String anotherString)
+  {
+    return m_str.equalsIgnoreCase(anotherString);
+  }
+
+  /**
+   * Compares two strings lexicographically.
+   *
+   * @param   anotherString   the <code>String</code> to be compared.
+   * @return  the value <code>0</code> if the argument string is equal to
+   *          this string; a value less than <code>0</code> if this string
+   *          is lexicographically less than the string argument; and a
+   *          value greater than <code>0</code> if this string is
+   *          lexicographically greater than the string argument.
+   * @exception java.lang.NullPointerException if <code>anotherString</code>
+   *          is <code>null</code>.
+   */
+  public int compareTo(XMLString anotherString)
+  {
+    return m_str.compareTo(anotherString.toString());
+  }
+
+  /**
+   * Compares two strings lexicographically, ignoring case considerations.
+   * This method returns an integer whose sign is that of
+   * <code>this.toUpperCase().toLowerCase().compareTo(
+   * str.toUpperCase().toLowerCase())</code>.
+   * <p>
+   * Note that this method does <em>not</em> take locale into account,
+   * and will result in an unsatisfactory ordering for certain locales.
+   * The java.text package provides <em>collators</em> to allow
+   * locale-sensitive ordering.
+   *
+   * @param   str   the <code>String</code> to be compared.
+   * @return  a negative integer, zero, or a positive integer as the
+   *          the specified String is greater than, equal to, or less
+   *          than this String, ignoring case considerations.
+   * @see     java.text.Collator#compare(String, String)
+   * @since   1.2
+   */
+  public int compareToIgnoreCase(XMLString str)
+  {
+    return m_str.compareToIgnoreCase(str.toString());
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(String prefix, int toffset)
+  {
+    return m_str.startsWith(prefix, toffset);
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(XMLString prefix, int toffset)
+  {
+    return m_str.startsWith(prefix.toString(), toffset);
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   * @since   JDK1. 0
+   */
+  public boolean startsWith(String prefix)
+  {
+    return m_str.startsWith(prefix);
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   * @since   JDK1. 0
+   */
+  public boolean startsWith(XMLString prefix)
+  {
+    return m_str.startsWith(prefix.toString());
+  }
+
+  /**
+   * Tests if this string ends with the specified suffix.
+   *
+   * @param   suffix   the suffix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a suffix of the character sequence represented by
+   *          this object; <code>false</code> otherwise. Note that the
+   *          result will be <code>true</code> if the argument is the
+   *          empty string or is equal to this <code>String</code> object
+   *          as determined by the {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>suffix</code> is
+   *          <code>null</code>.
+   */
+  public boolean endsWith(String suffix)
+  {
+    return m_str.endsWith(suffix);
+  }
+
+  /**
+   * Returns a hashcode for this string. The hashcode for a
+   * <code>String</code> object is computed as
+   * <blockquote><pre>
+   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+   * </pre></blockquote>
+   * using <code>int</code> arithmetic, where <code>s[i]</code> is the
+   * <i>i</i>th character of the string, <code>n</code> is the length of
+   * the string, and <code>^</code> indicates exponentiation.
+   * (The hash value of the empty string is zero.)
+   *
+   * @return  a hash code value for this object.
+   */
+  public int hashCode()
+  {
+    return m_str.hashCode();
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character. If a character with value <code>ch</code> occurs
+   * in the character sequence represented by this <code>String</code>
+   * object, then the index of the first such occurrence is returned --
+   * that is, the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is <code>true</code>. If no such character occurs in this string,
+   * then <code>-1</code> is returned.
+   *
+   * @param   ch   a character.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public int indexOf(int ch)
+  {
+    return m_str.indexOf(ch);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character, starting the search at the specified index.
+   * <p>
+   * If a character with value <code>ch</code> occurs in the character
+   * sequence represented by this <code>String</code> object at an index
+   * no smaller than <code>fromIndex</code>, then the index of the first
+   * such occurrence is returned--that is, the smallest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is true. If no such character occurs in this string at or after
+   * position <code>fromIndex</code>, then <code>-1</code> is returned.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If it
+   * is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object that is greater
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur.
+   */
+  public int indexOf(int ch, int fromIndex)
+  {
+    return m_str.indexOf(ch, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character. That is, the index returned is the largest
+   * value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is true.
+   * The String is searched backwards starting at the last character.
+   *
+   * @param   ch   a character.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public int lastIndexOf(int ch)
+  {
+    return m_str.lastIndexOf(ch);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character, searching backward starting at the specified
+   * index. That is, the index returned is the largest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * this.charAt(k) == ch) && (k <= fromIndex)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of <code>fromIndex</code>. If it is
+   *          greater than or equal to the length of this string, it has
+   *          the same effect as if it were equal to one less than the
+   *          length of this string: this entire string may be searched.
+   *          If it is negative, it has the same effect as if it were -1:
+   *          -1 is returned.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object that is less
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur before that point.
+   */
+  public int lastIndexOf(int ch, int fromIndex)
+  {
+    return m_str.lastIndexOf(ch, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int indexOf(String str)
+  {
+    return m_str.indexOf(str);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int indexOf(XMLString str)
+  {
+    return m_str.indexOf(str.toString());
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring, starting at the specified index. The integer
+   * returned is the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If
+   * it is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from.
+   * @return  If the string argument occurs as a substring within this
+   *          object at a starting index no smaller than
+   *          <code>fromIndex</code>, then the index of the first character
+   *          of the first such substring is returned. If it does not occur
+   *          as a substring starting at <code>fromIndex</code> or beyond,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>
+   */
+  public int indexOf(String str, int fromIndex)
+  {
+    return m_str.indexOf(str, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the rightmost occurrence
+   * of the specified substring.  The rightmost empty string "" is
+   * considered to occur at the index value <code>this.length()</code>.
+   * The returned index is the largest value <i>k</i> such that
+   * <blockquote><pre>
+   * this.startsWith(str, k)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   str   the substring to search for.
+   * @return  if the string argument occurs one or more times as a substring
+   *          within this object, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as
+   *          a substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException  if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int lastIndexOf(String str)
+  {
+    return m_str.lastIndexOf(str);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of
+   * the specified substring.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of fromIndex. If it is greater than
+   *          the length of this string, it has the same effect as if it
+   *          were equal to the length of this string: this entire string
+   *          may be searched. If it is negative, it has the same effect
+   *          as if it were -1: -1 is returned.
+   * @return  If the string argument occurs one or more times as a substring
+   *          within this object at a starting index no greater than
+   *          <code>fromIndex</code>, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as a
+   *          substring starting at <code>fromIndex</code> or earlier,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int lastIndexOf(String str, int fromIndex)
+  {
+    return m_str.lastIndexOf(str, fromIndex);
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins with the character at the specified index and
+   * extends to the end of this string. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "unhappy".substring(2) returns "happy"
+   * "Harbison".substring(3) returns "bison"
+   * "emptiness".substring(9) returns "" (an empty string)
+   * </pre></blockquote>
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if
+   *             <code>beginIndex</code> is negative or larger than the
+   *             length of this <code>String</code> object.
+   */
+  public XMLString substring(int beginIndex)
+  {
+    return new XMLStringDefault(m_str.substring(beginIndex));
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins at the specified <code>beginIndex</code> and
+   * extends to the character at index <code>endIndex - 1</code>.
+   * Thus the length of the substring is <code>endIndex-beginIndex</code>.
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @param      endIndex     the ending index, exclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if the
+   *             <code>beginIndex</code> is negative, or
+   *             <code>endIndex</code> is larger than the length of
+   *             this <code>String</code> object, or
+   *             <code>beginIndex</code> is larger than
+   *             <code>endIndex</code>.
+   */
+  public XMLString substring(int beginIndex, int endIndex)
+  {
+    return new XMLStringDefault(m_str.substring(beginIndex, endIndex));
+  }
+
+  /**
+   * Concatenates the specified string to the end of this string.
+   *
+   * @param   str   the <code>String</code> that is concatenated to the end
+   *                of this <code>String</code>.
+   * @return  a string that represents the concatenation of this object's
+   *          characters followed by the string argument's characters.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public XMLString concat(String str)
+  {
+    return new XMLStringDefault(m_str.concat(str));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the given <code>Locale</code>.
+   *
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public XMLString toLowerCase(Locale locale)
+  {
+    return new XMLStringDefault(m_str.toLowerCase(locale));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   * <p>
+   *
+   * @return  the string, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public XMLString toLowerCase()
+  {
+    return new XMLStringDefault(m_str.toLowerCase());
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the given locale.
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public XMLString toUpperCase(Locale locale)
+  {
+    return new XMLStringDefault(m_str.toUpperCase(locale));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   *
+   * <p>
+   * If no character in this string has a different uppercase version,
+   * based on calling the <code>toUpperCase</code> method defined by
+   * <code>Character</code>, then the original string is returned.
+   * <p>
+   * Otherwise, this method creates a new <code>String</code> object
+   * representing a character sequence identical in length to the
+   * character sequence represented by this <code>String</code> object and
+   * with every character equal to the result of applying the method
+   * <code>Character.toUpperCase</code> to the corresponding character of
+   * this <code>String</code> object. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "Fahrvergn&uuml;gen".toUpperCase() returns "FAHRVERGN&Uuml;GEN"
+   * "Visit Ljubinje!".toUpperCase() returns "VISIT LJUBINJE!"
+   * </pre></blockquote>
+   *
+   * @return  the string, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public XMLString toUpperCase()
+  {
+    return new XMLStringDefault(m_str.toUpperCase());
+  }
+
+  /**
+   * Removes white space from both ends of this string.
+   * <p>
+   * If this <code>String</code> object represents an empty character
+   * sequence, or the first and last characters of character sequence
+   * represented by this <code>String</code> object both have codes
+   * greater than <code>'&#92;u0020'</code> (the space character), then a
+   * reference to this <code>String</code> object is returned.
+   * <p>
+   * Otherwise, if there is no character with a code greater than
+   * <code>'&#92;u0020'</code> in the string, then a new
+   * <code>String</code> object representing an empty string is created
+   * and returned.
+   * <p>
+   * Otherwise, let <i>k</i> be the index of the first character in the
+   * string whose code is greater than <code>'&#92;u0020'</code>, and let
+   * <i>m</i> be the index of the last character in the string whose code
+   * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
+   * object is created, representing the substring of this string that
+   * begins with the character at index <i>k</i> and ends with the
+   * character at index <i>m</i>-that is, the result of
+   * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
+   * <p>
+   * This method may be used to trim
+   * {@link Character#isSpace(char) whitespace} from the beginning and end
+   * of a string; in fact, it trims all ASCII control characters as well.
+   *
+   * @return  this string, with white space removed from the front and end.
+   */
+  public XMLString trim()
+  {
+    return new XMLStringDefault(m_str.trim());
+  }
+
+  /**
+   * This object (which is already a string!) is itself returned.
+   *
+   * @return  the string itself.
+   */
+  public String toString()
+  {
+    return m_str;
+  }
+  
+  /**
+   * Tell if this object contains a java String object.
+   * 
+   * @return true if this XMLString can return a string without creating one.
+   */
+  public boolean hasString()
+  {
+    return true;
+  }
+  
+  /**
+   * Convert a string to a double -- Allowed input is in fixed
+   * notation ddd.fff.
+   *
+   * @return A double value representation of the string, or return Double.NaN 
+   * if the string can not be converted.
+   */
+  public double toDouble()
+  {
+    try {
+      return Double.valueOf(m_str).doubleValue();
+    }
+    catch (NumberFormatException nfe)
+    {
+      return Double.NaN;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/XMLStringFactory.java b/src/main/java/org/apache/xml/utils/XMLStringFactory.java
new file mode 100644
index 0000000..3656fa6
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/XMLStringFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLStringFactory.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils;
+
+/**
+ * A concrete class that implements this interface creates XMLString objects.
+ */
+public abstract class XMLStringFactory
+{
+
+  /**
+   * Create a new XMLString from a Java string.
+   *
+   *
+   * @param string Java String reference, which must be non-null.
+   *
+   * @return An XMLString object that wraps the String reference.
+   */
+  public abstract XMLString newstr(String string);
+
+  /**
+   * Create a XMLString from a FastStringBuffer.
+   *
+   *
+   * @param string FastStringBuffer reference, which must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   *
+   * @return An XMLString object that wraps the FastStringBuffer reference.
+   */
+  public abstract XMLString newstr(FastStringBuffer string, int start, 
+                                   int length);
+
+  /**
+   * Create a XMLString from a FastStringBuffer.
+   *
+   *
+   * @param string FastStringBuffer reference, which must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   *
+   * @return An XMLString object that wraps the FastStringBuffer reference.
+   */
+  public abstract XMLString newstr(char[] string, int start, 
+                                   int length);
+                                   
+  /**
+   * Get a cheap representation of an empty string.
+   * 
+   * @return An non-null reference to an XMLString that represents "".
+   */
+  public abstract XMLString emptystr();
+}
diff --git a/src/main/java/org/apache/xml/utils/package.html b/src/main/java/org/apache/xml/utils/package.html
new file mode 100644
index 0000000..c943bbc
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/package.html
@@ -0,0 +1,27 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>Xalan utilities.</title>
+  <body>
+    <p>Implementation of Xalan utility classes.  This package is also shared by XPath.
+       There *should* be no outward dependencies to XPath or Xalan by classes in this package.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xml/utils/res/CharArrayWrapper.java b/src/main/java/org/apache/xml/utils/res/CharArrayWrapper.java
new file mode 100755
index 0000000..62aa7ba
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/CharArrayWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: CharArrayWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+/**
+ *
+ * It is a mutable object to wrap the char[] used in
+ * the contents of the XResourceBundle class
+ */
+public class CharArrayWrapper {
+    private char[] m_char;
+    
+    public CharArrayWrapper(char[] arg){
+        m_char = arg;
+    }
+    
+    public char getChar(int index){
+        return m_char[index];
+    }
+    
+    public int getLength(){
+        return m_char.length;
+    }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/IntArrayWrapper.java b/src/main/java/org/apache/xml/utils/res/IntArrayWrapper.java
new file mode 100755
index 0000000..b9794a7
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/IntArrayWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IntArrayWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+/**
+ *
+ * It is a mutable object to wrap the int[] used in
+ * the contents of the XResourceBundle class
+ */
+public class IntArrayWrapper {
+    private int[] m_int;
+    
+    public IntArrayWrapper(int[] arg){
+        m_int = arg;
+    }
+    
+    public int getInt(int index){
+        return m_int[index];
+    }
+    
+    public int getLength(){
+        return m_int.length;
+    }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/LongArrayWrapper.java b/src/main/java/org/apache/xml/utils/res/LongArrayWrapper.java
new file mode 100755
index 0000000..a98bbb2
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/LongArrayWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: LongArrayWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+/**
+ *
+ * It is a mutable object to wrap the long[] used in
+ * the contents of the XResourceBundle class
+ */
+public class LongArrayWrapper {
+    private long[] m_long;
+    
+    public LongArrayWrapper(long[] arg){
+        m_long = arg;
+    }
+    
+    public long getLong(int index){
+        return m_long[index];
+    }
+    
+    public int getLength(){
+        return m_long.length;
+    }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/StringArrayWrapper.java b/src/main/java/org/apache/xml/utils/res/StringArrayWrapper.java
new file mode 100755
index 0000000..e669e8e
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/StringArrayWrapper.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StringArrayWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+/**
+ *
+ * It is a mutable object to wrap the String[] used in
+ * the contents of the XResourceBundle class
+ */
+public class StringArrayWrapper {
+    private String[] m_string;
+    
+    public StringArrayWrapper(String[] arg){
+        m_string = arg;
+    }
+    
+    public String getString(int index){
+        return m_string[index];
+    }
+    
+    public int getLength(){
+        return m_string.length;
+    }
+}
+
diff --git a/src/main/java/org/apache/xml/utils/res/XResourceBundle.java b/src/main/java/org/apache/xml/utils/res/XResourceBundle.java
new file mode 100644
index 0000000..72e829c
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResourceBundle.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResourceBundle.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * The default (english) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResourceBundle extends ListResourceBundle
+{
+
+  /** Error resource constants */
+  public static final String ERROR_RESOURCES =
+    "org.apache.xalan.res.XSLTErrorResources", XSLT_RESOURCE =
+    "org.apache.xml.utils.res.XResourceBundle", LANG_BUNDLE_NAME =
+    "org.apache.xml.utils.res.XResources", MULT_ORDER =
+    "multiplierOrder", MULT_PRECEDES = "precedes", MULT_FOLLOWS =
+    "follows", LANG_ORIENTATION = "orientation", LANG_RIGHTTOLEFT =
+    "rightToLeft", LANG_LEFTTORIGHT = "leftToRight", LANG_NUMBERING =
+    "numbering", LANG_ADDITIVE = "additive", LANG_MULT_ADD =
+    "multiplicative-additive", LANG_MULTIPLIER =
+    "multiplier", LANG_MULTIPLIER_CHAR =
+    "multiplierChar", LANG_NUMBERGROUPS = "numberGroups", LANG_NUM_TABLES =
+    "tables", LANG_ALPHABET = "alphabet", LANG_TRAD_ALPHABET = "tradAlphabet";
+
+  /**
+   * Return a named ResourceBundle for a particular locale.  This method mimics the behavior
+   * of ResourceBundle.getBundle().
+   *
+   * @param className Name of local-specific subclass.
+   * @param locale the locale to prefer when searching for the bundle
+   */
+  public static final XResourceBundle loadResourceBundle(
+          String className, Locale locale) throws MissingResourceException
+  {
+
+    String suffix = getResourceSuffix(locale);
+
+    //System.out.println("resource " + className + suffix);
+    try
+    {
+      
+      // first try with the given locale
+      String resourceName = className + suffix;
+      return (XResourceBundle) ResourceBundle.getBundle(resourceName, locale);
+    }
+    catch (MissingResourceException e)
+    {
+      try  // try to fall back to en_US if we can't load
+      {
+
+        // Since we can't find the localized property file,
+        // fall back to en_US.
+        return (XResourceBundle) ResourceBundle.getBundle(
+          XSLT_RESOURCE, new Locale("en", "US"));
+      }
+      catch (MissingResourceException e2)
+      {
+
+        // Now we are really in trouble.
+        // very bad, definitely very bad...not going to get very far
+        throw new MissingResourceException(
+          "Could not load any resource bundles.", className, "");
+      }
+    }
+  }
+
+  /**
+   * Return the resource file suffic for the indicated locale
+   * For most locales, this will be based the language code.  However
+   * for Chinese, we do distinguish between Taiwan and PRC
+   *
+   * @param locale the locale
+   * @return an String suffix which canbe appended to a resource name
+   */
+  private static final String getResourceSuffix(Locale locale)
+  {
+
+    String lang = locale.getLanguage();
+    String country = locale.getCountry();
+    String variant = locale.getVariant();
+    String suffix = "_" + locale.getLanguage();
+
+    if (lang.equals("zh"))
+      suffix += "_" + country;
+
+    if (country.equals("JP"))
+      suffix += "_" + country + "_" + variant;
+
+    return suffix;
+  }
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "en" }, { "help_language", "en" }, { "language", "en" },
+    { "alphabet", new CharArrayWrapper(new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+         'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 
+         'V', 'W', 'X', 'Y', 'Z' })},
+    { "tradAlphabet", new CharArrayWrapper(new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 
+         'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
+         'U', 'V', 'W', 'X', 'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResourceBundleBase.java b/src/main/java/org/apache/xml/utils/res/XResourceBundleBase.java
new file mode 100644
index 0000000..fd49302
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResourceBundleBase.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResourceBundleBase.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+import java.util.ListResourceBundle;
+
+/**
+ * This is an interface for error messages.  This class is misnamed,
+ * and should be called XalanResourceBundle, or some such.
+ * @xsl.usage internal
+ */
+abstract public class XResourceBundleBase extends ListResourceBundle
+{
+
+  /**
+   * Get the error string associated with the error code
+   *
+   * @param errorCode Error code
+   *
+   * @return error string associated with the given error code
+   */
+  abstract public String getMessageKey(int errorCode);
+
+  /**
+   * Get the warning string associated with the error code
+   *
+   * @param errorCode Error code
+   * 
+   * @return warning string associated with the given error code
+   */
+  abstract public String getWarningKey(int errorCode);
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_cy.java b/src/main/java/org/apache/xml/utils/res/XResources_cy.java
new file mode 100644
index 0000000..2c8b42f
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_cy.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_cy.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+
+/**
+ * The Cyrillic resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_cy extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "cy" }, { "help_language", "cy" }, { "language", "cy" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x0430, 0x0432, 0x0433, 0x0434, 0x0435, 0x0437, 0x0438,
+                  0x0439, 0x04A9, 0x0457, 0x043A, 0x043B, 0x043C, 0x043D,
+                  0x046F, 0x043E, 0x043F, 0x0447, 0x0440, 0x0441, 0x0442,
+                  0x0443, 0x0444, 0x0445, 0x0470, 0x0460, 0x0446 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering 
+    //{"numbering", "additive"},
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "precedes" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 100, 10, 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    { "multiplier", new LongArrayWrapper(new long[]{ 1000 }) },
+    { "multiplierChar", new CharArrayWrapper(new char[]{ 0x03D9 }) },
+
+    // chinese only??
+    { "zero", new CharArrayWrapper(new char[0]) },
+
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x0430, 0x0432, 0x0433, 0x0434, 0x0435, 0x0437, 0x0438,
+                  0x0439, 0x04A9 }) },
+    { "tens", new CharArrayWrapper(
+      new char[]{ 0x0457, 0x043A, 0x043B, 0x043C, 0x043D, 0x046F, 0x043E,
+                  0x043F, 0x0447 }) },
+    { "hundreds", new CharArrayWrapper(
+      new char[]{ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0470,
+                  0x0460, 0x0446 }) },
+    { "tables", new StringArrayWrapper(new String[]{ "hundreds", "tens", "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_de.java b/src/main/java/org/apache/xml/utils/res/XResources_de.java
new file mode 100644
index 0000000..9a13c37
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_de.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_de.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_de.properties
+//
+
+/**
+ * The German resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_de extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "de" }, { "help_language", "de" }, { "language", "de" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_el.java b/src/main/java/org/apache/xml/utils/res/XResources_el.java
new file mode 100644
index 0000000..d4bc82b
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_el.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_el.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Greek resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_el extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "el" }, { "help_language", "el" }, { "language", "el" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+                  0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be,
+                  0x03bf, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5,
+                  0x03c6, 0x03c7, 0x03c8, 0x03c9 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering 
+    //{"numbering", "additive"},
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "precedes" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 100, 10, 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    { "multiplier", new LongArrayWrapper(new long[]{ 1000 }) },
+    { "multiplierChar", new CharArrayWrapper(new char[]{ 0x03d9 }) },
+
+    // chinese only??
+    { "zero", new CharArrayWrapper(new char[0]) },
+
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03db, 0x03b6,
+                  0x03b7, 0x03b8 }) },
+    { "tens", new CharArrayWrapper(
+      new char[]{ 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+                  0x03c0, 0x03df }) },
+    { "hundreds", new CharArrayWrapper(
+      new char[]{ 0x03c1, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8,
+                  0x03c9, 0x03e1 }) },
+
+    //{"thousands", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    { "tables", new StringArrayWrapper(new String[]{ "hundreds", "tens", "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_en.java b/src/main/java/org/apache/xml/utils/res/XResources_en.java
new file mode 100644
index 0000000..7116607
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_en.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_en.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The English resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_en extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][] 
+  {
+    { "ui_language", "en" }, { "help_language", "en" }, { "language", "en" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' })},
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_es.java b/src/main/java/org/apache/xml/utils/res/XResources_es.java
new file mode 100644
index 0000000..18ecebc
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_es.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_es.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_es.properties
+//
+
+/**
+ * The Spanish resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_es extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "es" }, { "help_language", "es" }, { "language", "es" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_fr.java b/src/main/java/org/apache/xml/utils/res/XResources_fr.java
new file mode 100644
index 0000000..55b6c88
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_fr.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_fr.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_fr.properties
+//
+
+/**
+ * The French resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_fr extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "fr" }, { "help_language", "fr" }, { "language", "fr" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_he.java b/src/main/java/org/apache/xml/utils/res/XResources_he.java
new file mode 100644
index 0000000..1089eb7
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_he.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_he.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Hebrew resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_he extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "he" }, { "help_language", "he" }, { "language", "he" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6,
+                  0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD,
+                  0x05DE, 0x05DF, 0x05E0, 0x05E1 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "RightToLeft" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 10, 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6,
+                  0x05D7, 0x05D8 }) },
+    { "tens", new CharArrayWrapper(
+      new char[]{ 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+                  0x05E0, 0x05E1 }) },
+
+    //hundreds, etc...
+    { "tables", new StringArrayWrapper(new String[]{ "tens", "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_hy.java b/src/main/java/org/apache/xml/utils/res/XResources_hy.java
new file mode 100644
index 0000000..e23154d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_hy.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_hy.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Armenian resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_hy extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "hy" }, { "help_language", "hy" }, { "language", "hy" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
+                  0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E,
+                  0x056F, 0x0567, 0x0568, 0x0572, 0x0573, 0x0574, 0x0575,
+                  0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C,
+                  0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583,
+                  0x0584 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1000, 100, 10, 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
+                  0x0568, 0x0569 }) },
+    { "tens", new CharArrayWrapper(
+      new char[]{ 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, 0x0567,
+                  0x0568, 0x0572 }) },
+    { "hundreds", new CharArrayWrapper(
+      new char[]{ 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579,
+                  0x057A, 0x057B }) },
+    { "thousands", new CharArrayWrapper(
+      new char[]{ 0x057C, 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582,
+                  0x0583, 0x0584 }) },
+    { "tables", new StringArrayWrapper(new String[]{ "thousands", "hundreds", "tens", "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_it.java b/src/main/java/org/apache/xml/utils/res/XResources_it.java
new file mode 100644
index 0000000..8808e37
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_it.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_it.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_it.properties
+//
+
+/**
+ * The Italian resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_it extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "it" }, { "help_language", "it" }, { "language", "it" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_A.java b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_A.java
new file mode 100644
index 0000000..3f41216
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_A.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ja_JP_A.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Japanese (Katakana) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ja_JP_A extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ja" }, { "help_language", "ja" }, { "language", "ja" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad,
+                  0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb,
+                  0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca,
+                  0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5,
+                  0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2,
+                  0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec,
+                  0x30ed, 0x30ef, 0x30f0, 0x30f1, 0x30f2, 0x30f3 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation 
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    // Note that we are using longs and that the last two 
+    // multipliers are not supported. This is a known limitation.
+    { "multiplier", new LongArrayWrapper(
+      new long[]{ Long.MAX_VALUE, Long.MAX_VALUE, 100000000, 10000, 1000, 
+          100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x4EAC, 0x5146, 0x5104, 0x4E07, 0x5343, 0x767e, 0x5341 }) },
+
+    // chinese only? 
+    { "zero", new CharArrayWrapper(new char[0]) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 0x4E94, 0x516D, 0x4E03,
+                  0x516B, 0x4E5D }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HA.java b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HA.java
new file mode 100644
index 0000000..7934665
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HA.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ja_JP_HA.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Japanese (Hiragana) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ja_JP_HA extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ja" }, { "help_language", "ja" }, { "language", "ja" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x3042, 0x3044, 0x3046, 0x3048, 0x304a, 0x304b, 0x304d,
+                  0x304f, 0x3051, 0x3053, 0x3055, 0x3057, 0x3059, 0x305b,
+                  0x305d, 0x305f, 0x3061, 0x3064, 0x3066, 0x3068, 0x306a,
+                  0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3072, 0x3075,
+                  0x3078, 0x307b, 0x307e, 0x307f, 0x3080, 0x3081, 0x3082,
+                  0x3084, 0x3086, 0x3088, 0x3089, 0x308a, 0x308b, 0x308c,
+                  0x308d, 0x308f, 0x3090, 0x3091, 0x3092, 0x3093 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation 
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    // Note that we are using longs and that the last two 
+    // multipliers are not supported. This is a known limitation.
+    { "multiplier", new LongArrayWrapper(
+      new long[]{ Long.MAX_VALUE, Long.MAX_VALUE, 100000000, 10000, 1000, 
+          100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x4EAC, 0x5146, 0x5104, 0x4E07, 0x5343, 0x767e, 0x5341 }) },
+
+    // chinese only? 
+    { "zero", new CharArrayWrapper(new char[0]) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 0x4E94, 0x516D, 0x4E03,
+                  0x516B, 0x4E5D }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HI.java b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HI.java
new file mode 100644
index 0000000..306fcb2
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_HI.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ja_JP_HI.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Japanese (Hiragana) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ja_JP_HI extends XResourceBundle
+{
+
+  /**
+   * Get the association table for this resource.
+   *
+   *
+   * @return the association table for this resource.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ja" }, { "help_language", "ja" }, { "language", "ja" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x3044, 0x308d, 0x306f, 0x306b, 0x307b, 0x3078, 0x3068,
+                  0x3061, 0x308a, 0x306c, 0x308b, 0x3092, 0x308f, 0x304b,
+                  0x3088, 0x305f, 0x308c, 0x305d, 0x3064, 0x306d, 0x306a,
+                  0x3089, 0x3080, 0x3046, 0x3090, 0x306e, 0x304a, 0x304f,
+                  0x3084, 0x307e, 0x3051, 0x3075, 0x3053, 0x3048, 0x3066,
+                  0x3042, 0x3055, 0x304d, 0x3086, 0x3081, 0x307f, 0x3057,
+                  0x3091, 0x3072, 0x3082, 0x305b, 0x3059 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value 
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    // Note that we are using longs and that the last two 
+    // multipliers are not supported. This is a known limitation.
+    { "multiplier", new LongArrayWrapper(
+      new long[]{ Long.MAX_VALUE, Long.MAX_VALUE, 100000000, 10000, 1000, 
+          100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x4EAC, 0x5146, 0x5104, 0x4E07, 0x5343, 0x767e, 0x5341 }) },
+
+    // chinese only??
+    { "zero", new CharArrayWrapper(new char[0]) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 0x4E94, 0x516D, 0x4E03,
+                  0x516B, 0x4E5D }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_I.java b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_I.java
new file mode 100644
index 0000000..b2b6558
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ja_JP_I.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ja_JP_I.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Japanese (Katakana) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ja_JP_I extends XResourceBundle
+{
+
+  /**
+   * Get the association table for this resource.
+   *
+   *
+   * @return the association table for this resource.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ja" }, { "help_language", "ja" }, { "language", "ja" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x30a4, 0x30ed, 0x30cf, 0x30cb, 0x30db, 0x30d8, 0x30c8,
+                  0x30c1, 0x30ea, 0x30cc, 0x30eb, 0x30f2, 0x30ef, 0x30ab,
+                  0x30e8, 0x30bf, 0x30ec, 0x30bd, 0x30c4, 0x30cd, 0x30ca,
+                  0x30e9, 0x30e0, 0x30a6, 0x30f0, 0x30ce, 0x30aa, 0x30af,
+                  0x30e4, 0x30de, 0x30b1, 0x30d5, 0x30b3, 0x30a8, 0x30c6,
+                  0x30a2, 0x30b5, 0x30ad, 0x30e6, 0x30e1, 0x30df, 0x30b7,
+                  0x30f1, 0x30d2, 0x30e2, 0x30bb, 0x30b9 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value 
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    //These only used for mutiplicative-additive numbering
+    // Note that we are using longs and that the last two 
+    // multipliers are not supported. This is a known limitation.
+    { "multiplier", new LongArrayWrapper(
+      new long[]{ Long.MAX_VALUE, Long.MAX_VALUE, 100000000, 10000, 1000, 100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x4EAC, 0x5146, 0x5104, 0x4E07, 0x5343, 0x767e, 0x5341 }) },
+
+    // chinese only??
+    { "zero", new CharArrayWrapper(new char[0]) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 0x4E94, 0x516D, 0x4E03,
+                  0x516B, 0x4E5D }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ka.java b/src/main/java/org/apache/xml/utils/res/XResources_ka.java
new file mode 100644
index 0000000..53dd551
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ka.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ka.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Georgian resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ka extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ka" }, { "help_language", "ka" }, { "language", "ka" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6,
+                  0x10f1, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC,
+                  0x10f2, 0x10DD, 0x10DE, 0x10DF, 0x10E0, 0x10E1, 0x10E2,
+                  0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9,
+                  0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10F4, 0x10EF,
+                  0x10F0 }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(10000000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1000, 100, 10, 1 }) },
+
+    //These used for additive numbering
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6,
+                  0x10f1, 0x10D7 }) },
+    { "tens", new CharArrayWrapper(
+      new char[]{ 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10f2, 0x10DD,
+                  0x10DE, 0x10DF }) },
+    { "hundreds", new CharArrayWrapper(
+      new char[]{ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6,
+                  0x10E7, 0x10E8 }) },
+    { "thousands", new CharArrayWrapper(
+      new char[]{ 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10F4,
+                  0x10EF, 0x10F0 }) },
+    { "tables", new StringArrayWrapper(new String[]{ "thousands", "hundreds", 
+            "tens", "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_ko.java b/src/main/java/org/apache/xml/utils/res/XResources_ko.java
new file mode 100644
index 0000000..c6a622b
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_ko.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_ko.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_ko.properties
+//
+
+/**
+ * The Korean resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_ko extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "ko" }, { "help_language", "ko" }, { "language", "ko" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0x3131, 0x3134, 0x3137, 0x3139, 0x3141, 0x3142, 0x3145, 
+                  0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 
+                  0x314f, 0x3151, 0x3153, 0x3155, 0x3157, 0x315b, 0x315c, 
+                  0x3160, 0x3161, 0x3163})},
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation 
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(100000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    // chinese only ??
+    { "zero", new CharArrayWrapper(new char[0]) },
+
+    //These only used for mutiplicative-additive numbering
+    { "multiplier", new LongArrayWrapper(new long[]{ 100000000, 10000, 1000, 
+        100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{  0xc5b5, 0xb9cc, 0xcc9c, 0xbc31, 0xc2ed }) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0xc77c, 0xc774, 0xc0bc, 0xc0ac, 0xc624, 0xc721, 0xce60, 
+          0xd314, 0xad6c}) }, { "tables", new StringArrayWrapper(
+              new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_sv.java b/src/main/java/org/apache/xml/utils/res/XResources_sv.java
new file mode 100644
index 0000000..a50766d
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_sv.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_sv.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_sv.properties
+//
+
+/**
+ * The Swedish resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_sv extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "sv" }, { "help_language", "sv" }, { "language", "sv" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "additive" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer()},
+    //These would not be used for EN. Only used for traditional numbering   
+    //{"numberGroups", new int[]{10,1}},
+    //These only used for mutiplicative-additive numbering
+    //{"multiplier", "10"},
+    //{"multiplierChar", "M"}, 
+    //{"digits", new char[]{'a','b','c','d','e','f','g','h','i'}},
+    //{"digits", new char[]{0x10D0,0x10D1,0x10D2,0x10D3,0x10D4,0x10D5,0x10D6,0x10D7,0x10D8}},
+    //{"tens", new char[]{0x10D9,0x10DA,0x10DB,0x10DC,0x10DD,0x10DE,0x10DF,0x10E0,0x10E1}},  
+    //hundreds, etc...
+    //{"tables", new String[]{"tens", "digits"}}
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_zh_CN.java b/src/main/java/org/apache/xml/utils/res/XResources_zh_CN.java
new file mode 100644
index 0000000..03fdd79
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_zh_CN.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_zh_CN.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Chinese resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_zh_CN extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "zh" }, { "help_language", "zh" }, { "language", "zh" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+                  0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e,
+                  0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35,
+                  0xff36, 0xff37, 0xff38, 0xff39, 0xff3a }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation 
+    { "orientation", "LeftToRight" },
+
+    //language numbering   
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(100000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    // simplified chinese  
+    { "zero", new CharArrayWrapper(new char[]{ 0x96f6 }) },
+
+    //These only used for mutiplicative-additive numbering
+    { "multiplier", new LongArrayWrapper(new long[]{ 100000000, 10000, 1000, 
+        100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x4ebf, 0x4e07, 0x5343, 0x767e, 0x5341 }) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x4e94, 0x516d, 0x4e03,
+                  0x516b, 0x4e5d }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xml/utils/res/XResources_zh_TW.java b/src/main/java/org/apache/xml/utils/res/XResources_zh_TW.java
new file mode 100644
index 0000000..db531a0
--- /dev/null
+++ b/src/main/java/org/apache/xml/utils/res/XResources_zh_TW.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XResources_zh_TW.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xml.utils.res;
+
+//
+//  LangResources_en.properties
+//
+
+/**
+ * The Chinese(Taiwan) resource bundle.
+ * @xsl.usage internal
+ */
+public class XResources_zh_TW extends XResourceBundle
+{
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]
+  {
+    { "ui_language", "zh" }, { "help_language", "zh" }, { "language", "zh" },
+    { "alphabet", new CharArrayWrapper(
+      new char[]{ 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+                  0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e,
+                  0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35,
+                  0xff36, 0xff37, 0xff38, 0xff39, 0xff3a }) },
+    { "tradAlphabet", new CharArrayWrapper(
+      new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+                  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+                  'Y', 'Z' }) },
+
+    //language orientation 
+    { "orientation", "LeftToRight" },
+
+    //language numbering    
+    { "numbering", "multiplicative-additive" },
+    { "multiplierOrder", "follows" },
+
+    // largest numerical value
+    //{"MaxNumericalValue", new Integer(100000000)},
+    //These would not be used for EN. Only used for traditional numbering   
+    { "numberGroups", new IntArrayWrapper(new int[]{ 1 }) },
+
+    // simplified chinese 
+    { "zero", new CharArrayWrapper(new char[]{ 0x96f6 }) },
+
+    //These only used for mutiplicative-additive numbering 
+    { "multiplier", new LongArrayWrapper(new long[]{ 100000000, 10000, 1000, 
+        100, 10 }) },
+    { "multiplierChar", new CharArrayWrapper(
+      new char[]{ 0x5104, 0x842c, 0x4edf, 0x4f70, 0x62fe }) },
+    { "digits", new CharArrayWrapper(
+      new char[]{ 0x58f9, 0x8cb3, 0x53c3, 0x8086, 0x4f0d, 0x9678, 0x67d2,
+                  0x634c, 0x7396 }) }, { "tables", new StringArrayWrapper(
+                      new String[]{ "digits" }) }
+  };
+  }
+}
diff --git a/src/main/java/org/apache/xpath/Arg.java b/src/main/java/org/apache/xpath/Arg.java
new file mode 100644
index 0000000..5582038
--- /dev/null
+++ b/src/main/java/org/apache/xpath/Arg.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Arg.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import org.apache.xml.utils.QName;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This class holds an instance of an argument on
+ * the stack. The value of the argument can be either an
+ * XObject or a String containing an expression.
+ * @xsl.usage internal
+ */
+public class Arg
+{
+
+  /** Field m_qname: The name of this argument, expressed as a QName
+   * (Qualified Name) object.
+   * @see getQName
+   * @see setQName
+   *  */
+  private QName m_qname;
+
+  /**
+   * Get the qualified name for this argument.
+   *
+   * @return QName object containing the qualified name
+   */
+  public final QName getQName()
+  {
+    return m_qname;
+  }
+
+  /**
+   * Set the qualified name for this argument.
+   *
+   * @param name QName object representing the new Qualified Name.
+   */
+  public final void setQName(QName name)
+  {
+    m_qname = name;
+  }
+
+  /** Field m_val: Stored XObject value of this argument
+   * @see #getVal()
+   * @see #setVal()
+   */
+  private XObject m_val;
+
+  /**
+   * Get the value for this argument.
+   *
+   * @return the argument's stored XObject value.
+   * @see #setVal(XObject)
+   */
+  public final XObject getVal()
+  {
+    return m_val;
+  }
+
+  /**
+   * Set the value of this argument.
+   *
+   * @param val an XObject representing the arguments's value.
+   * @see #getVal()
+   */
+  public final void setVal(XObject val)
+  {
+    m_val = val;
+  }
+  
+  /**
+   * Have the object release it's resources.
+   * Call only when the variable or argument is going out of scope.
+   */
+  public void detach()
+  {
+    if(null != m_val)
+    {
+      m_val.allowDetachToRelease(true);
+      m_val.detach();
+    }
+  }
+
+
+  /** Field m_expression: Stored expression value of this argument.
+   * @see #setExpression
+   * @see #getExpression
+   * */
+  private String m_expression;
+
+  /**
+   * Get the value expression for this argument.
+   *
+   * @return String containing the expression previously stored into this
+   * argument
+   * @see #setExpression
+   */
+  public String getExpression()
+  {
+    return m_expression;
+  }
+
+  /**
+   * Set the value expression for this argument.
+   *
+   * @param expr String containing the expression to be stored as this
+   * argument's value.
+   * @see #getExpression
+   */
+  public void setExpression(String expr)
+  {
+    m_expression = expr;
+  }
+
+  /** 
+   * True if this variable was added with an xsl:with-param or
+   * is added via setParameter.
+   */
+  private boolean m_isFromWithParam;
+
+  /**
+   * Tell if this variable is a parameter passed with a with-param or as 
+   * a top-level parameter.
+   */
+   public boolean isFromWithParam()
+   {
+    return m_isFromWithParam;
+   }
+
+  /** 
+   * True if this variable is currently visible.  To be visible,
+   * a variable needs to come either from xsl:variable or be 
+   * a "received" parameter, ie one for which an xsl:param has
+   * been encountered.
+   * Set at the time the object is constructed and updated as needed.
+   */
+  private boolean m_isVisible;
+
+  /**
+   * Tell if this variable is currently visible.
+   */
+   public boolean isVisible()
+   {
+    return m_isVisible;
+   }
+   
+  /**
+   * Update visibility status of this variable.
+   */
+   public void setIsVisible(boolean b)
+   {
+    m_isVisible = b;
+   }
+
+  /**
+   * Construct a dummy parameter argument, with no QName and no
+   * value (either expression string or value XObject). isVisible
+   * defaults to true.
+   */
+  public Arg()
+  {
+
+    m_qname = new QName("");
+    ;  // so that string compares can be done.
+    m_val = null;
+    m_expression = null;
+    m_isVisible = true;
+    m_isFromWithParam = false;
+  }
+
+  /**
+   * Construct a parameter argument that contains an expression.
+   *
+   * @param qname Name of the argument, expressed as a QName object.
+   * @param expression String to be stored as this argument's value expression.
+   * @param isFromWithParam True if this is a parameter variable.
+   */
+  public Arg(QName qname, String expression, boolean isFromWithParam)
+  {
+
+    m_qname = qname;
+    m_val = null;
+    m_expression = expression;
+    m_isFromWithParam = isFromWithParam;
+    m_isVisible = !isFromWithParam;
+  }
+
+  /**
+   * Construct a parameter argument which has an XObject value.
+   * isVisible defaults to true.
+   *
+   * @param qname Name of the argument, expressed as a QName object.
+   * @param val Value of the argument, expressed as an XObject
+   */
+  public Arg(QName qname, XObject val)
+  {
+
+    m_qname = qname;
+    m_val = val;
+    m_isVisible = true;
+    m_isFromWithParam = false;
+    m_expression = null;
+  }
+  
+  /**
+   * Equality function specialized for the variable name.  If the argument 
+   * is not a qname, it will deligate to the super class.
+   * 
+   * @param   obj   the reference object with which to compare.
+   * @return  <code>true</code> if this object is the same as the obj
+   *          argument; <code>false</code> otherwise.
+   */
+  public boolean equals(Object obj) 
+  {
+    if(obj instanceof QName)
+    {
+      return m_qname.equals(obj);
+    }
+    else
+      return super.equals(obj);
+  }
+
+  /**
+   * Construct a parameter argument.
+   *
+   * @param qname Name of the argument, expressed as a QName object.
+   * @param val Value of the argument, expressed as an XObject
+   * @param isFromWithParam True if this is a parameter variable.
+   */
+  public Arg(QName qname, XObject val, boolean isFromWithParam)
+  {
+
+    m_qname = qname;
+    m_val = val;
+    m_isFromWithParam = isFromWithParam;
+    m_isVisible = !isFromWithParam;
+    m_expression = null;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/CachedXPathAPI.java b/src/main/java/org/apache/xpath/CachedXPathAPI.java
new file mode 100644
index 0000000..7ecfdfd
--- /dev/null
+++ b/src/main/java/org/apache/xpath/CachedXPathAPI.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: CachedXPathAPI.java 524811 2007-04-02 15:51:59Z zongaro $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.apache.xpath.objects.XObject;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * The methods in this class are convenience methods into the
+ * low-level XPath API.
+ *
+ * These functions tend to be a little slow, since a number of objects must be
+ * created for each evaluation.  A faster way is to precompile the
+ * XPaths using the low-level API, and then just use the XPaths
+ * over and over.
+ *
+ * This is an alternative for the old XPathAPI class, which provided
+ * static methods for the purpose but had the drawback of
+ * instantiating a new XPathContext (and thus building a new DTMManager,
+ * and new DTMs) each time it was called. XPathAPIObject instead retains
+ * its context as long as the object persists, reusing the DTMs. This
+ * does have a downside: if you've changed your source document, you should
+ * obtain a new XPathAPIObject to continue searching it, since trying to use
+ * the old DTMs will probably yield bad results or malfunction outright... and
+ * the cached DTMs may consume memory until this object and its context are
+ * returned to the heap. Essentially, it's the caller's responsibility to
+ * decide when to discard the cache.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath">XPath Specification</a>
+ * */
+public class CachedXPathAPI
+{
+  /** XPathContext, and thus the document model system (DTMs), persists through multiple
+      calls to this object. This is set in the constructor.
+  */
+  protected XPathContext xpathSupport;
+
+  /**
+   * <p>Default constructor. Establishes its own {@link XPathContext}, and hence
+   * its own {@link org.apache.xml.dtm.DTMManager}.
+   * Good choice for simple uses.</p>
+   * <p>Note that any particular instance of {@link CachedXPathAPI} must not be
+   * operated upon by multiple threads without synchronization; we do
+   * not currently support multithreaded access to a single
+   * {@link org.apache.xml.dtm.DTM}.</p>
+   */
+  public CachedXPathAPI()
+  {
+    // Create an XPathContext that doesn't support pushing and popping of
+    // variable resolution scopes.  Sufficient for simple XPath 1.0 expressions.
+    xpathSupport = new XPathContext(false);
+  }
+  
+  /**
+   * <p>This constructor shares its {@link XPathContext} with a pre-existing
+   * {@link CachedXPathAPI}.  That allows sharing document models
+   * ({@link org.apache.xml.dtm.DTM}) and previously established location
+   * state.</p>
+   * <p>Note that the original {@link CachedXPathAPI} and the new one should
+   * not be operated upon concurrently; we do not support multithreaded access
+   * to a single {@link org.apache.xml.dtm.DTM} at this time.  Similarly,
+   * any particular instance of {@link CachedXPathAPI} must not be operated
+   * upon by multiple threads without synchronization.</p>
+   * <p>%REVIEW% Should this instead do a clone-and-reset on the XPathSupport object?</p>
+   *
+   */
+  public CachedXPathAPI(CachedXPathAPI priorXPathAPI)
+  {
+    xpathSupport = priorXPathAPI.xpathSupport;
+  }
+
+
+  /** Returns the XPathSupport object used in this CachedXPathAPI
+   *
+   * %REVIEW% I'm somewhat concerned about the loss of encapsulation
+   * this causes, but the xml-security folks say they need it.
+   * */
+  public XPathContext getXPathContext()
+  {
+    return this.xpathSupport;
+  }
+  
+
+  /**
+   * Use an XPath string to select a single node. XPath namespace
+   * prefixes are resolved from the context node, which may not
+   * be what you want (see the next method).
+   *
+   * @param contextNode The node to start searching from.
+   * @param str A valid XPath string.
+   * @return The first node found that matches the XPath, or null.
+   *
+   * @throws TransformerException
+   */
+  public  Node selectSingleNode(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectSingleNode(contextNode, str, contextNode);
+  }
+
+  /**
+   * Use an XPath string to select a single node.
+   * XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   * @param contextNode The node to start searching from.
+   * @param str A valid XPath string.
+   * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   * @return The first node found that matches the XPath, or null.
+   *
+   * @throws TransformerException
+   */
+  public  Node selectSingleNode(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Have the XObject return its result as a NodeSetDTM.
+    NodeIterator nl = selectNodeIterator(contextNode, str, namespaceNode);
+
+    // Return the first node, or null
+    return nl.nextNode();
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the contextNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public  NodeIterator selectNodeIterator(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectNodeIterator(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public  NodeIterator selectNodeIterator(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Execute the XPath, and have it return the result
+    XObject list = eval(contextNode, str, namespaceNode);
+
+    // Have the XObject return its result as a NodeSetDTM.                
+    return list.nodeset();
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the contextNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public  NodeList selectNodeList(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectNodeList(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public  NodeList selectNodeList(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Execute the XPath, and have it return the result
+    XObject list = eval(contextNode, str, namespaceNode);
+
+    // Return a NodeList.
+    return list.nodelist();
+  }
+
+  /**
+   *  Evaluate XPath string to an XObject.  Using this method,
+   *  XPath namespace prefixes will be resolved from the namespaceNode.
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *  @see org.apache.xpath.objects.XObject
+   *  @see org.apache.xpath.objects.XNull
+   *  @see org.apache.xpath.objects.XBoolean
+   *  @see org.apache.xpath.objects.XNumber
+   *  @see org.apache.xpath.objects.XString
+   *  @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public  XObject eval(Node contextNode, String str)
+          throws TransformerException
+  {
+    return eval(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Evaluate XPath string to an XObject. 
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *  The implementation of this is a little slow, since it creates
+   *  a number of objects each time it is called.  This could be optimized
+   *  to keep the same objects around, but then thread-safety issues would arise.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *  @see org.apache.xpath.objects.XObject
+   *  @see org.apache.xpath.objects.XNull
+   *  @see org.apache.xpath.objects.XBoolean
+   *  @see org.apache.xpath.objects.XNumber
+   *  @see org.apache.xpath.objects.XString
+   *  @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public  XObject eval(Node contextNode, String str, Node namespaceNode)
+          throws TransformerException
+  {
+
+    // Since we don't have a XML Parser involved here, install some default support
+    // for things like namespaces, etc.
+    // (Changed from: XPathContext xpathSupport = new XPathContext();
+    //    because XPathContext is weak in a number of areas... perhaps
+    //    XPathContext should be done away with.)
+
+    // Create an object to resolve namespace prefixes.
+    // XPath namespaces are resolved from the input context node's document element
+    // if it is a root node, or else the current context node (for lack of a better
+    // resolution space, given the simplicity of this sample code).
+    PrefixResolverDefault prefixResolver = new PrefixResolverDefault(
+      (namespaceNode.getNodeType() == Node.DOCUMENT_NODE)
+      ? ((Document) namespaceNode).getDocumentElement() : namespaceNode);
+
+    // Create the XPath object.
+    XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
+
+    // Execute the XPath, and have it return the result
+    // return xpath.execute(xpathSupport, contextNode, prefixResolver);
+    int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
+
+    return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
+  }
+
+  /**
+   *   Evaluate XPath string to an XObject.
+   *   XPath namespace prefixes are resolved from the namespaceNode.
+   *   The implementation of this is a little slow, since it creates
+   *   a number of objects each time it is called.  This could be optimized
+   *   to keep the same objects around, but then thread-safety issues would arise.
+   *
+   *   @param contextNode The node to start searching from.
+   *   @param str A valid XPath string.
+   *   @param prefixResolver Will be called if the parser encounters namespace
+   *                         prefixes, to resolve the prefixes to URLs.
+   *   @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *   @see org.apache.xpath.objects.XObject
+   *   @see org.apache.xpath.objects.XNull
+   *   @see org.apache.xpath.objects.XBoolean
+   *   @see org.apache.xpath.objects.XNumber
+   *   @see org.apache.xpath.objects.XString
+   *   @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public  XObject eval(
+          Node contextNode, String str, PrefixResolver prefixResolver)
+            throws TransformerException
+  {
+
+    // Since we don't have a XML Parser involved here, install some default support
+    // for things like namespaces, etc.
+    // (Changed from: XPathContext xpathSupport = new XPathContext();
+    //    because XPathContext is weak in a number of areas... perhaps
+    //    XPathContext should be done away with.)
+    // Create the XPath object.
+    XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
+
+    // Create an XPathContext that doesn't support pushing and popping of
+    // variable resolution scopes.  Sufficient for simple XPath 1.0 expressions.
+    XPathContext xpathSupport = new XPathContext(false);
+
+    // Execute the XPath, and have it return the result
+    int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
+
+    return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/Expression.java b/src/main/java/org/apache/xpath/Expression.java
new file mode 100644
index 0000000..2b38290
--- /dev/null
+++ b/src/main/java/org/apache/xpath/Expression.java
@@ -0,0 +1,589 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Expression.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+import org.xml.sax.ContentHandler;
+
+/**
+ * This abstract class serves as the base for all expression objects.  An
+ * Expression can be executed to return a {@link org.apache.xpath.objects.XObject},
+ * normally has a location within a document or DOM, can send error and warning
+ * events, and normally do not hold state and are meant to be immutable once
+ * construction has completed.  An exception to the immutibility rule is iterators
+ * and walkers, which must be cloned in order to be used -- the original must
+ * still be immutable.
+ */
+public abstract class Expression implements java.io.Serializable, ExpressionNode, XPathVisitable
+{
+    static final long serialVersionUID = 565665869777906902L;
+  /**
+   * The location where this expression was built from.  Need for diagnostic
+   *  messages. May be null.
+   *  @serial
+   */
+  private ExpressionNode m_parent;
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+    return false;
+  }
+  
+//  /**
+//   * Set the location where this expression was built from.
+//   *
+//   *
+//   * @param locator the location where this expression was built from, may be
+//   *                null.
+//   */
+//  public void setSourceLocator(SourceLocator locator)
+//  {
+//    m_slocator = locator;
+//  }
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param currentNode The currentNode.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public XObject execute(XPathContext xctxt, int currentNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // For now, the current node is already pushed.
+    return execute(xctxt);
+  }
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param currentNode The currentNode.
+   * @param dtm The DTM of the current node.
+   * @param expType The expanded type ID of the current node.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public XObject execute(
+          XPathContext xctxt, int currentNode, DTM dtm, int expType)
+            throws javax.xml.transform.TransformerException
+  {
+
+    // For now, the current node is already pushed.
+    return execute(xctxt);
+  }
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public abstract XObject execute(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException;
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression, but tell that a "safe" object doesn't have 
+   * to be returned.  The default implementation just calls execute(xctxt).
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param destructiveOK true if a "safe" object doesn't need to be returned.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public XObject execute(XPathContext xctxt, boolean destructiveOK)
+    throws javax.xml.transform.TransformerException
+  {
+  	return execute(xctxt);
+  }
+
+
+  /**
+   * Evaluate expression to a number.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @return The expression evaluated as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return execute(xctxt).num();
+  }
+
+  /**
+   * Evaluate expression to a boolean.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @return false
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return execute(xctxt).bool();
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @return The string this wraps or the empty string if null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XMLString xstr(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return execute(xctxt).xstr();
+  }
+
+  /**
+   * Tell if the expression is a nodeset expression.  In other words, tell
+   * if you can execute {@link #asNode(XPathContext) asNode} without an exception.
+   * @return true if the expression can be represented as a nodeset.
+   */
+  public boolean isNodesetExpr()
+  {
+    return false;
+  }
+
+  /**
+   * Return the first node out of the nodeset, if this expression is
+   * a nodeset expression.
+   * @param xctxt The XPath runtime context.
+   * @return the first node out of the nodeset, or DTM.NULL.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public int asNode(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+  	DTMIterator iter = execute(xctxt).iter();
+    return iter.nextNode();
+  }
+
+  /**
+   * Given an select expression and a context, evaluate the XPath
+   * and return the resulting iterator.
+   *
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   *
+   *
+   * @return A valid DTMIterator.
+   * @throws TransformerException thrown if the active ProblemListener decides
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public DTMIterator asIterator(XPathContext xctxt, int contextNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    try
+    {
+      xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
+
+      return execute(xctxt).iter();
+    }
+    finally
+    {
+      xctxt.popCurrentNodeAndExpression();
+    }
+  }
+  
+  /**
+   * Given an select expression and a context, evaluate the XPath
+   * and return the resulting iterator, but do not clone.
+   *
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   *
+   *
+   * @return A valid DTMIterator.
+   * @throws TransformerException thrown if the active ProblemListener decides
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public DTMIterator asIteratorRaw(XPathContext xctxt, int contextNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    try
+    {
+      xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
+
+      XNodeSet nodeset = (XNodeSet)execute(xctxt);
+      return nodeset.iterRaw();
+    }
+    finally
+    {
+      xctxt.popCurrentNodeAndExpression();
+    }
+  }
+
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * NEEDSDOC @param handler
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   * @throws org.xml.sax.SAXException
+   */
+  public void executeCharsToContentHandler(
+          XPathContext xctxt, ContentHandler handler)
+            throws javax.xml.transform.TransformerException,
+                   org.xml.sax.SAXException
+  {
+
+    XObject obj = execute(xctxt);
+
+    obj.dispatchCharactersEvents(handler);
+    obj.detach();
+  }
+
+  /**
+   * Tell if this expression returns a stable number that will not change during 
+   * iterations within the expression.  This is used to determine if a proximity 
+   * position predicate can indicate that no more searching has to occur.
+   * 
+   *
+   * @return true if the expression represents a stable number.
+   */
+  public boolean isStableNumber()
+  {
+    return false;
+  }
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list
+   * should be searched backwards for the first qualified name that
+   * corresponds to the variable reference qname.  The position of the
+   * QName in the vector from the start of the vector will be its position
+   * in the stack frame (but variables above the globalsTop value will need
+   * to be offset to the current stack frame).
+   * NEEDSDOC @param globalsSize
+   */
+  public abstract void fixupVariables(java.util.Vector vars, int globalsSize);
+  
+  /**
+   * Compare this object with another object and see 
+   * if they are equal, include the sub heararchy.
+   * 
+   * @param expr Another expression object.
+   * @return true if this objects class and the expr
+   * object's class are the same, and the data contained 
+   * within both objects are considered equal.
+   */
+  public abstract boolean deepEquals(Expression expr);
+  
+  /**
+   * This is a utility method to tell if the passed in 
+   * class is the same class as this.  It is to be used by
+   * the deepEquals method.  I'm bottlenecking it here 
+   * because I'm not totally confident that comparing the 
+   * class objects is the best way to do this.
+   * @return true of the passed in class is the exact same 
+   * class as this class.
+   */
+  protected final boolean isSameClass(Expression expr)
+  {
+  	if(null == expr)
+  	  return false;
+  	  
+  	return (getClass() == expr.getClass());
+  }
+
+  /**
+   * Warn the user of an problem.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param msg An error msgkey that corresponds to one of the conststants found
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to
+   *                              throw an exception.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void warn(XPathContext xctxt, String msg, Object[] args)
+          throws javax.xml.transform.TransformerException
+  {
+
+    java.lang.String fmsg = XSLMessages.createXPATHWarning(msg, args);
+
+    if (null != xctxt)
+    {
+      ErrorListener eh = xctxt.getErrorListener();
+
+      // TO DO: Need to get stylesheet Locator from here.
+      eh.warning(new TransformerException(fmsg, xctxt.getSAXLocator()));
+    }
+  }
+
+  /**
+   * Tell the user of an assertion error, and probably throw an
+   * exception.
+   *
+   * @param b  If false, a runtime exception will be thrown.
+   * @param msg The assertion message, which should be informative.
+   *
+   * @throws RuntimeException if the b argument is false.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void assertion(boolean b, java.lang.String msg)
+  {
+
+    if (!b)
+    {
+      java.lang.String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ msg });
+
+      throw new RuntimeException(fMsg);
+    }
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param msg An error msgkey that corresponds to one of the constants found
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to
+   *                              throw an exception.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void error(XPathContext xctxt, String msg, Object[] args)
+          throws javax.xml.transform.TransformerException
+  {
+
+    java.lang.String fmsg = XSLMessages.createXPATHMessage(msg, args);
+
+    if (null != xctxt)
+    {
+      ErrorListener eh = xctxt.getErrorListener();
+      TransformerException te = new TransformerException(fmsg, this);
+
+      eh.fatalError(te);
+    }
+  }
+  
+  /**
+   * Get the first non-Expression parent of this node.
+   * @return null or first ancestor that is not an Expression.
+   */
+  public ExpressionNode getExpressionOwner()
+  {
+  	ExpressionNode parent = exprGetParent();
+  	while((null != parent) && (parent instanceof Expression))
+  		parent = parent.exprGetParent();
+  	return parent;
+  }
+  
+  //=============== ExpressionNode methods ================
+  
+  /** This pair of methods are used to inform the node of its
+    parent. */
+  public void exprSetParent(ExpressionNode n)
+  {
+  	assertion(n != this, "Can not parent an expression to itself!");
+  	m_parent = n;
+  }
+  
+  public ExpressionNode exprGetParent()
+  {
+  	return m_parent;
+  }
+
+  /** This method tells the node to add its argument to the node's
+    list of children.  */
+  public void exprAddChild(ExpressionNode n, int i)
+  {
+  	assertion(false, "exprAddChild method not implemented!");
+  }
+
+  /** This method returns a child node.  The children are numbered
+     from zero, left to right. */
+  public ExpressionNode exprGetChild(int i)
+  {
+  	return null;
+  }
+
+  /** Return the number of children the node has. */
+  public int exprGetNumChildren()
+  {
+  	return 0;
+  }
+  
+  //=============== SourceLocator methods ================
+
+  /**
+   * Return the public identifier for the current document event.
+   *
+   * <p>The return value is the public identifier of the document
+   * entity or of the external parsed entity in which the markup that
+   * triggered the event appears.</p>
+   *
+   * @return A string containing the public identifier, or
+   *         null if none is available.
+   * @see #getSystemId
+   */
+  public String getPublicId()
+  {
+  	if(null == m_parent)
+  	  return null;
+  	return m_parent.getPublicId();
+  }
+
+  /**
+   * Return the system identifier for the current document event.
+   *
+   * <p>The return value is the system identifier of the document
+   * entity or of the external parsed entity in which the markup that
+   * triggered the event appears.</p>
+   *
+   * <p>If the system identifier is a URL, the parser must resolve it
+   * fully before passing it to the application.</p>
+   *
+   * @return A string containing the system identifier, or null
+   *         if none is available.
+   * @see #getPublicId
+   */
+  public String getSystemId()
+  {
+  	if(null == m_parent)
+  	  return null;
+  	return m_parent.getSystemId();
+  }
+
+  /**
+   * Return the line number where the current document event ends.
+   *
+   * <p><strong>Warning:</strong> The return value from the method
+   * is intended only as an approximation for the sake of error
+   * reporting; it is not intended to provide sufficient information
+   * to edit the character content of the original XML document.</p>
+   *
+   * <p>The return value is an approximation of the line number
+   * in the document entity or external parsed entity where the
+   * markup that triggered the event appears.</p>
+   *
+   * @return The line number, or -1 if none is available.
+   * @see #getColumnNumber
+   */
+  public int getLineNumber()
+  {
+  	if(null == m_parent)
+  	  return 0;
+  	return m_parent.getLineNumber();
+  }
+
+  /**
+   * Return the character position where the current document event ends.
+   *
+   * <p><strong>Warning:</strong> The return value from the method
+   * is intended only as an approximation for the sake of error
+   * reporting; it is not intended to provide sufficient information
+   * to edit the character content of the original XML document.</p>
+   *
+   * <p>The return value is an approximation of the column number
+   * in the document entity or external parsed entity where the
+   * markup that triggered the event appears.</p>
+   *
+   * @return The column number, or -1 if none is available.
+   * @see #getLineNumber
+   */
+  public int getColumnNumber()
+  {
+  	if(null == m_parent)
+  	  return 0;
+  	return m_parent.getColumnNumber();
+  }
+}
diff --git a/src/main/java/org/apache/xpath/ExpressionNode.java b/src/main/java/org/apache/xpath/ExpressionNode.java
new file mode 100644
index 0000000..d415867
--- /dev/null
+++ b/src/main/java/org/apache/xpath/ExpressionNode.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExpressionNode.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.SourceLocator;
+
+/**
+ * A class that implements this interface can construct expressions, 
+ * give information about child and parent expressions,
+ * and give the originating source information.  A class that implements 
+ * this interface does not lay any claim to being directly executable.
+ * 
+ * <p>Note: This interface should not be considered stable.  Only exprSetParent 
+ * and exprGetParent can be counted on to work reliably.  Work in progress.</p>
+ */
+public interface ExpressionNode extends SourceLocator
+{
+  /** This pair of methods are used to inform the node of its
+    parent. */
+  public void exprSetParent(ExpressionNode n);
+  public ExpressionNode exprGetParent();
+
+  /** This method tells the node to add its argument to the node's
+    list of children.  */
+  public void exprAddChild(ExpressionNode n, int i);
+
+  /** This method returns a child node.  The children are numbered
+     from zero, left to right. */
+  public ExpressionNode exprGetChild(int i);
+
+  /** Return the number of children the node has. */
+  public int exprGetNumChildren();
+}
+
diff --git a/src/main/java/org/apache/xpath/ExpressionOwner.java b/src/main/java/org/apache/xpath/ExpressionOwner.java
new file mode 100644
index 0000000..54c1b13
--- /dev/null
+++ b/src/main/java/org/apache/xpath/ExpressionOwner.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExpressionOwner.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+/**
+ * Classes that implement this interface own an expression, which 
+ * can be rewritten.
+ */
+public interface ExpressionOwner
+{
+  /**
+   * Get the raw Expression object that this class wraps.
+   *
+   * @return the raw Expression object, which should not normally be null.
+   */
+  public Expression getExpression();
+
+  /**
+   * Set the raw expression object for this object.
+   *
+   * @param exp the raw Expression object, which should not normally be null.
+   */
+  public void setExpression(Expression exp);
+
+
+}
+
diff --git a/src/main/java/org/apache/xpath/ExtensionsProvider.java b/src/main/java/org/apache/xpath/ExtensionsProvider.java
new file mode 100644
index 0000000..c49d14e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/ExtensionsProvider.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ExtensionsProvider.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import java.util.Vector;
+
+import org.apache.xpath.functions.FuncExtFunction;
+
+/**
+ * Interface that XPath objects can call to obtain access to an 
+ * ExtensionsTable.
+ * 
+ */
+public interface ExtensionsProvider
+{
+  /**
+   * Is the extension function available?
+   */
+  
+  public boolean functionAvailable(String ns, String funcName)
+          throws javax.xml.transform.TransformerException;
+  
+  /**
+   * Is the extension element available?
+   */
+  public boolean elementAvailable(String ns, String elemName)
+          throws javax.xml.transform.TransformerException;
+   
+  /**
+   * Execute the extension function.
+   */
+  public Object extFunction(String ns, String funcName, 
+                            Vector argVec, Object methodKey)
+            throws javax.xml.transform.TransformerException;
+
+  /**
+   * Execute the extension function.
+   */
+  public Object extFunction(FuncExtFunction extFunction, 
+                            Vector argVec)
+            throws javax.xml.transform.TransformerException;
+}
diff --git a/src/main/java/org/apache/xpath/FoundIndex.java b/src/main/java/org/apache/xpath/FoundIndex.java
new file mode 100644
index 0000000..67ec811
--- /dev/null
+++ b/src/main/java/org/apache/xpath/FoundIndex.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FoundIndex.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+/**
+ * Class to let us know when it's time to do
+ * a search from the parent because of indexing.
+ * @xsl.usage internal
+ */
+public class FoundIndex extends RuntimeException
+{
+    static final long serialVersionUID = -4643975335243078270L;
+
+  /**
+   * Constructor FoundIndex
+   *
+   */
+  public FoundIndex(){}
+}
diff --git a/src/main/java/org/apache/xpath/NodeSet.java b/src/main/java/org/apache/xpath/NodeSet.java
new file mode 100644
index 0000000..d1c7f80
--- /dev/null
+++ b/src/main/java/org/apache/xpath/NodeSet.java
@@ -0,0 +1,1370 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeSet.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.DOM2Helper;
+import org.apache.xpath.axes.ContextNodeList;
+import org.apache.xpath.res.XPATHErrorResources;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.NodeIterator;
+
+
+/**
+ * <p>The NodeSet class can act as either a NodeVector,
+ * NodeList, or NodeIterator.  However, in order for it to
+ * act as a NodeVector or NodeList, it's required that
+ * setShouldCacheNodes(true) be called before the first
+ * nextNode() is called, in order that nodes can be added
+ * as they are fetched.  Derived classes that implement iterators
+ * must override runTo(int index), in order that they may
+ * run the iteration to the given index. </p>
+ * 
+ * <p>Note that we directly implement the DOM's NodeIterator
+ * interface. We do not emulate all the behavior of the
+ * standard NodeIterator. In particular, we do not guarantee
+ * to present a "live view" of the document ... but in XSLT,
+ * the source document should never be mutated, so this should
+ * never be an issue.</p>
+ * 
+ * <p>Thought: Should NodeSet really implement NodeList and NodeIterator,
+ * or should there be specific subclasses of it which do so? The
+ * advantage of doing it all here is that all NodeSets will respond
+ * to the same calls; the disadvantage is that some of them may return
+ * less-than-enlightening results when you do so.</p>
+ * @xsl.usage advanced
+ */
+public class NodeSet
+        implements NodeList, NodeIterator, Cloneable, ContextNodeList
+{
+
+  /**
+   * Create an empty nodelist.
+   */
+  public NodeSet()
+  {
+    m_blocksize = 32;
+    m_mapSize = 0;
+  }
+
+  /**
+   * Create an empty, using the given block size.
+   *
+   * @param blocksize Size of blocks to allocate 
+   */
+  public NodeSet(int blocksize)
+  {
+    m_blocksize = blocksize;
+    m_mapSize = 0;
+  }
+
+  /**
+   * Create a NodeSet, and copy the members of the
+   * given nodelist into it.
+   *
+   * @param nodelist List of Nodes to be made members of the new set.
+   */
+  public NodeSet(NodeList nodelist)
+  {
+
+    this(32);
+
+    addNodes(nodelist);
+  }
+
+  /**
+   * Create a NodeSet, and copy the members of the
+   * given NodeSet into it.
+   *
+   * @param nodelist Set of Nodes to be made members of the new set.
+   */
+  public NodeSet(NodeSet nodelist)
+  {
+
+    this(32);
+
+    addNodes((NodeIterator) nodelist);
+  }
+
+  /**
+   * Create a NodeSet, and copy the members of the
+   * given NodeIterator into it.
+   *
+   * @param ni Iterator which yields Nodes to be made members of the new set.
+   */
+  public NodeSet(NodeIterator ni)
+  {
+
+    this(32);
+
+    addNodes(ni);
+  }
+
+  /**
+   * Create a NodeSet which contains the given Node.
+   *
+   * @param node Single node to be added to the new set.
+   */
+  public NodeSet(Node node)
+  {
+
+    this(32);
+
+    addNode(node);
+  }
+
+  /**
+   * @return The root node of the Iterator, as specified when it was created.
+   * For non-Iterator NodeSets, this will be null.
+   */
+  public Node getRoot()
+  {
+    return null;
+  }
+
+  /**
+   * Get a cloned Iterator, and reset its state to the beginning of the
+   * iteration.
+   *
+   * @return a new NodeSet of the same type, having the same state...
+   * except that the reset() operation has been called.
+   *
+   * @throws CloneNotSupportedException if this subclass of NodeSet
+   * does not support the clone() operation.
+   */
+  public NodeIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    NodeSet clone = (NodeSet) clone();
+
+    clone.reset();
+
+    return clone;
+  }
+
+  /**
+   * Reset the iterator. May have no effect on non-iterator Nodesets.
+   */
+  public void reset()
+  {
+    m_next = 0;
+  }
+
+  /**
+   *  This attribute determines which node types are presented via the
+   * iterator. The available set of constants is defined in the
+   * <code>NodeFilter</code> interface. For NodeSets, the mask has been
+   * hardcoded to show all nodes except EntityReference nodes, which have
+   * no equivalent in the XPath data model.
+   *
+   * @return integer used as a bit-array, containing flags defined in
+   * the DOM's NodeFilter class. The value will be 
+   * <code>SHOW_ALL & ~SHOW_ENTITY_REFERENCE</code>, meaning that
+   * only entity references are suppressed.
+   */
+  public int getWhatToShow()
+  {
+    return NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_ENTITY_REFERENCE;
+  }
+
+  /**
+   * The filter object used to screen nodes. Filters are applied to
+   * further reduce (and restructure) the NodeIterator's view of the
+   * document. In our case, we will be using hardcoded filters built
+   * into our iterators... but getFilter() is part of the DOM's 
+   * NodeIterator interface, so we have to support it.
+   *
+   * @return null, which is slightly misleading. True, there is no
+   * user-written filter object, but in fact we are doing some very
+   * sophisticated custom filtering. A DOM purist might suggest
+   * returning a placeholder object just to indicate that this is
+   * not going to return all nodes selected by whatToShow.
+   */
+  public NodeFilter getFilter()
+  {
+    return null;
+  }
+
+  /**
+   *  The value of this flag determines whether the children of entity
+   * reference nodes are visible to the iterator. If false, they will be
+   * skipped over.
+   * <br> To produce a view of the document that has entity references
+   * expanded and does not expose the entity reference node itself, use the
+   * whatToShow flags to hide the entity reference node and set
+   * expandEntityReferences to true when creating the iterator. To produce
+   * a view of the document that has entity reference nodes but no entity
+   * expansion, use the whatToShow flags to show the entity reference node
+   * and set expandEntityReferences to false.
+   *
+   * @return true for all iterators based on NodeSet, meaning that the
+   * contents of EntityRefrence nodes may be returned (though whatToShow
+   * says that the EntityReferences themselves are not shown.)
+   */
+  public boolean getExpandEntityReferences()
+  {
+    return true;
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   * @throws DOMException
+   *    INVALID_STATE_ERR: Raised if this method is called after the
+   *   <code>detach</code> method was invoked.
+   */
+  public Node nextNode() throws DOMException
+  {
+
+    if ((m_next) < this.size())
+    {
+      Node next = this.elementAt(m_next);
+
+      m_next++;
+
+      return next;
+    }
+    else
+      return null;
+  }
+
+  /**
+   *  Returns the previous node in the set and moves the position of the
+   * iterator backwards in the set.
+   * @return  The previous <code>Node</code> in the set being iterated over,
+   *   or<code>null</code> if there are no more members in that set.
+   * @throws DOMException
+   *    INVALID_STATE_ERR: Raised if this method is called after the
+   *   <code>detach</code> method was invoked.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a cached type, and hence doesn't know what the previous node was.
+   */
+  public Node previousNode() throws DOMException
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_CANNOT_ITERATE, null)); //"This NodeSet can not iterate to a previous node!");
+
+    if ((m_next - 1) > 0)
+    {
+      m_next--;
+
+      return this.elementAt(m_next);
+    }
+    else
+      return null;
+  }
+
+  /**
+   * Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   * <p>
+   * This operation is a no-op in NodeSet, and will not cause 
+   * INVALID_STATE_ERR to be raised by later operations.
+   * </p>
+   */
+  public void detach(){}
+
+  /**
+   * Tells if this NodeSet is "fresh", in other words, if
+   * the first nextNode() that is called will return the
+   * first node in the set.
+   *
+   * @return true if nextNode() would return the first node in the set,
+   * false if it would return a later one.
+   */
+  public boolean isFresh()
+  {
+    return (m_next == 0);
+  }
+
+  /**
+   * If an index is requested, NodeSet will call this method
+   * to run the iterator to the index.  By default this sets
+   * m_next to the index.  If the index argument is -1, this
+   * signals that the iterator should be run to the end.
+   *
+   * @param index Position to advance (or retreat) to, with
+   * 0 requesting the reset ("fresh") position and -1 (or indeed
+   * any out-of-bounds value) requesting the final position.
+   * @throws RuntimeException thrown if this NodeSet is not
+   * one of the types which supports indexing/counting.
+   */
+  public void runTo(int index)
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_CANNOT_INDEX, null)); //"This NodeSet can not do indexing or counting functions!");
+
+    if ((index >= 0) && (m_next < m_firstFree))
+      m_next = index;
+    else
+      m_next = m_firstFree - 1;
+  }
+
+  /**
+   * Returns the <code>index</code>th item in the collection. If
+   * <code>index</code> is greater than or equal to the number of nodes in
+   * the list, this returns <code>null</code>.
+   * 
+   * TODO: What happens if index is out of range?
+   * 
+   * @param index Index into the collection.
+   * @return The node at the <code>index</code>th position in the
+   *   <code>NodeList</code>, or <code>null</code> if that is not a valid
+   *   index.
+   */
+  public Node item(int index)
+  {
+
+    runTo(index);
+
+    return (Node) this.elementAt(index);
+  }
+
+  /**
+   * The number of nodes in the list. The range of valid child node indices is
+   * 0 to <code>length-1</code> inclusive. Note that this operation requires
+   * finding all the matching nodes, which may defeat attempts to defer
+   * that work.
+   *
+   * @return integer indicating how many nodes are represented by this list.
+   */
+  public int getLength()
+  {
+
+    runTo(-1);
+
+    return this.size();
+  }
+
+  /**
+   * Add a node to the NodeSet. Not all types of NodeSets support this
+   * operation
+   *
+   * @param n Node to be added
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNode(Node n)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    this.addElement(n);
+  }
+
+  /**
+   * Insert a node at a given position.
+   *
+   * @param n Node to be added
+   * @param pos Offset at which the node is to be inserted,
+   * with 0 being the first position.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void insertNode(Node n, int pos)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    insertElementAt(n, pos);
+  }
+
+  /**
+   * Remove a node.
+   *
+   * @param n Node to be added
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void removeNode(Node n)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    this.removeElement(n);
+  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  If a node is null, don't add it.
+   *
+   * @param nodelist List of nodes which should now be referenced by
+   * this NodeSet.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNodes(NodeList nodelist)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if (null != nodelist)  // defensive to fix a bug that Sanjiva reported.
+    {
+      int nChildren = nodelist.getLength();
+
+      for (int i = 0; i < nChildren; i++)
+      {
+        Node obj = nodelist.item(i);
+
+        if (null != obj)
+        {
+          addElement(obj);
+        }
+      }
+    }
+
+    // checkDups();
+  }
+
+  /**
+   * <p>Copy NodeList members into this nodelist, adding in
+   * document order.  Only genuine node references will be copied;
+   * nulls appearing in the source NodeSet will
+   * not be added to this one. </p>
+   * 
+   * <p> In case you're wondering why this function is needed: NodeSet
+   * implements both NodeIterator and NodeList. If this method isn't
+   * provided, Java can't decide which of those to use when addNodes()
+   * is invoked. Providing the more-explicit match avoids that
+   * ambiguity.)</p>
+   *
+   * @param ns NodeSet whose members should be merged into this NodeSet.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNodes(NodeSet ns)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    addNodes((NodeIterator) ns);
+  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  Null references are not added.
+   *
+   * @param iterator NodeIterator which yields the nodes to be added.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNodes(NodeIterator iterator)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if (null != iterator)  // defensive to fix a bug that Sanjiva reported.
+    {
+      Node obj;
+
+      while (null != (obj = iterator.nextNode()))
+      {
+        addElement(obj);
+      }
+    }
+
+    // checkDups();
+  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  If a node is null, don't add it.
+   *
+   * @param nodelist List of nodes to be added
+   * @param support The XPath runtime context.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNodesInDocOrder(NodeList nodelist, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    int nChildren = nodelist.getLength();
+
+    for (int i = 0; i < nChildren; i++)
+    {
+      Node node = nodelist.item(i);
+
+      if (null != node)
+      {
+        addNodeInDocOrder(node, support);
+      }
+    }
+  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  If a node is null, don't add it.
+   *
+   * @param iterator NodeIterator which yields the nodes to be added.
+   * @param support The XPath runtime context.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public void addNodesInDocOrder(NodeIterator iterator, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    Node node;
+
+    while (null != (node = iterator.nextNode()))
+    {
+      addNodeInDocOrder(node, support);
+    }
+  }
+
+  /**
+   * Add the node list to this node set in document order.
+   *
+   * @param start index.
+   * @param end index.
+   * @param testIndex index.
+   * @param nodelist The nodelist to add.
+   * @param support The XPath runtime context.
+   *
+   * @return false always.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  private boolean addNodesInDocOrder(int start, int end, int testIndex,
+                                     NodeList nodelist, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    boolean foundit = false;
+    int i;
+    Node node = nodelist.item(testIndex);
+
+    for (i = end; i >= start; i--)
+    {
+      Node child = (Node) elementAt(i);
+
+      if (child == node)
+      {
+        i = -2;  // Duplicate, suppress insert
+
+        break;
+      }
+
+      if (!DOM2Helper.isNodeAfter(node, child))
+      {
+        insertElementAt(node, i + 1);
+
+        testIndex--;
+
+        if (testIndex > 0)
+        {
+          boolean foundPrev = addNodesInDocOrder(0, i, testIndex, nodelist,
+                                                 support);
+
+          if (!foundPrev)
+          {
+            addNodesInDocOrder(i, size() - 1, testIndex, nodelist, support);
+          }
+        }
+
+        break;
+      }
+    }
+
+    if (i == -1)
+    {
+      insertElementAt(node, 0);
+    }
+
+    return foundit;
+  }
+
+  /**
+   * Add the node into a vector of nodes where it should occur in
+   * document order.
+   * @param node The node to be added.
+   * @param test true if we should test for doc order
+   * @param support The XPath runtime context.
+   * @return insertIndex.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public int addNodeInDocOrder(Node node, boolean test, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    int insertIndex = -1;
+
+    if (test)
+    {
+
+      // This needs to do a binary search, but a binary search 
+      // is somewhat tough because the sequence test involves 
+      // two nodes.
+      int size = size(), i;
+
+      for (i = size - 1; i >= 0; i--)
+      {
+        Node child = (Node) elementAt(i);
+
+        if (child == node)
+        {
+          i = -2;  // Duplicate, suppress insert
+
+          break;
+        }
+
+        if (!DOM2Helper.isNodeAfter(node, child))
+        {
+          break;
+        }
+      }
+
+      if (i != -2)
+      {
+        insertIndex = i + 1;
+
+        insertElementAt(node, insertIndex);
+      }
+    }
+    else
+    {
+      insertIndex = this.size();
+
+      boolean foundit = false;
+
+      for (int i = 0; i < insertIndex; i++)
+      {
+        if (this.item(i).equals(node))
+        {
+          foundit = true;
+
+          break;
+        }
+      }
+
+      if (!foundit)
+        addElement(node);
+    }
+
+    // checkDups();
+    return insertIndex;
+  }  // end addNodeInDocOrder(Vector v, Object obj)
+
+  /**
+   * Add the node into a vector of nodes where it should occur in
+   * document order.
+   * @param node The node to be added.
+   * @param support The XPath runtime context.
+   *
+   * @return The index where it was inserted.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a mutable type.
+   */
+  public int addNodeInDocOrder(Node node, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    return addNodeInDocOrder(node, true, support);
+  }  // end addNodeInDocOrder(Vector v, Object obj)
+
+
+  /** If this node is being used as an iterator, the next index that nextNode()
+   *  will return.  */
+  transient protected int m_next = 0;
+
+  /**
+   * Get the current position, which is one less than
+   * the next nextNode() call will retrieve.  i.e. if
+   * you call getCurrentPos() and the return is 0, the next
+   * fetch will take place at index 1.
+   *
+   * @return The the current position index.
+   */
+  public int getCurrentPos()
+  {
+    return m_next;
+  }
+
+  /**
+   * Set the current position in the node set.
+   * @param i Must be a valid index.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a cached type, and thus doesn't permit indexed access.
+   */
+  public void setCurrentPos(int i)
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_CANNOT_INDEX, null)); //"This NodeSet can not do indexing or counting functions!");
+
+    m_next = i;
+  }
+
+  /**
+   * Return the last fetched node.  Needed to support the UnionPathIterator.
+   *
+   * @return the last fetched node.
+   * @throws RuntimeException thrown if this NodeSet is not of 
+   * a cached type, and thus doesn't permit indexed access.
+   */
+  public Node getCurrentNode()
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_CANNOT_INDEX, null)); //"This NodeSet can not do indexing or counting functions!");
+
+    int saved = m_next;
+    Node n = (m_next < m_firstFree) ? elementAt(m_next) : null;
+    m_next = saved; // HACK: I think this is a bit of a hack.  -sb
+    return n;
+  }
+
+  /** True if this list can be mutated.  */
+  transient protected boolean m_mutable = true;
+
+  /** True if this list is cached.
+   *  @serial  */
+  transient protected boolean m_cacheNodes = true;
+
+  /**
+   * Get whether or not this is a cached node set.
+   *
+   *
+   * @return True if this list is cached.
+   */
+  public boolean getShouldCacheNodes()
+  {
+    return m_cacheNodes;
+  }
+
+  /**
+   * If setShouldCacheNodes(true) is called, then nodes will
+   * be cached.  They are not cached by default. This switch must
+   * be set before the first call to nextNode is made, to ensure
+   * that all nodes are cached.
+   *
+   * @param b true if this node set should be cached.
+   * @throws RuntimeException thrown if an attempt is made to
+   * request caching after we've already begun stepping through the
+   * nodes in this set.
+  */
+  public void setShouldCacheNodes(boolean b)
+  {
+
+    if (!isFresh())
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_CALL_SETSHOULDCACHENODE, null)); //"Can not call setShouldCacheNodes after nextNode has been called!");
+
+    m_cacheNodes = b;
+    m_mutable = true;
+  }
+  
+  
+  transient private int m_last = 0;
+  
+  public int getLast()
+  {
+    return m_last;
+  }
+  
+  public void setLast(int last)
+  {
+    m_last = last;
+  }
+  
+  /** Size of blocks to allocate.
+   *  @serial          */
+  private int m_blocksize;
+
+  /** Array of nodes this points to.
+   *  @serial          */
+  Node m_map[];
+
+  /** Number of nodes in this NodeVector.
+   *  @serial          */
+  protected int m_firstFree = 0;
+
+  /** Size of the array this points to.
+   *  @serial           */
+  private int m_mapSize;  // lazy initialization
+
+  /**
+   * Get a cloned LocPathIterator.
+   *
+   * @return A clone of this
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    NodeSet clone = (NodeSet) super.clone();
+
+    if ((null != this.m_map) && (this.m_map == clone.m_map))
+    {
+      clone.m_map = new Node[this.m_map.length];
+
+      System.arraycopy(this.m_map, 0, clone.m_map, 0, this.m_map.length);
+    }
+
+    return clone;
+  }
+
+  /**
+   * Get the length of the list.
+   *
+   * @return Number of nodes in this NodeVector
+   */
+  public int size()
+  {
+    return m_firstFree;
+  }
+
+  /**
+   * Append a Node onto the vector.
+   *
+   * @param value Node to add to the vector
+   */
+  public void addElement(Node value)
+  {
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if ((m_firstFree + 1) >= m_mapSize)
+    {
+      if (null == m_map)
+      {
+        m_map = new Node[m_blocksize];
+        m_mapSize = m_blocksize;
+      }
+      else
+      {
+        m_mapSize += m_blocksize;
+
+        Node newMap[] = new Node[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[m_firstFree] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Append a Node onto the vector.
+   *
+   * @param value Node to add to the vector
+   */
+  public final void push(Node value)
+  {
+
+    int ff = m_firstFree;
+
+    if ((ff + 1) >= m_mapSize)
+    {
+      if (null == m_map)
+      {
+        m_map = new Node[m_blocksize];
+        m_mapSize = m_blocksize;
+      }
+      else
+      {
+        m_mapSize += m_blocksize;
+
+        Node newMap[] = new Node[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, ff + 1);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[ff] = value;
+
+    ff++;
+
+    m_firstFree = ff;
+  }
+
+  /**
+   * Pop a node from the tail of the vector and return the result.
+   *
+   * @return the node at the tail of the vector
+   */
+  public final Node pop()
+  {
+
+    m_firstFree--;
+
+    Node n = m_map[m_firstFree];
+
+    m_map[m_firstFree] = null;
+
+    return n;
+  }
+
+  /**
+   * Pop a node from the tail of the vector and return the
+   * top of the stack after the pop.
+   *
+   * @return The top of the stack after it's been popped 
+   */
+  public final Node popAndTop()
+  {
+
+    m_firstFree--;
+
+    m_map[m_firstFree] = null;
+
+    return (m_firstFree == 0) ? null : m_map[m_firstFree - 1];
+  }
+
+  /**
+   * Pop a node from the tail of the vector.
+   */
+  public final void popQuick()
+  {
+
+    m_firstFree--;
+
+    m_map[m_firstFree] = null;
+  }
+
+  /**
+   * Return the node at the top of the stack without popping the stack.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node at the top of the stack or null if stack is empty.  
+   */
+  public final Node peepOrNull()
+  {
+    return ((null != m_map) && (m_firstFree > 0))
+           ? m_map[m_firstFree - 1] : null;
+  }
+
+  /**
+   * Push a pair of nodes into the stack.  
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param v1 First node to add to vector
+   * @param v2 Second node to add to vector
+   */
+  public final void pushPair(Node v1, Node v2)
+  {
+
+    if (null == m_map)
+    {
+      m_map = new Node[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+    else
+    {
+      if ((m_firstFree + 2) >= m_mapSize)
+      {
+        m_mapSize += m_blocksize;
+
+        Node newMap[] = new Node[m_mapSize];
+
+        System.arraycopy(m_map, 0, newMap, 0, m_firstFree);
+
+        m_map = newMap;
+      }
+    }
+
+    m_map[m_firstFree] = v1;
+    m_map[m_firstFree + 1] = v2;
+    m_firstFree += 2;
+  }
+
+  /**
+   * Pop a pair of nodes from the tail of the stack. 
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   */
+  public final void popPair()
+  {
+
+    m_firstFree -= 2;
+    m_map[m_firstFree] = null;
+    m_map[m_firstFree + 1] = null;
+  }
+
+  /**
+   * Set the tail of the stack to the given node.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param n Node to set at the tail of vector
+   */
+  public final void setTail(Node n)
+  {
+    m_map[m_firstFree - 1] = n;
+  }
+
+  /**
+   * Set the given node one position from the tail.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @param n Node to set
+   */
+  public final void setTailSub1(Node n)
+  {
+    m_map[m_firstFree - 2] = n;
+  }
+
+  /**
+   * Return the node at the tail of the vector without popping
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node at the tail of the vector
+   */
+  public final Node peepTail()
+  {
+    return m_map[m_firstFree - 1];
+  }
+
+  /**
+   * Return the node one position from the tail without popping.
+   * Special purpose method for TransformerImpl, pushElemTemplateElement.
+   * Performance critical.
+   *
+   * @return Node one away from the tail
+   */
+  public final Node peepTailSub1()
+  {
+    return m_map[m_firstFree - 2];
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * @param value Node to insert
+   * @param at Position where to insert
+   */
+  public void insertElementAt(Node value, int at)
+  {
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if (null == m_map)
+    {
+      m_map = new Node[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+    else if ((m_firstFree + 1) >= m_mapSize)
+    {
+      m_mapSize += m_blocksize;
+
+      Node newMap[] = new Node[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
+
+      m_map = newMap;
+    }
+
+    if (at <= (m_firstFree - 1))
+    {
+      System.arraycopy(m_map, at, m_map, at + 1, m_firstFree - at);
+    }
+
+    m_map[at] = value;
+
+    m_firstFree++;
+  }
+
+  /**
+   * Append the nodes to the list.
+   *
+   * @param nodes NodeVector to append to this list
+   */
+  public void appendNodes(NodeSet nodes)
+  {
+
+    int nNodes = nodes.size();
+
+    if (null == m_map)
+    {
+      m_mapSize = nNodes + m_blocksize;
+      m_map = new Node[m_mapSize];
+    }
+    else if ((m_firstFree + nNodes) >= m_mapSize)
+    {
+      m_mapSize += (nNodes + m_blocksize);
+
+      Node newMap[] = new Node[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + nNodes);
+
+      m_map = newMap;
+    }
+
+    System.arraycopy(nodes.m_map, 0, m_map, m_firstFree, nNodes);
+
+    m_firstFree += nNodes;
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   */
+  public void removeAllElements()
+  {
+
+    if (null == m_map)
+      return;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      m_map[i] = null;
+    }
+
+    m_firstFree = 0;
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s Node to remove from the list
+   *
+   * @return True if the node was successfully removed
+   */
+  public boolean removeElement(Node s)
+  {
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if (null == m_map)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      Node node = m_map[i];
+
+      if ((null != node) && node.equals(s))
+      {
+        if (i < m_firstFree - 1)
+          System.arraycopy(m_map, i + 1, m_map, i, m_firstFree - i - 1);
+
+        m_firstFree--;
+        m_map[m_firstFree] = null;
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i Index of node to remove
+   */
+  public void removeElementAt(int i)
+  {
+
+    if (null == m_map)
+      return;
+      
+    if (i >= m_firstFree)
+      throw new ArrayIndexOutOfBoundsException(i + " >= " + m_firstFree);
+    else if (i < 0)
+      throw new ArrayIndexOutOfBoundsException(i);
+
+    if (i < m_firstFree - 1)
+      System.arraycopy(m_map, i + 1, m_map, i, m_firstFree - i - 1);
+
+    m_firstFree--;
+    m_map[m_firstFree] = null;
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param node Node to set
+   * @param index Index of where to set the node
+   */
+  public void setElementAt(Node node, int index)
+  {
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESET_NOT_MUTABLE, null)); //"This NodeSet is not mutable!");
+
+    if (null == m_map)
+    {
+      m_map = new Node[m_blocksize];
+      m_mapSize = m_blocksize;
+    }
+
+    m_map[index] = node;
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i Index of node to get
+   *
+   * @return Node at specified index
+   */
+  public Node elementAt(int i)
+  {
+
+    if (null == m_map)
+      return null;
+
+    return m_map[i];
+  }
+
+  /**
+   * Tell if the table contains the given node.
+   *
+   * @param s Node to look for
+   *
+   * @return True if the given node was found.
+   */
+  public boolean contains(Node s)
+  {
+    runTo(-1);
+
+    if (null == m_map)
+      return false;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      Node node = m_map[i];
+
+      if ((null != node) && node.equals(s))
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for
+   * @param index Index of where to start the search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(Node elem, int index)
+  {
+    runTo(-1);
+
+    if (null == m_map)
+      return -1;
+
+    for (int i = index; i < m_firstFree; i++)
+    {
+      Node node = m_map[i];
+
+      if ((null != node) && node.equals(elem))
+        return i;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for 
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(Node elem)
+  {
+    runTo(-1);
+
+    if (null == m_map)
+      return -1;
+
+    for (int i = 0; i < m_firstFree; i++)
+    {
+      Node node = m_map[i];
+
+      if ((null != node) && node.equals(elem))
+        return i;
+    }
+
+    return -1;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/NodeSetDTM.java b/src/main/java/org/apache/xpath/NodeSetDTM.java
new file mode 100644
index 0000000..f92d505
--- /dev/null
+++ b/src/main/java/org/apache/xpath/NodeSetDTM.java
@@ -0,0 +1,1247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeSetDTM.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.NodeVector;
+import org.apache.xpath.res.XPATHErrorResources;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+
+/**
+ * <p>The NodeSetDTM class can act as either a NodeVector,
+ * NodeList, or NodeIterator.  However, in order for it to
+ * act as a NodeVector or NodeList, it's required that
+ * setShouldCacheNodes(true) be called before the first
+ * nextNode() is called, in order that nodes can be added
+ * as they are fetched.  Derived classes that implement iterators
+ * must override runTo(int index), in order that they may
+ * run the iteration to the given index. </p>
+ * 
+ * <p>Note that we directly implement the DOM's NodeIterator
+ * interface. We do not emulate all the behavior of the
+ * standard NodeIterator. In particular, we do not guarantee
+ * to present a "live view" of the document ... but in XSLT,
+ * the source document should never be mutated, so this should
+ * never be an issue.</p>
+ * 
+ * <p>Thought: Should NodeSetDTM really implement NodeList and NodeIterator,
+ * or should there be specific subclasses of it which do so? The
+ * advantage of doing it all here is that all NodeSetDTMs will respond
+ * to the same calls; the disadvantage is that some of them may return
+ * less-than-enlightening results when you do so.</p>
+ * @xsl.usage advanced
+ */
+public class NodeSetDTM extends NodeVector
+        implements /* NodeList, NodeIterator, */ DTMIterator, 
+        Cloneable
+{
+    static final long serialVersionUID = 7686480133331317070L;
+
+  /**
+   * Create an empty nodelist.
+   */
+  public NodeSetDTM(DTMManager dtmManager)
+  {
+    super();
+    m_manager = dtmManager;
+  }
+
+  /**
+   * Create an empty, using the given block size.
+   *
+   * @param blocksize Size of blocks to allocate 
+   * @param dummy pass zero for right now...
+   */
+  public NodeSetDTM(int blocksize, int dummy, DTMManager dtmManager)
+  {
+    super(blocksize);
+    m_manager = dtmManager;
+  }
+
+  // %TBD%
+//  /**
+//   * Create a NodeSetDTM, and copy the members of the
+//   * given nodelist into it.
+//   *
+//   * @param nodelist List of Nodes to be made members of the new set.
+//   */
+//  public NodeSetDTM(NodeList nodelist)
+//  {
+//
+//    super();
+//
+//    addNodes(nodelist);
+//  }
+
+  /**
+   * Create a NodeSetDTM, and copy the members of the
+   * given NodeSetDTM into it.
+   *
+   * @param nodelist Set of Nodes to be made members of the new set.
+   */
+  public NodeSetDTM(NodeSetDTM nodelist)
+  {
+
+    super();
+    m_manager = nodelist.getDTMManager();
+    m_root = nodelist.getRoot();
+
+    addNodes((DTMIterator) nodelist);
+  }
+
+  /**
+   * Create a NodeSetDTM, and copy the members of the
+   * given DTMIterator into it.
+   *
+   * @param ni Iterator which yields Nodes to be made members of the new set.
+   */
+  public NodeSetDTM(DTMIterator ni)
+  {
+
+    super();
+
+    m_manager = ni.getDTMManager();
+    m_root = ni.getRoot();
+    addNodes(ni);
+  }
+  
+  /**
+   * Create a NodeSetDTM, and copy the members of the
+   * given DTMIterator into it.
+   *
+   * @param iterator Iterator which yields Nodes to be made members of the new set.
+   */
+  public NodeSetDTM(NodeIterator iterator, XPathContext xctxt)
+  {
+
+    super();
+
+    Node node;
+    m_manager = xctxt.getDTMManager();
+
+    while (null != (node = iterator.nextNode()))
+    {
+      int handle = xctxt.getDTMHandleFromNode(node);
+      addNodeInDocOrder(handle, xctxt);
+    }
+  }
+  
+  /**
+   * Create a NodeSetDTM, and copy the members of the
+   * given DTMIterator into it.
+   *
+   */
+  public NodeSetDTM(NodeList nodeList, XPathContext xctxt)
+  {
+
+    super();
+
+    m_manager = xctxt.getDTMManager();
+
+    int n = nodeList.getLength();
+    for (int i = 0; i < n; i++) 
+    {
+      Node node = nodeList.item(i);
+      int handle = xctxt.getDTMHandleFromNode(node);
+      // Do not reorder or strip duplicate nodes from the given DOM nodelist
+      addNode(handle); // addNodeInDocOrder(handle, xctxt);  
+    } 
+  }
+
+
+  /**
+   * Create a NodeSetDTM which contains the given Node.
+   *
+   * @param node Single node to be added to the new set.
+   */
+  public NodeSetDTM(int node, DTMManager dtmManager)
+  {
+
+    super();
+    m_manager = dtmManager;
+
+    addNode(node);
+  }
+  
+  /**
+   * Set the environment in which this iterator operates, which should provide:
+   * a node (the context node... same value as "root" defined below) 
+   * a pair of non-zero positive integers (the context position and the context size) 
+   * a set of variable bindings 
+   * a function library 
+   * the set of namespace declarations in scope for the expression.
+   * 
+   * <p>At this time the exact implementation of this environment is application 
+   * dependent.  Probably a proper interface will be created fairly soon.</p>
+   * 
+   * @param environment The environment object.
+   */
+  public void setEnvironment(Object environment)
+  {
+    // no-op
+  }
+
+
+  /**
+   * @return The root node of the Iterator, as specified when it was created.
+   * For non-Iterator NodeSetDTMs, this will be null.
+   */
+  public int getRoot()
+  {
+    if(DTM.NULL == m_root)
+    {
+      if(size() > 0)
+        return item(0);
+      else
+        return DTM.NULL;
+    }
+    else
+      return m_root;
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    // no-op, I guess...  (-sb)
+  }
+
+  /**
+   * Clone this NodeSetDTM.
+   * At this time, we only expect this to be used with LocPathIterators;
+   * it may not work with other kinds of NodeSetDTMs.
+   *
+   * @return a new NodeSetDTM of the same type, having the same state...
+   * though unless overridden in the subclasses, it may not copy all
+   * the state information.
+   *
+   * @throws CloneNotSupportedException if this subclass of NodeSetDTM
+   * does not support the clone() operation.
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    NodeSetDTM clone = (NodeSetDTM) super.clone();
+
+    return clone;
+  }
+
+  /**
+   * Get a cloned Iterator, and reset its state to the beginning of the
+   * iteration.
+   *
+   * @return a new NodeSetDTM of the same type, having the same state...
+   * except that the reset() operation has been called.
+   *
+   * @throws CloneNotSupportedException if this subclass of NodeSetDTM
+   * does not support the clone() operation.
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    NodeSetDTM clone = (NodeSetDTM) clone();
+
+    clone.reset();
+
+    return clone;
+  }
+
+  /**
+   * Reset the iterator. May have no effect on non-iterator Nodesets.
+   */
+  public void reset()
+  {
+    m_next = 0;
+  }
+
+  /**
+   *  This attribute determines which node types are presented via the
+   * iterator. The available set of constants is defined in the
+   * <code>DTMFilter</code> interface. For NodeSetDTMs, the mask has been
+   * hardcoded to show all nodes except EntityReference nodes, which have
+   * no equivalent in the XPath data model.
+   *
+   * @return integer used as a bit-array, containing flags defined in
+   * the DOM's DTMFilter class. The value will be 
+   * <code>SHOW_ALL & ~SHOW_ENTITY_REFERENCE</code>, meaning that
+   * only entity references are suppressed.
+   */
+  public int getWhatToShow()
+  {
+    return DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE;
+  }
+
+  /**
+   * The filter object used to screen nodes. Filters are applied to
+   * further reduce (and restructure) the DTMIterator's view of the
+   * document. In our case, we will be using hardcoded filters built
+   * into our iterators... but getFilter() is part of the DOM's 
+   * DTMIterator interface, so we have to support it.
+   *
+   * @return null, which is slightly misleading. True, there is no
+   * user-written filter object, but in fact we are doing some very
+   * sophisticated custom filtering. A DOM purist might suggest
+   * returning a placeholder object just to indicate that this is
+   * not going to return all nodes selected by whatToShow.
+   */
+  public DTMFilter getFilter()
+  {
+    return null;
+  }
+
+  /**
+   *  The value of this flag determines whether the children of entity
+   * reference nodes are visible to the iterator. If false, they will be
+   * skipped over.
+   * <br> To produce a view of the document that has entity references
+   * expanded and does not expose the entity reference node itself, use the
+   * whatToShow flags to hide the entity reference node and set
+   * expandEntityReferences to true when creating the iterator. To produce
+   * a view of the document that has entity reference nodes but no entity
+   * expansion, use the whatToShow flags to show the entity reference node
+   * and set expandEntityReferences to false.
+   *
+   * @return true for all iterators based on NodeSetDTM, meaning that the
+   * contents of EntityRefrence nodes may be returned (though whatToShow
+   * says that the EntityReferences themselves are not shown.)
+   */
+  public boolean getExpandEntityReferences()
+  {
+    return true;
+  }
+  
+  /**
+   * Get an instance of a DTM that "owns" a node handle.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTM using just the iterator.
+   *
+   * @param nodeHandle the nodeHandle.
+   *
+   * @return a non-null DTM reference.
+   */
+  public DTM getDTM(int nodeHandle)
+  {
+    
+    return m_manager.getDTM(nodeHandle);
+  }
+  
+  /* An instance of the DTMManager. */
+  DTMManager m_manager;
+  
+  /**
+   * Get an instance of the DTMManager.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTMManager using just the iterator.
+   *
+   * @return a non-null DTMManager reference.
+   */
+  public DTMManager getDTMManager()
+  {
+    
+    return m_manager;
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a DTMIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>DTM.NULL</code> if there are no more members in that set.
+   * @throws DOMException
+   *    INVALID_STATE_ERR: Raised if this method is called after the
+   *   <code>detach</code> method was invoked.
+   */
+  public int nextNode()
+  {
+
+    if ((m_next) < this.size())
+    {
+      int next = this.elementAt(m_next);
+
+      m_next++;
+
+      return next;
+    }
+    else
+      return DTM.NULL;
+  }
+
+  /**
+   *  Returns the previous node in the set and moves the position of the
+   * iterator backwards in the set.
+   * @return  The previous <code>Node</code> in the set being iterated over,
+   *   or<code>DTM.NULL</code> if there are no more members in that set.
+   * @throws DOMException
+   *    INVALID_STATE_ERR: Raised if this method is called after the
+   *   <code>detach</code> method was invoked.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a cached type, and hence doesn't know what the previous node was.
+   */
+  public int previousNode()
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_ITERATE, null)); //"This NodeSetDTM can not iterate to a previous node!");
+
+    if ((m_next - 1) > 0)
+    {
+      m_next--;
+
+      return this.elementAt(m_next);
+    }
+    else
+      return DTM.NULL;
+  }
+
+  /**
+   * Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   * <p>
+   * This operation is a no-op in NodeSetDTM, and will not cause 
+   * INVALID_STATE_ERR to be raised by later operations.
+   * </p>
+   */
+  public void detach(){}
+  
+  /**
+   * Specify if it's OK for detach to release the iterator for reuse.
+   * 
+   * @param allowRelease true if it is OK for detach to release this iterator 
+   * for pooling.
+   */
+  public void allowDetachToRelease(boolean allowRelease)
+  {
+    // no action for right now.
+  }
+
+
+  /**
+   * Tells if this NodeSetDTM is "fresh", in other words, if
+   * the first nextNode() that is called will return the
+   * first node in the set.
+   *
+   * @return true if nextNode() would return the first node in the set,
+   * false if it would return a later one.
+   */
+  public boolean isFresh()
+  {
+    return (m_next == 0);
+  }
+
+  /**
+   * If an index is requested, NodeSetDTM will call this method
+   * to run the iterator to the index.  By default this sets
+   * m_next to the index.  If the index argument is -1, this
+   * signals that the iterator should be run to the end.
+   *
+   * @param index Position to advance (or retreat) to, with
+   * 0 requesting the reset ("fresh") position and -1 (or indeed
+   * any out-of-bounds value) requesting the final position.
+   * @throws RuntimeException thrown if this NodeSetDTM is not
+   * one of the types which supports indexing/counting.
+   */
+  public void runTo(int index)
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_INDEX, null)); //"This NodeSetDTM can not do indexing or counting functions!");
+
+    if ((index >= 0) && (m_next < m_firstFree))
+      m_next = index;
+    else
+      m_next = m_firstFree - 1;
+  }
+
+  /**
+   * Returns the <code>index</code>th item in the collection. If
+   * <code>index</code> is greater than or equal to the number of nodes in
+   * the list, this returns <code>null</code>.
+   * 
+   * TODO: What happens if index is out of range?
+   * 
+   * @param index Index into the collection.
+   * @return The node at the <code>index</code>th position in the
+   *   <code>NodeList</code>, or <code>null</code> if that is not a valid
+   *   index.
+   */
+  public int item(int index)
+  {
+
+    runTo(index);
+
+    return this.elementAt(index);
+  }
+
+  /**
+   * The number of nodes in the list. The range of valid child node indices is
+   * 0 to <code>length-1</code> inclusive. Note that this operation requires
+   * finding all the matching nodes, which may defeat attempts to defer
+   * that work.
+   *
+   * @return integer indicating how many nodes are represented by this list.
+   */
+  public int getLength()
+  {
+
+    runTo(-1);
+
+    return this.size();
+  }
+
+  /**
+   * Add a node to the NodeSetDTM. Not all types of NodeSetDTMs support this
+   * operation
+   *
+   * @param n Node to be added
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void addNode(int n)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    this.addElement(n);
+  }
+
+  /**
+   * Insert a node at a given position.
+   *
+   * @param n Node to be added
+   * @param pos Offset at which the node is to be inserted,
+   * with 0 being the first position.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void insertNode(int n, int pos)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    insertElementAt(n, pos);
+  }
+
+  /**
+   * Remove a node.
+   *
+   * @param n Node to be added
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void removeNode(int n)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    this.removeElement(n);
+  }
+
+  // %TBD%
+//  /**
+//   * Copy NodeList members into this nodelist, adding in
+//   * document order.  If a node is null, don't add it.
+//   *
+//   * @param nodelist List of nodes which should now be referenced by
+//   * this NodeSetDTM.
+//   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+//   * a mutable type.
+//   */
+//  public void addNodes(NodeList nodelist)
+//  {
+//
+//    if (!m_mutable)
+//      throw new RuntimeException("This NodeSetDTM is not mutable!");
+//
+//    if (null != nodelist)  // defensive to fix a bug that Sanjiva reported.
+//    {
+//      int nChildren = nodelist.getLength();
+//
+//      for (int i = 0; i < nChildren; i++)
+//      {
+//        int obj = nodelist.item(i);
+//
+//        if (null != obj)
+//        {
+//          addElement(obj);
+//        }
+//      }
+//    }
+//
+//    // checkDups();
+//  }
+
+  // %TBD%
+//  /**
+//   * <p>Copy NodeList members into this nodelist, adding in
+//   * document order.  Only genuine node references will be copied;
+//   * nulls appearing in the source NodeSetDTM will
+//   * not be added to this one. </p>
+//   * 
+//   * <p> In case you're wondering why this function is needed: NodeSetDTM
+//   * implements both DTMIterator and NodeList. If this method isn't
+//   * provided, Java can't decide which of those to use when addNodes()
+//   * is invoked. Providing the more-explicit match avoids that
+//   * ambiguity.)</p>
+//   *
+//   * @param ns NodeSetDTM whose members should be merged into this NodeSetDTM.
+//   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+//   * a mutable type.
+//   */
+//  public void addNodes(NodeSetDTM ns)
+//  {
+//
+//    if (!m_mutable)
+//      throw new RuntimeException("This NodeSetDTM is not mutable!");
+//
+//    addNodes((DTMIterator) ns);
+//  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  Null references are not added.
+   *
+   * @param iterator DTMIterator which yields the nodes to be added.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void addNodes(DTMIterator iterator)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    if (null != iterator)  // defensive to fix a bug that Sanjiva reported.
+    {
+      int obj;
+
+      while (DTM.NULL != (obj = iterator.nextNode()))
+      {
+        addElement(obj);
+      }
+    }
+
+    // checkDups();
+  }
+
+  // %TBD%
+//  /**
+//   * Copy NodeList members into this nodelist, adding in
+//   * document order.  If a node is null, don't add it.
+//   *
+//   * @param nodelist List of nodes to be added
+//   * @param support The XPath runtime context.
+//   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+//   * a mutable type.
+//   */
+//  public void addNodesInDocOrder(NodeList nodelist, XPathContext support)
+//  {
+//
+//    if (!m_mutable)
+//      throw new RuntimeException("This NodeSetDTM is not mutable!");
+//
+//    int nChildren = nodelist.getLength();
+//
+//    for (int i = 0; i < nChildren; i++)
+//    {
+//      int node = nodelist.item(i);
+//
+//      if (null != node)
+//      {
+//        addNodeInDocOrder(node, support);
+//      }
+//    }
+//  }
+
+  /**
+   * Copy NodeList members into this nodelist, adding in
+   * document order.  If a node is null, don't add it.
+   *
+   * @param iterator DTMIterator which yields the nodes to be added.
+   * @param support The XPath runtime context.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void addNodesInDocOrder(DTMIterator iterator, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    int node;
+
+    while (DTM.NULL != (node = iterator.nextNode()))
+    {
+      addNodeInDocOrder(node, support);
+    }
+  }
+
+  // %TBD%
+//  /**
+//   * Add the node list to this node set in document order.
+//   *
+//   * @param start index.
+//   * @param end index.
+//   * @param testIndex index.
+//   * @param nodelist The nodelist to add.
+//   * @param support The XPath runtime context.
+//   *
+//   * @return false always.
+//   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+//   * a mutable type.
+//   */
+//  private boolean addNodesInDocOrder(int start, int end, int testIndex,
+//                                     NodeList nodelist, XPathContext support)
+//  {
+//
+//    if (!m_mutable)
+//      throw new RuntimeException("This NodeSetDTM is not mutable!");
+//
+//    boolean foundit = false;
+//    int i;
+//    int node = nodelist.item(testIndex);
+//
+//    for (i = end; i >= start; i--)
+//    {
+//      int child = elementAt(i);
+//
+//      if (child == node)
+//      {
+//        i = -2;  // Duplicate, suppress insert
+//
+//        break;
+//      }
+//
+//      if (!support.getDOMHelper().isNodeAfter(node, child))
+//      {
+//        insertElementAt(node, i + 1);
+//
+//        testIndex--;
+//
+//        if (testIndex > 0)
+//        {
+//          boolean foundPrev = addNodesInDocOrder(0, i, testIndex, nodelist,
+//                                                 support);
+//
+//          if (!foundPrev)
+//          {
+//            addNodesInDocOrder(i, size() - 1, testIndex, nodelist, support);
+//          }
+//        }
+//
+//        break;
+//      }
+//    }
+//
+//    if (i == -1)
+//    {
+//      insertElementAt(node, 0);
+//    }
+//
+//    return foundit;
+//  }
+
+  /**
+   * Add the node into a vector of nodes where it should occur in
+   * document order.
+   * @param node The node to be added.
+   * @param test true if we should test for doc order
+   * @param support The XPath runtime context.
+   * @return insertIndex.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public int addNodeInDocOrder(int node, boolean test, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    int insertIndex = -1;
+
+    if (test)
+    {
+
+      // This needs to do a binary search, but a binary search 
+      // is somewhat tough because the sequence test involves 
+      // two nodes.
+      int size = size(), i;
+
+      for (i = size - 1; i >= 0; i--)
+      {
+        int child = elementAt(i);
+
+        if (child == node)
+        {
+          i = -2;  // Duplicate, suppress insert
+
+          break;
+        }
+
+        DTM dtm = support.getDTM(node);
+        if (!dtm.isNodeAfter(node, child))
+        {
+          break;
+        }
+      }
+
+      if (i != -2)
+      {
+        insertIndex = i + 1;
+
+        insertElementAt(node, insertIndex);
+      }
+    }
+    else
+    {
+      insertIndex = this.size();
+
+      boolean foundit = false;
+
+      for (int i = 0; i < insertIndex; i++)
+      {
+        if (i == node)
+        {
+          foundit = true;
+
+          break;
+        }
+      }
+
+      if (!foundit)
+        addElement(node);
+    }
+
+    // checkDups();
+    return insertIndex;
+  }  // end addNodeInDocOrder(Vector v, Object obj)
+
+  /**
+   * Add the node into a vector of nodes where it should occur in
+   * document order.
+   * @param node The node to be added.
+   * @param support The XPath runtime context.
+   *
+   * @return The index where it was inserted.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public int addNodeInDocOrder(int node, XPathContext support)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    return addNodeInDocOrder(node, true, support);
+  }  // end addNodeInDocOrder(Vector v, Object obj)
+
+  /**
+   * Get the length of the list.
+   *
+   * @return The size of this node set.
+   */
+  public int size()
+  {
+    return super.size();
+  }
+
+  /**
+   * Append a Node onto the vector.
+   *
+   * @param value The node to be added.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void addElement(int value)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.addElement(value);
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   *
+   * @param value The node to be inserted.
+   * @param at The index where the insert should occur.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void insertElementAt(int value, int at)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.insertElementAt(value, at);
+  }
+
+  /**
+   * Append the nodes to the list.
+   *
+   * @param nodes The nodes to be appended to this node set.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void appendNodes(NodeVector nodes)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.appendNodes(nodes);
+  }
+
+  /**
+   * Inserts the specified node in this vector at the specified index.
+   * Each component in this vector with an index greater or equal to
+   * the specified index is shifted upward to have an index one greater
+   * than the value it had previously.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void removeAllElements()
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.removeAllElements();
+  }
+
+  /**
+   * Removes the first occurrence of the argument from this vector.
+   * If the object is found in this vector, each component in the vector
+   * with an index greater or equal to the object's index is shifted
+   * downward to have an index one smaller than the value it had
+   * previously.
+   *
+   * @param s The node to be removed.
+   *
+   * @return True if the node was successfully removed
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public boolean removeElement(int s)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    return super.removeElement(s);
+  }
+
+  /**
+   * Deletes the component at the specified index. Each component in
+   * this vector with an index greater or equal to the specified
+   * index is shifted downward to have an index one smaller than
+   * the value it had previously.
+   *
+   * @param i The index of the node to be removed.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void removeElementAt(int i)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.removeElementAt(i);
+  }
+
+  /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param node  The node to be set.
+   * @param index The index of the node to be replaced.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void setElementAt(int node, int index)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.setElementAt(node, index);
+  }
+  
+  /**
+   * Same as setElementAt.
+   *
+   * @param node  The node to be set.
+   * @param index The index of the node to be replaced.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+  public void setItem(int node, int index)
+  {
+
+    if (!m_mutable)
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_NOT_MUTABLE, null)); //"This NodeSetDTM is not mutable!");
+
+    super.setElementAt(node, index);
+  }
+
+  /**
+   * Get the nth element.
+   *
+   * @param i The index of the requested node.
+   *
+   * @return Node at specified index.
+   */
+  public int elementAt(int i)
+  {
+
+    runTo(i);
+
+    return super.elementAt(i);
+  }
+  
+  /**
+   * Tell if the table contains the given node.
+   *
+   * @param s Node to look for
+   *
+   * @return True if the given node was found.
+   */
+  public boolean contains(int s)
+  {
+
+    runTo(-1);
+
+    return super.contains(s);
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for
+   * @param index Index of where to start the search
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem, int index)
+  {
+
+    runTo(-1);
+
+    return super.indexOf(elem, index);
+  }
+
+  /**
+   * Searches for the first occurence of the given argument,
+   * beginning the search at index, and testing for equality
+   * using the equals method.
+   *
+   * @param elem Node to look for 
+   * @return the index of the first occurrence of the object
+   * argument in this vector at position index or later in the
+   * vector; returns -1 if the object is not found.
+   */
+  public int indexOf(int elem)
+  {
+
+    runTo(-1);
+
+    return super.indexOf(elem);
+  }
+
+  /** If this node is being used as an iterator, the next index that nextNode()
+   *  will return.  */
+  transient protected int m_next = 0;
+
+  /**
+   * Get the current position, which is one less than
+   * the next nextNode() call will retrieve.  i.e. if
+   * you call getCurrentPos() and the return is 0, the next
+   * fetch will take place at index 1.
+   *
+   * @return The the current position index.
+   */
+  public int getCurrentPos()
+  {
+    return m_next;
+  }
+
+  /**
+   * Set the current position in the node set.
+   * @param i Must be a valid index.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a cached type, and thus doesn't permit indexed access.
+   */
+  public void setCurrentPos(int i)
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_INDEX, null)); //"This NodeSetDTM can not do indexing or counting functions!");
+
+    m_next = i;
+  }
+
+  /**
+   * Return the last fetched node.  Needed to support the UnionPathIterator.
+   *
+   * @return the last fetched node.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a cached type, and thus doesn't permit indexed access.
+   */
+  public int getCurrentNode()
+  {
+
+    if (!m_cacheNodes)
+      throw new RuntimeException(
+        "This NodeSetDTM can not do indexing or counting functions!");
+
+    int saved = m_next;
+    // because nextNode always increments
+    // But watch out for copy29, where the root iterator didn't
+    // have nextNode called on it.
+    int current = (m_next > 0) ? m_next-1 : m_next; 
+    int n = (current < m_firstFree) ? elementAt(current) : DTM.NULL;
+    m_next = saved; // HACK: I think this is a bit of a hack.  -sb
+    return n;
+  }
+
+  /** True if this list can be mutated.  */
+  transient protected boolean m_mutable = true;
+
+  /** True if this list is cached.
+   *  @serial  */
+  transient protected boolean m_cacheNodes = true;
+  
+  /** The root of the iteration, if available. */
+  protected int m_root = DTM.NULL;
+
+  /**
+   * Get whether or not this is a cached node set.
+   *
+   *
+   * @return True if this list is cached.
+   */
+  public boolean getShouldCacheNodes()
+  {
+    return m_cacheNodes;
+  }
+
+  /**
+   * If setShouldCacheNodes(true) is called, then nodes will
+   * be cached.  They are not cached by default. This switch must
+   * be set before the first call to nextNode is made, to ensure
+   * that all nodes are cached.
+   *
+   * @param b true if this node set should be cached.
+   * @throws RuntimeException thrown if an attempt is made to
+   * request caching after we've already begun stepping through the
+   * nodes in this set.
+  */
+  public void setShouldCacheNodes(boolean b)
+  {
+
+    if (!isFresh())
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_CALL_SETSHOULDCACHENODE, null)); //"Can not call setShouldCacheNodes after nextNode has been called!");
+
+    m_cacheNodes = b;
+    m_mutable = true;
+  }
+  
+  /**
+   * Tells if this iterator can have nodes added to it or set via 
+   * the <code>setItem(int node, int index)</code> method.
+   * 
+   * @return True if the nodelist can be mutated.
+   */
+  public boolean isMutable()
+  {
+    return m_mutable;
+  }
+  
+  transient private int m_last = 0;
+  
+  public int getLast()
+  {
+    return m_last;
+  }
+  
+  public void setLast(int last)
+  {
+    m_last = last;
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return true;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return -1;
+  }
+  
+
+}
diff --git a/src/main/java/org/apache/xpath/SourceTree.java b/src/main/java/org/apache/xpath/SourceTree.java
new file mode 100644
index 0000000..6492810
--- /dev/null
+++ b/src/main/java/org/apache/xpath/SourceTree.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SourceTree.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+
+/**
+ * This object represents a Source Tree, and any associated
+ * information.
+ * @xsl.usage internal
+ */
+public class SourceTree
+{
+
+  /**
+   * Constructor SourceTree
+   *
+   *
+   * @param root The root of the source tree, which may or may not be a 
+   * {@link org.w3c.dom.Document} node.
+   * @param url The URI of the source tree.
+   */
+  public SourceTree(int root, String url)
+  {
+    m_root = root;
+    m_url = url;
+  }
+
+  /** The URI of the source tree.   */
+  public String m_url;
+
+  /** The root of the source tree, which may or may not be a 
+   * {@link org.w3c.dom.Document} node.  */
+  public int m_root;
+}
diff --git a/src/main/java/org/apache/xpath/SourceTreeManager.java b/src/main/java/org/apache/xpath/SourceTreeManager.java
new file mode 100644
index 0000000..0ba44cf
--- /dev/null
+++ b/src/main/java/org/apache/xpath/SourceTreeManager.java
@@ -0,0 +1,390 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SourceTreeManager.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.SystemIDResolver;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * This class bottlenecks all management of source trees.  The methods
+ * in this class should allow easy garbage collection of source
+ * trees (not yet!), and should centralize parsing for those source trees.
+ */
+public class SourceTreeManager
+{
+
+  /** Vector of SourceTree objects that this manager manages. */
+  private Vector m_sourceTree = new Vector();
+
+  /**
+   * Reset the list of SourceTree objects that this manager manages.
+   *
+   */
+  public void reset()
+  {
+    m_sourceTree = new Vector();
+  }
+
+  /** The TrAX URI resolver used to obtain source trees. */
+  URIResolver m_uriResolver;
+
+  /**
+   * Set an object that will be used to resolve URIs used in
+   * document(), etc.
+   * @param resolver An object that implements the URIResolver interface,
+   * or null.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+    m_uriResolver = resolver;
+  }
+
+  /**
+   * Get the object that will be used to resolve URIs used in
+   * document(), etc.
+   * @return An object that implements the URIResolver interface,
+   * or null.
+   */
+  public URIResolver getURIResolver()
+  {
+    return m_uriResolver;
+  }
+
+  /**
+   * Given a document, find the URL associated with that document.
+   * @param owner Document that was previously processed by this liaison.
+   *
+   * @return The base URI of the owner argument.
+   */
+  public String findURIFromDoc(int owner)
+  {
+    int n = m_sourceTree.size();
+
+    for (int i = 0; i < n; i++)
+    {
+      SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);
+
+      if (owner == sTree.m_root)
+        return sTree.m_url;
+    }
+
+    return null;
+  }
+
+  /**
+   * This will be called by the processor when it encounters
+   * an xsl:include, xsl:import, or document() function.
+   *
+   * @param base The base URI that should be used.
+   * @param urlString Value from an xsl:import or xsl:include's href attribute,
+   * or a URI specified in the document() function.
+   * 
+   * @return a Source that can be used to process the resource.
+   *
+   * @throws IOException
+   * @throws TransformerException
+   */
+  public Source resolveURI(
+          String base, String urlString, SourceLocator locator)
+            throws TransformerException, IOException
+  {
+
+    Source source = null;
+
+    if (null != m_uriResolver)
+    {
+      source = m_uriResolver.resolve(urlString, base);
+    }
+
+    if (null == source)
+    {
+      String uri = SystemIDResolver.getAbsoluteURI(urlString, base);
+
+      source = new StreamSource(uri);
+    }
+
+    return source;
+  }
+
+  /** JJK: Support  <?xalan:doc_cache_off?> kluge in ElemForEach.
+   * TODO: This function is highly dangerous. Cache management must be improved.
+   *
+   * @param n The node to remove.
+   */
+  public void removeDocumentFromCache(int n)
+  {
+    if(DTM.NULL ==n)
+      return;
+    for(int i=m_sourceTree.size()-1;i>=0;--i)
+    {
+      SourceTree st=(SourceTree)m_sourceTree.elementAt(i);
+      if(st!=null && st.m_root==n)
+      {
+	m_sourceTree.removeElementAt(i);
+	return;
+      }
+    }
+  }
+  
+
+
+  /**
+   * Put the source tree root node in the document cache.
+   * TODO: This function needs to be a LOT more sophisticated.
+   *
+   * @param n The node to cache.
+   * @param source The Source object to cache.
+   */
+  public void putDocumentInCache(int n, Source source)
+  {
+
+    int cachedNode = getNode(source);
+
+    if (DTM.NULL != cachedNode)
+    {
+      if (!(cachedNode == n))
+        throw new RuntimeException(
+          "Programmer's Error!  "
+          + "putDocumentInCache found reparse of doc: "
+          + source.getSystemId());
+      return;
+    }
+    if (null != source.getSystemId())
+    {
+      m_sourceTree.addElement(new SourceTree(n, source.getSystemId()));
+    }
+  }
+
+  /**
+   * Given a Source object, find the node associated with it.
+   *
+   * @param source The Source object to act as the key.
+   *
+   * @return The node that is associated with the Source, or null if not found.
+   */
+  public int getNode(Source source)
+  {
+
+//    if (source instanceof DOMSource)
+//      return ((DOMSource) source).getNode();
+
+    // TODO: Not sure if the BaseID is really the same thing as the ID.
+    String url = source.getSystemId();
+
+    if (null == url)
+      return DTM.NULL;
+
+    int n = m_sourceTree.size();
+
+    // System.out.println("getNode: "+n);
+    for (int i = 0; i < n; i++)
+    {
+      SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);
+
+      // System.out.println("getNode -         url: "+url);
+      // System.out.println("getNode - sTree.m_url: "+sTree.m_url);
+      if (url.equals(sTree.m_url))
+        return sTree.m_root;
+    }
+
+    // System.out.println("getNode - returning: "+node);
+    return DTM.NULL;
+  }
+
+  /**
+   * Get the source tree from the a base URL and a URL string.
+   *
+   * @param base The base URI to use if the urlString is relative.
+   * @param urlString An absolute or relative URL string.
+   * @param locator The location of the caller, for diagnostic purposes.
+   *
+   * @return should be a non-null reference to the node identified by the 
+   * base and urlString.
+   *
+   * @throws TransformerException If the URL can not resolve to a node.
+   */
+  public int getSourceTree(
+          String base, String urlString, SourceLocator locator, XPathContext xctxt)
+            throws TransformerException
+  {
+
+    // System.out.println("getSourceTree");
+    try
+    {
+      Source source = this.resolveURI(base, urlString, locator);
+
+      // System.out.println("getSourceTree - base: "+base+", urlString: "+urlString+", source: "+source.getSystemId());
+      return getSourceTree(source, locator, xctxt);
+    }
+    catch (IOException ioe)
+    {
+      throw new TransformerException(ioe.getMessage(), locator, ioe);
+    }
+
+    /* catch (TransformerException te)
+     {
+       throw new TransformerException(te.getMessage(), locator, te);
+     }*/
+  }
+
+  /**
+   * Get the source tree from the input source.
+   *
+   * @param source The Source object that should identify the desired node.
+   * @param locator The location of the caller, for diagnostic purposes.
+   *
+   * @return non-null reference to a node.
+   *
+   * @throws TransformerException if the Source argument can't be resolved to 
+   *         a node.
+   */
+  public int getSourceTree(Source source, SourceLocator locator, XPathContext xctxt)
+          throws TransformerException
+  {
+
+    int n = getNode(source);
+
+    if (DTM.NULL != n)
+      return n;
+
+    n = parseToNode(source, locator, xctxt);
+
+    if (DTM.NULL != n)
+      putDocumentInCache(n, source);
+
+    return n;
+  }
+
+  /**
+   * Try to create a DOM source tree from the input source.
+   *
+   * @param source The Source object that identifies the source node.
+   * @param locator The location of the caller, for diagnostic purposes.
+   *
+   * @return non-null reference to node identified by the source argument.
+   *
+   * @throws TransformerException if the source argument can not be resolved 
+   *         to a source node.
+   */
+  public int parseToNode(Source source, SourceLocator locator, XPathContext xctxt)
+          throws TransformerException
+  {
+
+    try
+    {      
+      Object xowner = xctxt.getOwnerObject();
+      DTM dtm;
+      if(null != xowner && xowner instanceof org.apache.xml.dtm.DTMWSFilter)
+      {
+        dtm = xctxt.getDTM(source, false, 
+                          (org.apache.xml.dtm.DTMWSFilter)xowner, false, true);
+      }
+      else
+      {
+        dtm = xctxt.getDTM(source, false, null, false, true);
+      }
+      return dtm.getDocument();
+    }
+    catch (Exception e)
+    {
+      //e.printStackTrace();
+      throw new TransformerException(e.getMessage(), locator, e);
+    }
+
+  }
+
+  /**
+   * This method returns the SAX2 parser to use with the InputSource
+   * obtained from this URI.
+   * It may return null if any SAX2-conformant XML parser can be used,
+   * or if getInputSource() will also return null. The parser must
+   * be free for use (i.e.
+   * not currently in use for another parse().
+   *
+   * @param inputSource The value returned from the URIResolver.
+   * @return a SAX2 XMLReader to use to resolve the inputSource argument.
+   * @param locator The location of the original caller, for diagnostic purposes.
+   *
+   * @throws TransformerException if the reader can not be created.
+   */
+  public static XMLReader getXMLReader(Source inputSource, SourceLocator locator)
+          throws TransformerException
+  {
+
+    try
+    {
+      XMLReader reader = (inputSource instanceof SAXSource)
+                         ? ((SAXSource) inputSource).getXMLReader() : null;
+                         
+      if (null == reader)
+      {
+        try {
+          javax.xml.parsers.SAXParserFactory factory=
+              javax.xml.parsers.SAXParserFactory.newInstance();
+          factory.setNamespaceAware( true );
+          javax.xml.parsers.SAXParser jaxpParser=
+              factory.newSAXParser();
+          reader=jaxpParser.getXMLReader();
+          
+        } catch( javax.xml.parsers.ParserConfigurationException ex ) {
+          throw new org.xml.sax.SAXException( ex );
+        } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
+            throw new org.xml.sax.SAXException( ex1.toString() );
+        } catch( NoSuchMethodError ex2 ) {
+        }
+        catch (AbstractMethodError ame){}
+        if(null == reader)
+          reader = XMLReaderFactory.createXMLReader();
+      }
+
+      try
+      {
+        reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
+                          true);
+      }
+      catch (org.xml.sax.SAXException se)
+      {
+
+        // What can we do?
+        // TODO: User diagnostics.
+      }
+
+      return reader;
+    }
+    catch (org.xml.sax.SAXException se)
+    {
+      throw new TransformerException(se.getMessage(), locator, se);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/VariableStack.java b/src/main/java/org/apache/xpath/VariableStack.java
new file mode 100644
index 0000000..e72c265
--- /dev/null
+++ b/src/main/java/org/apache/xpath/VariableStack.java
@@ -0,0 +1,547 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: VariableStack.java 524812 2007-04-02 15:52:03Z zongaro $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Defines a class to keep track of a stack for
+ * template arguments and variables.
+ *
+ * <p>This has been changed from the previous incarnations of this
+ * class to be fairly low level.</p>
+ * @xsl.usage internal
+ */
+public class VariableStack implements Cloneable
+{
+  /**
+   * limitation for 1K
+   */
+  public static final int CLEARLIMITATION= 1024;
+
+  /**
+   * Constructor for a variable stack.
+   */
+  public VariableStack()
+  {
+    reset();
+  }
+
+  /**
+   * Constructor for a variable stack.
+   * @param initStackSize The initial stack size.  Must be at least one.  The
+   *                      stack can grow if needed.
+   */
+  public VariableStack(int initStackSize)
+  {
+    // Allow for twice as many variables as stack link entries
+    reset(initStackSize, initStackSize*2);
+  }
+
+  /**
+   * Returns a clone of this variable stack.
+   *
+   * @return  a clone of this variable stack.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public synchronized Object clone() throws CloneNotSupportedException
+  {
+
+    VariableStack vs = (VariableStack) super.clone();
+
+    // I *think* I can get away with a shallow clone here?
+    vs._stackFrames = (XObject[]) _stackFrames.clone();
+    vs._links = (int[]) _links.clone();
+
+    return vs;
+  }
+
+  /**
+   * The stack frame where all variables and params will be kept.
+   * @serial
+   */
+  XObject[] _stackFrames;
+
+  /**
+   * The top of the stack frame (<code>_stackFrames</code>).
+   * @serial
+   */
+  int _frameTop;
+
+  /**
+   * The bottom index of the current frame (relative to <code>_stackFrames</code>).
+   * @serial
+   */
+  private int _currentFrameBottom;
+
+  /**
+   * The stack of frame positions.  I call 'em links because of distant
+   * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html">
+   * Motorola 68000 assembler</a> memories.  :-)
+   * @serial
+   */
+  int[] _links;
+
+  /**
+   * The top of the links stack.
+   */
+  int _linksTop;
+
+  /**
+   * Get the element at the given index, regardless of stackframe.
+   *
+   * @param i index from zero.
+   *
+   * @return The item at the given index.
+   */
+  public XObject elementAt(final int i)
+  {
+    return _stackFrames[i];
+  }
+
+  /**
+   * Get size of the stack.
+   *
+   * @return the total size of the execution stack.
+   */
+  public int size()
+  {
+    return _frameTop;
+  }
+
+  /**
+   * Reset the stack to a start position.
+   */
+  public void reset()
+  {
+    // If the stack was previously allocated, assume that about the same
+    // amount of stack space will be needed again; otherwise, use a very
+    // large stack size.
+    int linksSize = (_links == null) ? XPathContext.RECURSIONLIMIT
+                                     : _links.length;
+    int varArraySize = (_stackFrames == null) ? XPathContext.RECURSIONLIMIT * 2
+                                              : _stackFrames.length;
+    reset(linksSize, varArraySize);
+  }
+
+  /**
+   * Reset the stack to a start position.
+   * @param linksSize Initial stack size to use
+   * @param varArraySize Initial variable array size to use
+   */
+  protected void reset(int linksSize, int varArraySize) {
+    _frameTop = 0;
+    _linksTop = 0;
+
+    // Don't bother reallocating _links array if it exists already
+    if (_links == null) {
+      _links = new int[linksSize];
+    }
+
+    // Adding one here to the stack of frame positions will allow us always 
+    // to look one under without having to check if we're at zero.
+    // (As long as the caller doesn't screw up link/unlink.)
+    _links[_linksTop++] = 0;
+
+    // Get a clean _stackFrames array and discard the old one.
+    _stackFrames = new XObject[varArraySize]; 
+  }
+
+  /**
+   * Set the current stack frame.
+   *
+   * @param sf The new stack frame position.
+   */
+  public void setStackFrame(int sf)
+  {
+    _currentFrameBottom = sf;
+  }
+
+  /**
+   * Get the position from where the search should start,
+   * which is either the searchStart property, or the top
+   * of the stack if that value is -1.
+   *
+   * @return The current stack frame position.
+   */
+  public int getStackFrame()
+  {
+    return _currentFrameBottom;
+  }
+
+  /**
+   * Allocates memory (called a stackframe) on the stack; used to store
+   * local variables and parameter arguments.
+   *
+   * <p>I use the link/unlink concept because of distant
+   * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html">
+   * Motorola 68000 assembler</a> memories.</p>
+   *
+   * @param size The size of the stack frame allocation.  This ammount should
+   * normally be the maximum number of variables that you can have allocated
+   * at one time in the new stack frame.
+   *
+   * @return The bottom of the stack frame, from where local variable addressing
+   * should start from.
+   */
+  public int link(final int size)
+  {
+
+    _currentFrameBottom = _frameTop;
+    _frameTop += size;
+
+    if (_frameTop >= _stackFrames.length)
+    {
+      XObject newsf[] = new XObject[_stackFrames.length + XPathContext.RECURSIONLIMIT + size];
+
+      System.arraycopy(_stackFrames, 0, newsf, 0, _stackFrames.length);
+
+      _stackFrames = newsf;
+    }
+
+    if (_linksTop + 1 >= _links.length)
+    {
+      int newlinks[] = new int[_links.length + (CLEARLIMITATION * 2)];
+
+      System.arraycopy(_links, 0, newlinks, 0, _links.length);
+
+      _links = newlinks;
+    }
+
+    _links[_linksTop++] = _currentFrameBottom;
+
+    return _currentFrameBottom;
+  }
+
+  /**
+   * Free up the stack frame that was last allocated with
+   * {@link #link(int size)}.
+   */
+  public  void unlink()
+  {
+    _frameTop = _links[--_linksTop];
+    _currentFrameBottom = _links[_linksTop - 1];
+  }
+  
+  /**
+   * Free up the stack frame that was last allocated with
+   * {@link #link(int size)}.
+   * @param currentFrame The current frame to set to 
+   * after the unlink.
+   */
+  public  void unlink(int currentFrame)
+  {
+    _frameTop = _links[--_linksTop];
+    _currentFrameBottom = currentFrame; 
+  }
+
+  /**
+   * Set a local variable or parameter in the current stack frame.
+   *
+   *
+   * @param index Local variable index relative to the current stack
+   * frame bottom.
+   *
+   * @param val The value of the variable that is being set.
+   */
+  public void setLocalVariable(int index, XObject val)
+  {
+    _stackFrames[index + _currentFrameBottom] = val;
+  }
+
+  /**
+   * Set a local variable or parameter in the specified stack frame.
+   *
+   *
+   * @param index Local variable index relative to the current stack
+   * frame bottom.
+   * NEEDSDOC @param stackFrame
+   *
+   * @param val The value of the variable that is being set.
+   */
+  public void setLocalVariable(int index, XObject val, int stackFrame)
+  {
+    _stackFrames[index + stackFrame] = val;
+  }
+
+  /**
+   * Get a local variable or parameter in the current stack frame.
+   *
+   *
+   * @param xctxt The XPath context, which must be passed in order to
+   * lazy evaluate variables.
+   *
+   * @param index Local variable index relative to the current stack
+   * frame bottom.
+   *
+   * @return The value of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getLocalVariable(XPathContext xctxt, int index)
+          throws TransformerException
+  {
+
+    index += _currentFrameBottom;
+
+    XObject val = _stackFrames[index];
+    
+    if(null == val)
+      throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VARIABLE_ACCESSED_BEFORE_BIND, null),
+                     xctxt.getSAXLocator());
+      // "Variable accessed before it is bound!", xctxt.getSAXLocator());
+
+    // Lazy execution of variables.
+    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
+      return (_stackFrames[index] = val.execute(xctxt));
+
+    return val;
+  }
+
+  /**
+   * Get a local variable or parameter in the current stack frame.
+   *
+   *
+   * @param index Local variable index relative to the given
+   * frame bottom.
+   * NEEDSDOC @param frame
+   *
+   * @return The value of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getLocalVariable(int index, int frame)
+          throws TransformerException
+  {
+
+    index += frame;
+
+    XObject val = _stackFrames[index];
+
+    return val;
+  }
+  
+  /**
+   * Get a local variable or parameter in the current stack frame.
+   *
+   *
+   * @param xctxt The XPath context, which must be passed in order to
+   * lazy evaluate variables.
+   *
+   * @param index Local variable index relative to the current stack
+   * frame bottom.
+   *
+   * @return The value of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getLocalVariable(XPathContext xctxt, int index, boolean destructiveOK)
+          throws TransformerException
+  {
+
+    index += _currentFrameBottom;
+
+    XObject val = _stackFrames[index];
+    
+    if(null == val)
+      throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VARIABLE_ACCESSED_BEFORE_BIND, null),
+                     xctxt.getSAXLocator());
+      // "Variable accessed before it is bound!", xctxt.getSAXLocator());
+
+    // Lazy execution of variables.
+    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
+      return (_stackFrames[index] = val.execute(xctxt));
+
+    return destructiveOK ? val : val.getFresh();
+  }
+
+  /**
+   * Tell if a local variable has been set or not.
+   *
+   * @param index Local variable index relative to the current stack
+   * frame bottom.
+   *
+   * @return true if the value at the index is not null.
+   *
+   * @throws TransformerException
+   */
+  public boolean isLocalSet(int index) throws TransformerException
+  {
+    return (_stackFrames[index + _currentFrameBottom] != null);
+  }
+
+  /** NEEDSDOC Field m_nulls          */
+  private static XObject[] m_nulls = new XObject[CLEARLIMITATION];
+
+  /**
+   * Use this to clear the variables in a section of the stack.  This is
+   * used to clear the parameter section of the stack, so that default param
+   * values can tell if they've already been set.  It is important to note that
+   * this function has a 1K limitation.
+   *
+   * @param start The start position, relative to the current local stack frame.
+   * @param len The number of slots to be cleared.
+   */
+  public void clearLocalSlots(int start, int len)
+  {
+
+    start += _currentFrameBottom;
+
+    System.arraycopy(m_nulls, 0, _stackFrames, start, len);
+  }
+
+  /**
+   * Set a global variable or parameter in the global stack frame.
+   *
+   *
+   * @param index Local variable index relative to the global stack frame
+   * bottom.
+   *
+   * @param val The value of the variable that is being set.
+   */
+  public void setGlobalVariable(final int index, final XObject val)
+  {
+    _stackFrames[index] = val;
+  }
+
+  /**
+   * Get a global variable or parameter from the global stack frame.
+   *
+   *
+   * @param xctxt The XPath context, which must be passed in order to
+   * lazy evaluate variables.
+   *
+   * @param index Global variable index relative to the global stack
+   * frame bottom.
+   *
+   * @return The value of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getGlobalVariable(XPathContext xctxt, final int index)
+          throws TransformerException
+  {
+
+    XObject val = _stackFrames[index];
+
+    // Lazy execution of variables.
+    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
+      return (_stackFrames[index] = val.execute(xctxt));
+
+    return val;
+  }
+  
+  /**
+   * Get a global variable or parameter from the global stack frame.
+   *
+   *
+   * @param xctxt The XPath context, which must be passed in order to
+   * lazy evaluate variables.
+   *
+   * @param index Global variable index relative to the global stack
+   * frame bottom.
+   *
+   * @return The value of the variable.
+   *
+   * @throws TransformerException
+   */
+  public XObject getGlobalVariable(XPathContext xctxt, final int index, boolean destructiveOK)
+          throws TransformerException
+  {
+
+    XObject val = _stackFrames[index];
+
+    // Lazy execution of variables.
+    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
+      return (_stackFrames[index] = val.execute(xctxt));
+
+    return destructiveOK ? val : val.getFresh();
+  }
+
+  /**
+   * Get a variable based on it's qualified name.
+   * This is for external use only.
+   *
+   * @param xctxt The XPath context, which must be passed in order to
+   * lazy evaluate variables.
+   * 
+   * @param qname The qualified name of the variable.
+   *
+   * @return The evaluated value of the variable.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject getVariableOrParam(
+          XPathContext xctxt, org.apache.xml.utils.QName qname)
+            throws javax.xml.transform.TransformerException
+  {
+
+    org.apache.xml.utils.PrefixResolver prefixResolver =
+      xctxt.getNamespaceContext();
+
+    // Get the current ElemTemplateElement, which must be pushed in as the 
+    // prefix resolver, and then walk backwards in document order, searching 
+    // for an xsl:param element or xsl:variable element that matches our 
+    // qname.  If we reach the top level, use the StylesheetRoot's composed
+    // list of top level variables and parameters.
+
+    if (prefixResolver instanceof org.apache.xalan.templates.ElemTemplateElement)
+    {
+      
+      org.apache.xalan.templates.ElemVariable vvar;
+
+      org.apache.xalan.templates.ElemTemplateElement prev =
+        (org.apache.xalan.templates.ElemTemplateElement) prefixResolver;
+
+      if (!(prev instanceof org.apache.xalan.templates.Stylesheet))
+      {
+        while ( !(prev.getParentNode() instanceof org.apache.xalan.templates.Stylesheet) )
+        {
+          org.apache.xalan.templates.ElemTemplateElement savedprev = prev;
+
+          while (null != (prev = prev.getPreviousSiblingElem()))
+          {
+            if (prev instanceof org.apache.xalan.templates.ElemVariable)
+            {
+              vvar = (org.apache.xalan.templates.ElemVariable) prev;
+
+              if (vvar.getName().equals(qname))
+                return getLocalVariable(xctxt, vvar.getIndex());
+            }
+          }
+          prev = savedprev.getParentElem();
+        }
+      }
+
+      vvar = prev.getStylesheetRoot().getVariableOrParamComposed(qname);
+      if (null != vvar)
+        return getGlobalVariable(xctxt, vvar.getIndex());
+    }
+
+    throw new javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VAR_NOT_RESOLVABLE, new Object[]{qname.toString()})); //"Variable not resolvable: " + qname);
+  }
+}  // end VariableStack
+
diff --git a/src/main/java/org/apache/xpath/WhitespaceStrippingElementMatcher.java b/src/main/java/org/apache/xpath/WhitespaceStrippingElementMatcher.java
new file mode 100644
index 0000000..2315b0c
--- /dev/null
+++ b/src/main/java/org/apache/xpath/WhitespaceStrippingElementMatcher.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WhitespaceStrippingElementMatcher.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Element;
+
+/**
+ * A class that implements this interface can tell if a given element should 
+ * strip whitespace nodes from it's children.
+ */
+public interface WhitespaceStrippingElementMatcher
+{
+  /**
+   * Get information about whether or not an element should strip whitespace.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @param support The XPath runtime state.
+   * @param targetElement Element to check
+   *
+   * @return true if the whitespace should be stripped.
+   *
+   * @throws TransformerException
+   */
+  public boolean shouldStripWhiteSpace(
+          XPathContext support, Element targetElement) throws TransformerException;
+  
+  /**
+   * Get information about whether or not whitespace can be stripped.
+   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
+   *
+   * @return true if the whitespace can be stripped.
+   */
+  public boolean canStripWhiteSpace();
+}
diff --git a/src/main/java/org/apache/xpath/XPath.java b/src/main/java/org/apache/xpath/XPath.java
new file mode 100644
index 0000000..56c2b73
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPath.java
@@ -0,0 +1,643 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPath.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import java.io.Serializable;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.FunctionTable;
+import org.apache.xpath.compiler.XPathParser;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * The XPath class wraps an expression object and provides general services 
+ * for execution of that expression.
+ * @xsl.usage advanced
+ */
+public class XPath implements Serializable, ExpressionOwner
+{
+    static final long serialVersionUID = 3976493477939110553L;
+
+  /** The top of the expression tree. 
+   *  @serial */
+  private Expression m_mainExp;
+  
+  /**
+   * The function table for xpath build-in functions
+   */
+  private transient FunctionTable m_funcTable = null;
+
+  /**
+   * initial the function table
+   */
+  private void initFunctionTable(){
+  	      m_funcTable = new FunctionTable();
+  }
+
+  /**
+   * Get the raw Expression object that this class wraps.
+   *
+   *
+   * @return the raw Expression object, which should not normally be null.
+   */
+  public Expression getExpression()
+  {
+    return m_mainExp;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_mainExp.fixupVariables(vars, globalsSize);
+  }
+
+  /**
+   * Set the raw expression object for this object.
+   *
+   *
+   * @param exp the raw Expression object, which should not normally be null.
+   */
+  public void setExpression(Expression exp)
+  {
+  	if(null != m_mainExp)
+    	exp.exprSetParent(m_mainExp.exprGetParent()); // a bit bogus
+    m_mainExp = exp;
+  }
+
+  /**
+   * Get the SourceLocator on the expression object.
+   *
+   *
+   * @return the SourceLocator on the expression object, which may be null.
+   */
+  public SourceLocator getLocator()
+  {
+    return m_mainExp;
+  }
+
+//  /**
+//   * Set the SourceLocator on the expression object.
+//   *
+//   *
+//   * @param l the SourceLocator on the expression object, which may be null.
+//   */
+//  public void setLocator(SourceLocator l)
+//  {
+//    // Note potential hazards -- l may not be serializable, or may be changed
+//      // after being assigned here.
+//    m_mainExp.setSourceLocator(l);
+//  }
+
+  /** The pattern string, mainly kept around for diagnostic purposes.
+   *  @serial  */
+  String m_patternString;
+
+  /**
+   * Return the XPath string associated with this object.
+   *
+   *
+   * @return the XPath string associated with this object.
+   */
+  public String getPatternString()
+  {
+    return m_patternString;
+  }
+
+  /** Represents a select type expression. */
+  public static final int SELECT = 0;
+
+  /** Represents a match type expression.  */
+  public static final int MATCH = 1;
+
+  /**
+   * Construct an XPath object.  
+   *
+   * (Needs review -sc) This method initializes an XPathParser/
+   * Compiler and compiles the expression.
+   * @param exprString The XPath expression.
+   * @param locator The location of the expression, may be null.
+   * @param prefixResolver A prefix resolver to use to resolve prefixes to 
+   *                       namespace URIs.
+   * @param type one of {@link #SELECT} or {@link #MATCH}.
+   * @param errorListener The error listener, or null if default should be used.
+   *
+   * @throws javax.xml.transform.TransformerException if syntax or other error.
+   */
+  public XPath(
+          String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type,
+          ErrorListener errorListener)
+            throws javax.xml.transform.TransformerException
+  { 
+    initFunctionTable();     
+    if(null == errorListener)
+      errorListener = new org.apache.xml.utils.DefaultErrorHandler();
+    
+    m_patternString = exprString;
+
+    XPathParser parser = new XPathParser(errorListener, locator);
+    Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
+
+    if (SELECT == type)
+      parser.initXPath(compiler, exprString, prefixResolver);
+    else if (MATCH == type)
+      parser.initMatchPattern(compiler, exprString, prefixResolver);
+    else
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)})); //"Can not deal with XPath type: " + type);
+
+    // System.out.println("----------------");
+    Expression expr = compiler.compile(0);
+
+    // System.out.println("expr: "+expr);
+    this.setExpression(expr);
+    
+    if((null != locator) && locator instanceof ExpressionNode)
+    {
+    	expr.exprSetParent((ExpressionNode)locator);
+    }
+
+  }
+
+  /**
+   * Construct an XPath object.  
+   *
+   * (Needs review -sc) This method initializes an XPathParser/
+   * Compiler and compiles the expression.
+   * @param exprString The XPath expression.
+   * @param locator The location of the expression, may be null.
+   * @param prefixResolver A prefix resolver to use to resolve prefixes to 
+   *                       namespace URIs.
+   * @param type one of {@link #SELECT} or {@link #MATCH}.
+   * @param errorListener The error listener, or null if default should be used.
+   *
+   * @throws javax.xml.transform.TransformerException if syntax or other error.
+   */
+  public XPath(
+          String exprString, SourceLocator locator, 
+          PrefixResolver prefixResolver, int type,
+          ErrorListener errorListener, FunctionTable aTable)
+            throws javax.xml.transform.TransformerException
+  { 
+    m_funcTable = aTable;     
+    if(null == errorListener)
+      errorListener = new org.apache.xml.utils.DefaultErrorHandler();
+    
+    m_patternString = exprString;
+
+    XPathParser parser = new XPathParser(errorListener, locator);
+    Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
+
+    if (SELECT == type)
+      parser.initXPath(compiler, exprString, prefixResolver);
+    else if (MATCH == type)
+      parser.initMatchPattern(compiler, exprString, prefixResolver);
+    else
+      throw new RuntimeException(XSLMessages.createXPATHMessage(
+            XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, 
+            new Object[]{Integer.toString(type)})); 
+            //"Can not deal with XPath type: " + type);
+
+    // System.out.println("----------------");
+    Expression expr = compiler.compile(0);
+
+    // System.out.println("expr: "+expr);
+    this.setExpression(expr);
+    
+    if((null != locator) && locator instanceof ExpressionNode)
+    {
+    	expr.exprSetParent((ExpressionNode)locator);
+    }
+
+  }
+  
+  /**
+   * Construct an XPath object.  
+   *
+   * (Needs review -sc) This method initializes an XPathParser/
+   * Compiler and compiles the expression.
+   * @param exprString The XPath expression.
+   * @param locator The location of the expression, may be null.
+   * @param prefixResolver A prefix resolver to use to resolve prefixes to 
+   *                       namespace URIs.
+   * @param type one of {@link #SELECT} or {@link #MATCH}.
+   *
+   * @throws javax.xml.transform.TransformerException if syntax or other error.
+   */
+  public XPath(
+          String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type)
+            throws javax.xml.transform.TransformerException
+  {  
+    this(exprString, locator, prefixResolver, type, null);    
+  }
+
+  /**
+   * Construct an XPath object.
+   *
+   * @param expr The Expression object.
+   *
+   * @throws javax.xml.transform.TransformerException if syntax or other error.
+   */
+  public XPath(Expression expr)
+  {  
+    this.setExpression(expr);
+    initFunctionTable();   
+  }
+  
+  /**
+   * Given an expression and a context, evaluate the XPath
+   * and return the result.
+   * 
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   * @param namespaceContext The context in which namespaces in the
+   * XPath are supposed to be expanded.
+   *
+   * @return The result of the XPath or null if callbacks are used.
+   * @throws TransformerException thrown if
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public XObject execute(
+          XPathContext xctxt, org.w3c.dom.Node contextNode, 
+          PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+    return execute(
+          xctxt, xctxt.getDTMHandleFromNode(contextNode), 
+          namespaceContext);
+  }
+  
+
+  /**
+   * Given an expression and a context, evaluate the XPath
+   * and return the result.
+   * 
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   * @param namespaceContext The context in which namespaces in the
+   * XPath are supposed to be expanded.
+   * 
+   * @throws TransformerException thrown if the active ProblemListener decides
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public XObject execute(
+          XPathContext xctxt, int contextNode, PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    xctxt.pushNamespaceContext(namespaceContext);
+
+    xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
+
+    XObject xobj = null;
+
+    try
+    {
+      xobj = m_mainExp.execute(xctxt);
+    }
+    catch (TransformerException te)
+    {
+      te.setLocator(this.getLocator());
+      ErrorListener el = xctxt.getErrorListener();
+      if(null != el) // defensive, should never happen.
+      {
+        el.error(te);
+      }
+      else
+        throw te;
+    }
+    catch (Exception e)
+    {
+      while (e instanceof org.apache.xml.utils.WrappedRuntimeException)
+      {
+        e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
+      }
+      // e.printStackTrace();
+
+      String msg = e.getMessage();
+      
+      if (msg == null || msg.length() == 0) {
+           msg = XSLMessages.createXPATHMessage(
+               XPATHErrorResources.ER_XPATH_ERROR, null);
+     
+      }  
+      TransformerException te = new TransformerException(msg,
+              getLocator(), e);
+      ErrorListener el = xctxt.getErrorListener();
+      // te.printStackTrace();
+      if(null != el) // defensive, should never happen.
+      {
+        el.fatalError(te);
+      }
+      else
+        throw te;
+    }
+    finally
+    {
+      xctxt.popNamespaceContext();
+
+      xctxt.popCurrentNodeAndExpression();
+    }
+
+    return xobj;
+  }
+  
+  /**
+   * Given an expression and a context, evaluate the XPath
+   * and return the result.
+   * 
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   * @param namespaceContext The context in which namespaces in the
+   * XPath are supposed to be expanded.
+   * 
+   * @throws TransformerException thrown if the active ProblemListener decides
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public boolean bool(
+          XPathContext xctxt, int contextNode, PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    xctxt.pushNamespaceContext(namespaceContext);
+
+    xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
+
+    try
+    {
+      return m_mainExp.bool(xctxt);
+    }
+    catch (TransformerException te)
+    {
+      te.setLocator(this.getLocator());
+      ErrorListener el = xctxt.getErrorListener();
+      if(null != el) // defensive, should never happen.
+      {
+        el.error(te);
+      }
+      else
+        throw te;
+    }
+    catch (Exception e)
+    {
+      while (e instanceof org.apache.xml.utils.WrappedRuntimeException)
+      {
+        e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
+      }
+      // e.printStackTrace();
+
+      String msg = e.getMessage();
+      
+      if (msg == null || msg.length() == 0) {
+           msg = XSLMessages.createXPATHMessage(
+               XPATHErrorResources.ER_XPATH_ERROR, null);
+     
+      }        
+      
+      TransformerException te = new TransformerException(msg,
+              getLocator(), e);
+      ErrorListener el = xctxt.getErrorListener();
+      // te.printStackTrace();
+      if(null != el) // defensive, should never happen.
+      {
+        el.fatalError(te);
+      }
+      else
+        throw te;
+    }
+    finally
+    {
+      xctxt.popNamespaceContext();
+
+      xctxt.popCurrentNodeAndExpression();
+    }
+
+    return false;
+  }
+
+  /** Set to true to get diagnostic messages about the result of 
+   *  match pattern testing.  */
+  private static final boolean DEBUG_MATCHES = false;
+
+  /**
+   * Get the match score of the given node.
+   *
+   * @param xctxt XPath runtime context.
+   * @param context The current source tree context node.
+   * 
+   * @return score, one of {@link #MATCH_SCORE_NODETEST},
+   * {@link #MATCH_SCORE_NONE}, {@link #MATCH_SCORE_OTHER}, 
+   * or {@link #MATCH_SCORE_QNAME}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double getMatchScore(XPathContext xctxt, int context)
+          throws javax.xml.transform.TransformerException
+  {
+
+    xctxt.pushCurrentNode(context);
+    xctxt.pushCurrentExpressionNode(context);
+
+    try
+    {
+      XObject score = m_mainExp.execute(xctxt);
+
+      if (DEBUG_MATCHES)
+      {
+        DTM dtm = xctxt.getDTM(context);
+        System.out.println("score: " + score.num() + " for "
+                           + dtm.getNodeName(context) + " for xpath "
+                           + this.getPatternString());
+      }
+
+      return score.num();
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      xctxt.popCurrentExpressionNode();
+    }
+
+    // return XPath.MATCH_SCORE_NONE;
+  }
+
+
+  /**
+   * Warn the user of an problem.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param sourceNode Not used.
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  public void warn(
+          XPathContext xctxt, int sourceNode, String msg, Object[] args)
+            throws javax.xml.transform.TransformerException
+  {
+
+    String fmsg = XSLMessages.createXPATHWarning(msg, args);
+    ErrorListener ehandler = xctxt.getErrorListener();
+
+    if (null != ehandler)
+    {
+
+      // TO DO: Need to get stylesheet Locator from here.
+      ehandler.warning(new TransformerException(fmsg, (SAXSourceLocator)xctxt.getSAXLocator()));
+    }
+  }
+
+  /**
+   * Tell the user of an assertion error, and probably throw an
+   * exception.
+   *
+   * @param b  If false, a runtime exception will be thrown.
+   * @param msg The assertion message, which should be informative.
+   * 
+   * @throws RuntimeException if the b argument is false.
+   */
+  public void assertion(boolean b, String msg)
+  {
+
+    if (!b)
+    {
+      String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ msg });
+
+      throw new RuntimeException(fMsg);
+    }
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param sourceNode Not used.
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  public void error(
+          XPathContext xctxt, int sourceNode, String msg, Object[] args)
+            throws javax.xml.transform.TransformerException
+  {
+
+    String fmsg = XSLMessages.createXPATHMessage(msg, args);
+    ErrorListener ehandler = xctxt.getErrorListener();
+
+    if (null != ehandler)
+    {
+      ehandler.fatalError(new TransformerException(fmsg,
+                              (SAXSourceLocator)xctxt.getSAXLocator()));
+    }
+    else
+    {
+      SourceLocator slocator = xctxt.getSAXLocator();
+      System.out.println(fmsg + "; file " + slocator.getSystemId()
+                         + "; line " + slocator.getLineNumber() + "; column "
+                         + slocator.getColumnNumber());
+    }
+  }
+  
+  /**
+   * This will traverse the heararchy, calling the visitor for 
+   * each member.  If the called visitor method returns 
+   * false, the subtree should not be called.
+   * 
+   * @param owner The owner of the visitor, where that path may be 
+   *              rewritten if needed.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	m_mainExp.callVisitors(this, visitor);
+  }
+
+  /**
+   * The match score if no match is made.
+   * @xsl.usage advanced
+   */
+  public static final double MATCH_SCORE_NONE = Double.NEGATIVE_INFINITY;
+
+  /**
+   * The match score if the pattern has the form
+   * of a QName optionally preceded by an @ character.
+   * @xsl.usage advanced
+   */
+  public static final double MATCH_SCORE_QNAME = 0.0;
+
+  /**
+   * The match score if the pattern pattern has the form NCName:*.
+   * @xsl.usage advanced
+   */
+  public static final double MATCH_SCORE_NSWILD = -0.25;
+
+  /**
+   * The match score if the pattern consists of just a NodeTest.
+   * @xsl.usage advanced
+   */
+  public static final double MATCH_SCORE_NODETEST = -0.5;
+
+  /**
+   * The match score if the pattern consists of something
+   * other than just a NodeTest or just a qname.
+   * @xsl.usage advanced
+   */
+  public static final double MATCH_SCORE_OTHER = 0.5;
+}
diff --git a/src/main/java/org/apache/xpath/XPathAPI.java b/src/main/java/org/apache/xpath/XPathAPI.java
new file mode 100644
index 0000000..01d1741
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathAPI.java
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathAPI.java 524807 2007-04-02 15:51:43Z zongaro $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.apache.xpath.objects.XObject;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * The methods in this class are convenience methods into the
+ * low-level XPath API.
+ * These functions tend to be a little slow, since a number of objects must be
+ * created for each evaluation.  A faster way is to precompile the
+ * XPaths using the low-level API, and then just use the XPaths
+ * over and over.
+ *
+ * NOTE: In particular, each call to this method will create a new
+ * XPathContext, a new DTMManager... and thus a new DTM. That's very
+ * safe, since it guarantees that you're always processing against a
+ * fully up-to-date view of your document. But it's also portentially
+ * very expensive, since you're rebuilding the DTM every time. You should
+ * consider using an instance of CachedXPathAPI rather than these static
+ * methods.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath">XPath Specification</a> 
+ * */
+public class XPathAPI
+{
+
+  /**
+   * Use an XPath string to select a single node. XPath namespace
+   * prefixes are resolved from the context node, which may not
+   * be what you want (see the next method).
+   *
+   * @param contextNode The node to start searching from.
+   * @param str A valid XPath string.
+   * @return The first node found that matches the XPath, or null.
+   *
+   * @throws TransformerException
+   */
+  public static Node selectSingleNode(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectSingleNode(contextNode, str, contextNode);
+  }
+
+  /**
+   * Use an XPath string to select a single node.
+   * XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   * @param contextNode The node to start searching from.
+   * @param str A valid XPath string.
+   * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   * @return The first node found that matches the XPath, or null.
+   *
+   * @throws TransformerException
+   */
+  public static Node selectSingleNode(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Have the XObject return its result as a NodeSetDTM.
+    NodeIterator nl = selectNodeIterator(contextNode, str, namespaceNode);
+
+    // Return the first node, or null
+    return nl.nextNode();
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the contextNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public static NodeIterator selectNodeIterator(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectNodeIterator(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public static NodeIterator selectNodeIterator(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Execute the XPath, and have it return the result
+    XObject list = eval(contextNode, str, namespaceNode);
+
+    // Have the XObject return its result as a NodeSetDTM.                
+    return list.nodeset();
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the contextNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public static NodeList selectNodeList(Node contextNode, String str)
+          throws TransformerException
+  {
+    return selectNodeList(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Use an XPath string to select a nodelist.
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return A NodeIterator, should never be null.
+   *
+   * @throws TransformerException
+   */
+  public static NodeList selectNodeList(
+          Node contextNode, String str, Node namespaceNode)
+            throws TransformerException
+  {
+
+    // Execute the XPath, and have it return the result
+    XObject list = eval(contextNode, str, namespaceNode);
+
+    // Return a NodeList.
+    return list.nodelist();
+  }
+
+  /**
+   *  Evaluate XPath string to an XObject.  Using this method,
+   *  XPath namespace prefixes will be resolved from the namespaceNode.
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *  @see org.apache.xpath.objects.XObject
+   *  @see org.apache.xpath.objects.XNull
+   *  @see org.apache.xpath.objects.XBoolean
+   *  @see org.apache.xpath.objects.XNumber
+   *  @see org.apache.xpath.objects.XString
+   *  @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public static XObject eval(Node contextNode, String str)
+          throws TransformerException
+  {
+    return eval(contextNode, str, contextNode);
+  }
+
+  /**
+   *  Evaluate XPath string to an XObject.
+   *  XPath namespace prefixes are resolved from the namespaceNode.
+   *  The implementation of this is a little slow, since it creates
+   *  a number of objects each time it is called.  This could be optimized
+   *  to keep the same objects around, but then thread-safety issues would arise.
+   *
+   *  @param contextNode The node to start searching from.
+   *  @param str A valid XPath string.
+   *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
+   *  @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *  @see org.apache.xpath.objects.XObject
+   *  @see org.apache.xpath.objects.XNull
+   *  @see org.apache.xpath.objects.XBoolean
+   *  @see org.apache.xpath.objects.XNumber
+   *  @see org.apache.xpath.objects.XString
+   *  @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public static XObject eval(Node contextNode, String str, Node namespaceNode)
+          throws TransformerException
+  {
+
+    // Since we don't have a XML Parser involved here, install some default support
+    // for things like namespaces, etc.
+    // (Changed from: XPathContext xpathSupport = new XPathContext();
+    //    because XPathContext is weak in a number of areas... perhaps
+    //    XPathContext should be done away with.)
+    // Create an XPathContext that doesn't support pushing and popping of
+    // variable resolution scopes.  Sufficient for simple XPath 1.0 expressions.
+    XPathContext xpathSupport = new XPathContext(false);
+
+    // Create an object to resolve namespace prefixes.
+    // XPath namespaces are resolved from the input context node's document element
+    // if it is a root node, or else the current context node (for lack of a better
+    // resolution space, given the simplicity of this sample code).
+    PrefixResolverDefault prefixResolver = new PrefixResolverDefault(
+      (namespaceNode.getNodeType() == Node.DOCUMENT_NODE)
+      ? ((Document) namespaceNode).getDocumentElement() : namespaceNode);
+
+    // Create the XPath object.
+    XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
+
+    // Execute the XPath, and have it return the result
+    // return xpath.execute(xpathSupport, contextNode, prefixResolver);
+    int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
+
+    return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
+  }
+
+  /**
+   *   Evaluate XPath string to an XObject.
+   *   XPath namespace prefixes are resolved from the namespaceNode.
+   *   The implementation of this is a little slow, since it creates
+   *   a number of objects each time it is called.  This could be optimized
+   *   to keep the same objects around, but then thread-safety issues would arise.
+   *
+   *   @param contextNode The node to start searching from.
+   *   @param str A valid XPath string.
+   *   @param prefixResolver Will be called if the parser encounters namespace
+   *                         prefixes, to resolve the prefixes to URLs.
+   *   @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
+   *   @see org.apache.xpath.objects.XObject
+   *   @see org.apache.xpath.objects.XNull
+   *   @see org.apache.xpath.objects.XBoolean
+   *   @see org.apache.xpath.objects.XNumber
+   *   @see org.apache.xpath.objects.XString
+   *   @see org.apache.xpath.objects.XRTreeFrag
+   *
+   * @throws TransformerException
+   */
+  public static XObject eval(
+          Node contextNode, String str, PrefixResolver prefixResolver)
+            throws TransformerException
+  {
+
+    // Since we don't have a XML Parser involved here, install some default support
+    // for things like namespaces, etc.
+    // (Changed from: XPathContext xpathSupport = new XPathContext();
+    //    because XPathContext is weak in a number of areas... perhaps
+    //    XPathContext should be done away with.)
+    // Create the XPath object.
+    XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
+
+    // Create an XPathContext that doesn't support pushing and popping of
+    // variable resolution scopes.  Sufficient for simple XPath 1.0 expressions.
+    XPathContext xpathSupport = new XPathContext(false);
+
+    // Execute the XPath, and have it return the result
+    int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
+
+    return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/XPathContext.java b/src/main/java/org/apache/xpath/XPathContext.java
new file mode 100644
index 0000000..5da437e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathContext.java
@@ -0,0 +1,1352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathContext.java 524809 2007-04-02 15:51:51Z zongaro $
+ */
+package org.apache.xpath;
+
+import java.lang.reflect.Method;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+
+import org.apache.xalan.extensions.ExpressionContext;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.dtm.ref.sax2dtm.SAX2RTFDTM;
+import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.NodeVector;
+import org.apache.xml.utils.ObjectStack;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.axes.SubContextList;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.DTMXRTreeFrag;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.res.XPATHErrorResources;
+
+import org.xml.sax.XMLReader;
+
+/**
+ * Default class for the runtime execution context for XPath.
+ * 
+ * <p>This class extends DTMManager but does not directly implement it.</p>
+ * @xsl.usage advanced
+ */
+public class XPathContext extends DTMManager // implements ExpressionContext
+{
+	IntStack m_last_pushed_rtfdtm=new IntStack();	
+  /**
+   * Stack of cached "reusable" DTMs for Result Tree Fragments.
+   * This is a kluge to handle the problem of starting an RTF before
+   * the old one is complete.
+   * 
+   * %REVIEW% I'm using a Vector rather than Stack so we can reuse
+   * the DTMs if the problem occurs multiple times. I'm not sure that's
+   * really a net win versus discarding the DTM and starting a new one...
+   * but the retained RTF DTM will have been tail-pruned so should be small.
+   */
+  private Vector m_rtfdtm_stack=null;
+  /** Index of currently active RTF DTM in m_rtfdtm_stack */
+  private int m_which_rtfdtm=-1;
+  
+ /**
+   * Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
+   * required since we're never going to pop these.
+   */
+  private SAX2RTFDTM m_global_rtfdtm=null;
+  
+  /**
+   * HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
+   * The object are just wrappers for DTMs which are used in  XRTreeFrag.
+   */
+  private HashMap m_DTMXRTreeFrags = null;
+  
+  /**
+   * state of the secure processing feature.
+   */
+  private boolean m_isSecureProcessing = false;
+	
+  /**
+   * Though XPathContext context extends 
+   * the DTMManager, it really is a proxy for this object, which 
+   * is the real DTMManager.
+   */
+  protected DTMManager m_dtmManager = DTMManager.newInstance(
+                   org.apache.xpath.objects.XMLStringFactoryImpl.getFactory());
+  
+  /**
+   * Return the DTMManager object.  Though XPathContext context extends 
+   * the DTMManager, it really is a proxy for the real DTMManager.  If a 
+   * caller needs to make a lot of calls to the DTMManager, it is faster 
+   * if it gets the real one from this function.
+   */
+   public DTMManager getDTMManager()
+   {
+     return m_dtmManager;
+   }
+  
+  /**
+   * Set the state of the secure processing feature
+   */
+  public void setSecureProcessing(boolean flag)
+  {
+    m_isSecureProcessing = flag;
+  }
+  
+  /**
+   * Return the state of the secure processing feature
+   */
+  public boolean isSecureProcessing()
+  {
+    return m_isSecureProcessing;
+  }
+  
+  /**
+   * Get an instance of a DTM, loaded with the content from the
+   * specified source.  If the unique flag is true, a new instance will
+   * always be returned.  Otherwise it is up to the DTMManager to return a
+   * new instance or an instance that it already created and may be being used
+   * by someone else.
+   * (I think more parameters will need to be added for error handling, and entity
+   * resolution).
+   *
+   * @param source the specification of the source object, which may be null, 
+   *               in which case it is assumed that node construction will take 
+   *               by some other means.
+   * @param unique true if the returned DTM must be unique, probably because it
+   * is going to be mutated.
+   * @param wsfilter Enables filtering of whitespace nodes, and may be null.
+   * @param incremental true if the construction should try and be incremental.
+   * @param doIndexing true if the caller considers it worth it to use 
+   *                   indexing schemes.
+   *
+   * @return a non-null DTM reference.
+   */
+  public DTM getDTM(javax.xml.transform.Source source, boolean unique, 
+                    DTMWSFilter wsfilter,
+                    boolean incremental,
+                    boolean doIndexing)
+  {
+    return m_dtmManager.getDTM(source, unique, wsfilter, 
+                               incremental, doIndexing);
+  }
+                             
+  /**
+   * Get an instance of a DTM that "owns" a node handle. 
+   *
+   * @param nodeHandle the nodeHandle.
+   *
+   * @return a non-null DTM reference.
+   */
+  public DTM getDTM(int nodeHandle)
+  {
+    return m_dtmManager.getDTM(nodeHandle);
+  }
+
+  /**
+   * Given a W3C DOM node, try and return a DTM handle.
+   * Note: calling this may be non-optimal.
+   * 
+   * @param node Non-null reference to a DOM node.
+   * 
+   * @return a valid DTM handle.
+   */
+  public int getDTMHandleFromNode(org.w3c.dom.Node node)
+  {
+    return m_dtmManager.getDTMHandleFromNode(node);
+  }
+//
+//  
+  /**
+   * %TBD% Doc
+   */
+  public int getDTMIdentity(DTM dtm)
+  {
+    return m_dtmManager.getDTMIdentity(dtm);
+  }
+//  
+  /**
+   * Creates an empty <code>DocumentFragment</code> object. 
+   * @return A new <code>DocumentFragment handle</code>.
+   */
+  public DTM createDocumentFragment()
+  {
+    return m_dtmManager.createDocumentFragment();
+  }
+//  
+  /**
+   * Release a DTM either to a lru pool, or completely remove reference.
+   * DTMs without system IDs are always hard deleted.
+   * State: experimental.
+   * 
+   * @param dtm The DTM to be released.
+   * @param shouldHardDelete True if the DTM should be removed no matter what.
+   * @return true if the DTM was removed, false if it was put back in a lru pool.
+   */
+  public boolean release(DTM dtm, boolean shouldHardDelete)
+  {
+    // %REVIEW% If it's a DTM which may contain multiple Result Tree
+    // Fragments, we can't discard it unless we know not only that it
+    // is empty, but that the XPathContext itself is going away. So do
+    // _not_ accept the request. (May want to do it as part of
+    // reset(), though.)
+    if(m_rtfdtm_stack!=null && m_rtfdtm_stack.contains(dtm))
+    {
+      return false;
+    }
+  	
+    return m_dtmManager.release(dtm, shouldHardDelete);
+  }
+
+  /**
+   * Create a new <code>DTMIterator</code> based on an XPath
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param xpathCompiler ??? Somehow we need to pass in a subpart of the
+   * expression.  I hate to do this with strings, since the larger expression
+   * has already been parsed.
+   *
+   * @param pos The position in the expression.
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public DTMIterator createDTMIterator(Object xpathCompiler, int pos)
+  {
+    return m_dtmManager.createDTMIterator(xpathCompiler, pos);
+  }
+//
+  /**
+   * Create a new <code>DTMIterator</code> based on an XPath
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param xpathString Must be a valid string expressing a
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
+   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+   *
+   * @param presolver An object that can resolve prefixes to namespace URLs.
+   *
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public DTMIterator createDTMIterator(String xpathString,
+          PrefixResolver presolver)
+  {
+    return m_dtmManager.createDTMIterator(xpathString, presolver);
+  }
+//
+  /**
+   * Create a new <code>DTMIterator</code> based only on a whatToShow and
+   * a DTMFilter.  The traversal semantics are defined as the descendant
+   * access.
+   *
+   * @param whatToShow This flag specifies which node types may appear in
+   *   the logical view of the tree presented by the iterator. See the
+   *   description of <code>NodeFilter</code> for the set of possible
+   *   <code>SHOW_</code> values.These flags can be combined using
+   *   <code>OR</code>.
+   * @param filter The <code>NodeFilter</code> to be used with this
+   *   <code>TreeWalker</code>, or <code>null</code> to indicate no filter.
+   * @param entityReferenceExpansion The value of this flag determines
+   *   whether entity reference nodes are expanded.
+   *
+   * @return The newly created <code>NodeIterator</code>.
+   */
+  public DTMIterator createDTMIterator(int whatToShow,
+          DTMFilter filter, boolean entityReferenceExpansion)
+  {
+    return m_dtmManager.createDTMIterator(whatToShow, filter, entityReferenceExpansion);
+  }
+  
+  /**
+   * Create a new <code>DTMIterator</code> that holds exactly one node.
+   *
+   * @param node The node handle that the DTMIterator will iterate to.
+   *
+   * @return The newly created <code>DTMIterator</code>.
+   */
+  public DTMIterator createDTMIterator(int node)
+  {
+    // DescendantIterator iter = new DescendantIterator();
+    DTMIterator iter = new org.apache.xpath.axes.OneStepIteratorForward(Axis.SELF);
+    iter.setRoot(node, this);
+    return iter;
+    // return m_dtmManager.createDTMIterator(node);
+  }
+
+  /**
+   * Create an XPathContext instance.  This is equivalent to calling
+   * the {@link #XPathContext(boolean)} constructor with the value
+   * <code>true</code>.
+   */
+  public XPathContext() {
+    this(true);
+  }
+
+  /**
+   * Create an XPathContext instance.
+   * @param recursiveVarContext A <code>boolean</code> value indicating whether
+   *             the XPath context needs to support pushing of scopes for
+   *             variable resolution
+   */
+  public XPathContext(boolean recursiveVarContext) {
+    m_prefixResolvers.push(null);
+    m_currentNodes.push(DTM.NULL);
+    m_currentExpressionNodes.push(DTM.NULL);
+    m_saxLocations.push(null);
+    m_variableStacks = recursiveVarContext ? new VariableStack()
+                                           : new VariableStack(1);
+  }
+
+  /**
+   * Create an XPathContext instance.  This is equivalent to calling the
+   * constructor {@link #XPathContext(java.lang.Object,boolean)} with the
+   * value of the second parameter set to <code>true</code>.
+   * @param owner Value that can be retrieved via the getOwnerObject() method.
+   * @see #getOwnerObject
+   */
+  public XPathContext(Object owner)
+  {
+    this(owner, true);
+  }
+
+  /**
+   * Create an XPathContext instance.
+   * @param owner Value that can be retrieved via the getOwnerObject() method.
+   * @see #getOwnerObject
+   * @param recursiveVarContext A <code>boolean</code> value indicating whether
+   *             the XPath context needs to support pushing of scopes for
+   *             variable resolution
+   */
+  public XPathContext(Object owner, boolean recursiveVarContext) {
+    this(recursiveVarContext);
+    m_owner = owner;
+    try {
+      m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {});
+    }
+    catch (NoSuchMethodException nsme) {}
+  }
+
+  /**
+   * Reset for new run.
+   */
+  public void reset()
+  {
+    releaseDTMXRTreeFrags();
+  	// These couldn't be disposed of earlier (see comments in release()); zap them now.
+  	if(m_rtfdtm_stack!=null)
+  		 for (java.util.Enumeration e = m_rtfdtm_stack.elements() ; e.hasMoreElements() ;) 
+  		 	m_dtmManager.release((DTM)e.nextElement(), true);
+
+    m_rtfdtm_stack=null; // drop our references too
+    m_which_rtfdtm=-1;
+    
+    if(m_global_rtfdtm!=null)
+  		 	m_dtmManager.release(m_global_rtfdtm,true);
+    m_global_rtfdtm=null;
+    
+  	
+    m_dtmManager = DTMManager.newInstance(
+                   org.apache.xpath.objects.XMLStringFactoryImpl.getFactory());
+                   
+    m_saxLocations.removeAllElements();   
+	m_axesIteratorStack.removeAllElements();
+	m_contextNodeLists.removeAllElements();
+	m_currentExpressionNodes.removeAllElements();
+	m_currentNodes.removeAllElements();
+	m_iteratorRoots.RemoveAllNoClear();
+	m_predicatePos.removeAllElements();
+	m_predicateRoots.RemoveAllNoClear();
+	m_prefixResolvers.removeAllElements();
+	
+	m_prefixResolvers.push(null);
+    m_currentNodes.push(DTM.NULL);
+    m_currentExpressionNodes.push(DTM.NULL);
+    m_saxLocations.push(null);
+  }
+
+  /** The current stylesheet locator. */
+  ObjectStack m_saxLocations = new ObjectStack(RECURSIONLIMIT);
+
+  /**
+   * Set the current locater in the stylesheet.
+   *
+   * @param location The location within the stylesheet.
+   */
+  public void setSAXLocator(SourceLocator location)
+  {
+    m_saxLocations.setTop(location);
+  }
+  
+  /**
+   * Set the current locater in the stylesheet.
+   *
+   * @param location The location within the stylesheet.
+   */
+  public void pushSAXLocator(SourceLocator location)
+  {
+    m_saxLocations.push(location);
+  }
+  
+  /**
+   * Push a slot on the locations stack so that setSAXLocator can be 
+   * repeatedly called.
+   *
+   */
+  public void pushSAXLocatorNull()
+  {
+    m_saxLocations.push(null);
+  }
+
+
+  /**
+   * Pop the current locater.
+   */
+  public void popSAXLocator()
+  {
+    m_saxLocations.pop();
+  }
+
+  /**
+   * Get the current locater in the stylesheet.
+   *
+   * @return The location within the stylesheet, or null if not known.
+   */
+  public SourceLocator getSAXLocator()
+  {
+    return (SourceLocator) m_saxLocations.peek();
+  }
+
+  /** The owner context of this XPathContext.  In the case of XSLT, this will be a
+   *  Transformer object.
+   */
+  private Object m_owner;
+
+  /** The owner context of this XPathContext.  In the case of XSLT, this will be a
+   *  Transformer object.
+   */
+  private Method m_ownerGetErrorListener;
+
+  /**
+   * Get the "owner" context of this context, which should be,
+   * in the case of XSLT, the Transformer object.  This is needed
+   * so that XSLT functions can get the Transformer.
+   * @return The owner object passed into the constructor, or null.
+   */
+  public Object getOwnerObject()
+  {
+    return m_owner;
+  }
+
+  // ================ VarStack ===================
+
+  /**
+   * The stack of Variable stacks.  A VariableStack will be
+   * pushed onto this stack for each template invocation.
+   */
+  private VariableStack m_variableStacks;
+
+  /**
+   * Get the variable stack, which is in charge of variables and
+   * parameters.
+   *
+   * @return the variable stack, which should not be null.
+   */
+  public final VariableStack getVarStack()
+  {
+    return m_variableStacks;
+  }
+
+  /** 
+   * Get the variable stack, which is in charge of variables and
+   * parameters.
+   *
+   * @param varStack non-null reference to the variable stack.
+   */
+  public final void setVarStack(VariableStack varStack)
+  {
+    m_variableStacks = varStack;
+  }
+
+  // ================ SourceTreeManager ===================
+
+  /** The source tree manager, which associates Source objects to source 
+   *  tree nodes. */
+  private SourceTreeManager m_sourceTreeManager = new SourceTreeManager();
+
+  /**
+   * Get the SourceTreeManager associated with this execution context.
+   *
+   * @return the SourceTreeManager associated with this execution context.
+   */
+  public final SourceTreeManager getSourceTreeManager()
+  {
+    return m_sourceTreeManager;
+  }
+
+  /**
+   * Set the SourceTreeManager associated with this execution context.
+   *
+   * @param mgr the SourceTreeManager to be associated with this 
+   *        execution context.
+   */
+  public void setSourceTreeManager(SourceTreeManager mgr)
+  {
+    m_sourceTreeManager = mgr;
+  }
+  
+  // =================================================
+
+  /** The ErrorListener where errors and warnings are to be reported.   */
+  private ErrorListener m_errorListener;
+
+  /** A default ErrorListener in case our m_errorListener was not specified and our
+   *  owner either does not have an ErrorListener or has a null one.
+   */
+  private ErrorListener m_defaultErrorListener;
+
+  /**
+   * Get the ErrorListener where errors and warnings are to be reported.
+   *
+   * @return A non-null ErrorListener reference.
+   */
+  public final ErrorListener getErrorListener()
+  {
+
+    if (null != m_errorListener)
+        return m_errorListener;
+
+    ErrorListener retval = null;
+
+    try {
+      if (null != m_ownerGetErrorListener)
+        retval = (ErrorListener) m_ownerGetErrorListener.invoke(m_owner, new Object[] {});
+    }
+    catch (Exception e) {}
+
+    if (null == retval)
+    {
+      if (null == m_defaultErrorListener) 
+        m_defaultErrorListener = new org.apache.xml.utils.DefaultErrorHandler();
+      retval = m_defaultErrorListener;
+    }
+
+    return retval;
+  }
+
+  /**
+   * Set the ErrorListener where errors and warnings are to be reported.
+   *
+   * @param listener A non-null ErrorListener reference.
+   */
+  public void setErrorListener(ErrorListener listener) throws IllegalArgumentException
+  {
+    if (listener == null) 
+      throw new IllegalArgumentException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler");
+    m_errorListener = listener;
+  }
+
+
+  // =================================================
+
+  /** The TrAX URI Resolver for resolving URIs from the document(...)
+   *  function to source tree nodes.  */
+  private URIResolver m_uriResolver;
+
+  /**
+   * Get the URIResolver associated with this execution context.
+   *
+   * @return a URI resolver, which may be null.
+   */
+  public final URIResolver getURIResolver()
+  {
+    return m_uriResolver;
+  }
+
+  /**
+   * Set the URIResolver associated with this execution context.
+   *
+   * @param resolver the URIResolver to be associated with this 
+   *        execution context, may be null to clear an already set resolver.
+   */
+  public void setURIResolver(URIResolver resolver)
+  {
+    m_uriResolver = resolver;
+  }
+
+  // =================================================
+
+  /** The reader of the primary source tree.    */
+  public XMLReader m_primaryReader;
+
+  /**
+   * Get primary XMLReader associated with this execution context.
+   *
+   * @return The reader of the primary source tree.
+   */
+  public final XMLReader getPrimaryReader()
+  {
+    return m_primaryReader;
+  }
+
+  /**
+   * Set primary XMLReader associated with this execution context.
+   *
+   * @param reader The reader of the primary source tree.
+   */
+  public void setPrimaryReader(XMLReader reader)
+  {
+    m_primaryReader = reader;
+  }
+
+  // =================================================
+
+
+  /** Misnamed string manager for XPath messages.  */
+  // private static XSLMessages m_XSLMessages = new XSLMessages();
+
+  /**
+   * Tell the user of an assertion error, and probably throw an
+   * exception.
+   *
+   * @param b  If false, a TransformerException will be thrown.
+   * @param msg The assertion message, which should be informative.
+   * 
+   * @throws javax.xml.transform.TransformerException if b is false.
+   */
+  private void assertion(boolean b, String msg) throws javax.xml.transform.TransformerException
+  {
+    if (!b) 
+    {
+      ErrorListener errorHandler = getErrorListener();
+
+      if (errorHandler != null)
+      {
+        errorHandler.fatalError(
+          new TransformerException(
+            XSLMessages.createMessage(
+              XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+              new Object[]{ msg }), (SAXSourceLocator)this.getSAXLocator()));
+      }
+    }
+  }
+
+  //==========================================================
+  // SECTION: Execution context state tracking
+  //==========================================================
+  
+  /**
+   * The current context node list.
+   */
+  private Stack m_contextNodeLists = new Stack();
+  
+  public Stack getContextNodeListsStack() { return m_contextNodeLists; }
+  public void setContextNodeListsStack(Stack s) { m_contextNodeLists = s; }
+
+  /**
+   * Get the current context node list.
+   *
+   * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
+   * also refered to here as a <term>context node list</term>.
+   */
+  public final DTMIterator getContextNodeList()
+  {
+
+    if (m_contextNodeLists.size() > 0)
+      return (DTMIterator) m_contextNodeLists.peek();
+    else
+      return null;
+  }
+
+  /**
+   * Set the current context node list.
+   *
+   * @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
+   * also refered to here as a <term>context node list</term>.
+   * @xsl.usage internal
+   */
+  public final void pushContextNodeList(DTMIterator nl)
+  {
+    m_contextNodeLists.push(nl);
+  }
+
+  /**
+   * Pop the current context node list.
+   * @xsl.usage internal
+   */
+  public final void popContextNodeList()
+  {
+  	if(m_contextNodeLists.isEmpty())
+  	  System.err.println("Warning: popContextNodeList when stack is empty!");
+  	else
+      m_contextNodeLists.pop();
+  }
+
+  /**
+   * The ammount to use for stacks that record information during the 
+   * recursive execution.
+   */
+  public static final int RECURSIONLIMIT = (1024*4);
+
+  /** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
+   *  Not to be confused with the current node list.  %REVIEW% Note that there 
+   *  are no bounds check and resize for this stack, so if it is blown, it's all 
+   *  over.  */
+  private IntStack m_currentNodes = new IntStack(RECURSIONLIMIT);
+   
+//  private NodeVector m_currentNodes = new NodeVector();
+  
+  public IntStack getCurrentNodeStack() {return m_currentNodes; }
+  public void setCurrentNodeStack(IntStack nv) { m_currentNodes = nv; }
+
+  /**
+   * Get the current context node.
+   *
+   * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
+   */
+  public final int getCurrentNode()
+  {
+    return m_currentNodes.peek();
+  }
+  
+  /**
+   * Set the current context node and expression node.
+   *
+   * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
+   * @param en the sub-expression context node.
+   */
+  public final void pushCurrentNodeAndExpression(int cn, int en)
+  {
+    m_currentNodes.push(cn);
+    m_currentExpressionNodes.push(cn);
+  }
+
+  /**
+   * Set the current context node.
+   */
+  public final void popCurrentNodeAndExpression()
+  {
+    m_currentNodes.quickPop(1);
+    m_currentExpressionNodes.quickPop(1);
+  }
+  
+  /**
+   * Push the current context node, expression node, and prefix resolver.
+   *
+   * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
+   * @param en the sub-expression context node.
+   * @param nc the namespace context (prefix resolver.
+   */
+  public final void pushExpressionState(int cn, int en, PrefixResolver nc)
+  {
+    m_currentNodes.push(cn);
+    m_currentExpressionNodes.push(cn);
+    m_prefixResolvers.push(nc);
+  }
+  
+  /**
+   * Pop the current context node, expression node, and prefix resolver.
+   */
+  public final void popExpressionState()
+  {
+    m_currentNodes.quickPop(1);
+    m_currentExpressionNodes.quickPop(1);
+    m_prefixResolvers.pop();
+  }
+
+
+
+  /**
+   * Set the current context node.
+   *
+   * @param n the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
+   */
+  public final void pushCurrentNode(int n)
+  {
+    m_currentNodes.push(n);
+  }
+  
+  /**
+   * Pop the current context node.
+   */
+  public final void popCurrentNode()
+  {
+    m_currentNodes.quickPop(1);
+  }
+  
+  /**
+   * Set the current predicate root.
+   */
+  public final void pushPredicateRoot(int n)
+  {
+    m_predicateRoots.push(n);
+  }
+
+  /**
+   * Pop the current predicate root.
+   */
+  public final void popPredicateRoot()
+  {
+    m_predicateRoots.popQuick();
+  }
+
+  /**
+   * Get the current predicate root.
+   */
+  public final int getPredicateRoot()
+  {
+    return m_predicateRoots.peepOrNull();
+  }
+  
+  /**
+   * Set the current location path iterator root.
+   */
+  public final void pushIteratorRoot(int n)
+  {
+    m_iteratorRoots.push(n);
+  }
+
+  /**
+   * Pop the current location path iterator root.
+   */
+  public final void popIteratorRoot()
+  {
+    m_iteratorRoots.popQuick();
+  }
+
+  /**
+   * Get the current location path iterator root.
+   */
+  public final int getIteratorRoot()
+  {
+    return m_iteratorRoots.peepOrNull();
+  }
+  
+  /** A stack of the current sub-expression nodes.  */
+  private NodeVector m_iteratorRoots = new NodeVector();
+
+  /** A stack of the current sub-expression nodes.  */
+  private NodeVector m_predicateRoots = new NodeVector();
+
+  /** A stack of the current sub-expression nodes.  */
+  private IntStack m_currentExpressionNodes = new IntStack(RECURSIONLIMIT);
+  
+     
+  public IntStack getCurrentExpressionNodeStack() { return m_currentExpressionNodes; }
+  public void setCurrentExpressionNodeStack(IntStack nv) { m_currentExpressionNodes = nv; }
+  
+  private IntStack m_predicatePos = new IntStack();
+  
+  public final int getPredicatePos()
+  {
+    return m_predicatePos.peek();
+  }
+
+  public final void pushPredicatePos(int n)
+  {
+    m_predicatePos.push(n);
+  }
+
+  public final void popPredicatePos()
+  {
+    m_predicatePos.pop();
+  }
+
+  /**
+   * Get the current node that is the expression's context (i.e. for current() support).
+   *
+   * @return The current sub-expression node.
+   */
+  public final int getCurrentExpressionNode()
+  {
+    return m_currentExpressionNodes.peek();
+  }
+
+  /**
+   * Set the current node that is the expression's context (i.e. for current() support).
+   *
+   * @param n The sub-expression node to be current.
+   */
+  public final void pushCurrentExpressionNode(int n)
+  {
+    m_currentExpressionNodes.push(n);
+  }
+
+  /**
+   * Pop the current node that is the expression's context 
+   * (i.e. for current() support).
+   */
+  public final void popCurrentExpressionNode()
+  {
+    m_currentExpressionNodes.quickPop(1);
+  }
+  
+  private ObjectStack m_prefixResolvers 
+                                   = new ObjectStack(RECURSIONLIMIT);
+
+  /**
+   * Get the current namespace context for the xpath.
+   *
+   * @return the current prefix resolver for resolving prefixes to 
+   *         namespace URLs.
+   */
+  public final PrefixResolver getNamespaceContext()
+  {
+    return (PrefixResolver) m_prefixResolvers.peek();
+  }
+
+  /**
+   * Get the current namespace context for the xpath.
+   *
+   * @param pr the prefix resolver to be used for resolving prefixes to 
+   *         namespace URLs.
+   */
+  public final void setNamespaceContext(PrefixResolver pr)
+  {
+    m_prefixResolvers.setTop(pr);
+  }
+
+  /**
+   * Push a current namespace context for the xpath.
+   *
+   * @param pr the prefix resolver to be used for resolving prefixes to 
+   *         namespace URLs.
+   */
+  public final void pushNamespaceContext(PrefixResolver pr)
+  {
+    m_prefixResolvers.push(pr);
+  }
+  
+  /**
+   * Just increment the namespace contest stack, so that setNamespaceContext
+   * can be used on the slot.
+   */
+  public final void pushNamespaceContextNull()
+  {
+    m_prefixResolvers.push(null);
+  }
+
+  /**
+   * Pop the current namespace context for the xpath.
+   */
+  public final void popNamespaceContext()
+  {
+    m_prefixResolvers.pop();
+  }
+
+  //==========================================================
+  // SECTION: Current TreeWalker contexts (for internal use)
+  //==========================================================
+
+  /**
+   * Stack of AxesIterators.
+   */
+  private Stack m_axesIteratorStack = new Stack();
+  
+  public Stack getAxesIteratorStackStacks() { return m_axesIteratorStack; }
+  public void setAxesIteratorStackStacks(Stack s) { m_axesIteratorStack = s; }
+
+  /**
+   * Push a TreeWalker on the stack.
+   *
+   * @param iter A sub-context AxesWalker.
+   * @xsl.usage internal
+   */
+  public final void pushSubContextList(SubContextList iter)
+  {
+    m_axesIteratorStack.push(iter);
+  }
+
+  /**
+   * Pop the last pushed axes iterator.
+   * @xsl.usage internal
+   */
+  public final void popSubContextList()
+  {
+    m_axesIteratorStack.pop();
+  }
+
+  /**
+   * Get the current axes iterator, or return null if none.
+   *
+   * @return the sub-context node list.
+   * @xsl.usage internal
+   */
+  public SubContextList getSubContextList()
+  {
+    return m_axesIteratorStack.isEmpty()
+           ? null : (SubContextList) m_axesIteratorStack.peek();
+  }
+  
+  /**
+   * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a> 
+   * as defined by the XSLT spec.
+   *
+   * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>.
+   * @xsl.usage internal
+   */
+
+  public org.apache.xpath.axes.SubContextList getCurrentNodeList()
+  {
+    return m_axesIteratorStack.isEmpty()
+           ? null : (SubContextList) m_axesIteratorStack.elementAt(0);
+  }
+  //==========================================================
+  // SECTION: Implementation of ExpressionContext interface
+  //==========================================================
+
+  /**
+   * Get the current context node.
+   * @return The current context node.
+   */
+  public final int getContextNode()
+  {
+    return this.getCurrentNode();
+  }
+
+  /**
+   * Get the current context node list.
+   * @return An iterator for the current context list, as
+   * defined in XSLT.
+   */
+  public final DTMIterator getContextNodes()
+  {
+
+    try
+    {
+      DTMIterator cnl = getContextNodeList();
+
+      if (null != cnl)
+        return cnl.cloneWithReset();
+      else
+        return null;  // for now... this might ought to be an empty iterator.
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      return null;  // error reporting?
+    }
+  }
+  
+  XPathExpressionContext expressionContext = new XPathExpressionContext();
+  
+  /**
+   * The the expression context for extensions for this context.
+   * 
+   * @return An object that implements the ExpressionContext.
+   */
+  public ExpressionContext getExpressionContext()
+  {
+    return expressionContext;
+  }
+  
+  public class XPathExpressionContext implements ExpressionContext
+  {
+    /**
+     * Return the XPathContext associated with this XPathExpressionContext.
+     * Extensions should use this judiciously and only when special processing
+     * requirements cannot be met another way.  Consider requesting an enhancement
+     * to the ExpressionContext interface to avoid having to call this method.
+     * @return the XPathContext associated with this XPathExpressionContext.
+     */
+     public XPathContext getXPathContext()
+     {
+       return XPathContext.this;
+     }
+
+    /**
+     * Return the DTMManager object.  Though XPathContext context extends 
+     * the DTMManager, it really is a proxy for the real DTMManager.  If a 
+     * caller needs to make a lot of calls to the DTMManager, it is faster 
+     * if it gets the real one from this function.
+     */
+     public DTMManager getDTMManager()
+     {
+       return m_dtmManager;
+     }
+    
+    /**
+     * Get the current context node.
+     * @return The current context node.
+     */
+    public org.w3c.dom.Node getContextNode()
+    {
+      int context = getCurrentNode();
+      
+      return getDTM(context).getNode(context);
+    }
+  
+    /**
+     * Get the current context node list.
+     * @return An iterator for the current context list, as
+     * defined in XSLT.
+     */
+    public org.w3c.dom.traversal.NodeIterator getContextNodes()
+    {
+      return new org.apache.xml.dtm.ref.DTMNodeIterator(getContextNodeList());
+    }
+
+    /**
+     * Get the error listener.
+     * @return The registered error listener.
+     */
+    public ErrorListener getErrorListener()
+    {
+      return XPathContext.this.getErrorListener();
+    }
+  
+    /**
+     * Get the value of a node as a number.
+     * @param n Node to be converted to a number.  May be null.
+     * @return value of n as a number.
+     */
+    public double toNumber(org.w3c.dom.Node n)
+    {
+      // %REVIEW% You can't get much uglier than this...
+      int nodeHandle = getDTMHandleFromNode(n);
+      DTM dtm = getDTM(nodeHandle);
+      XString xobj = (XString)dtm.getStringValue(nodeHandle);
+      return xobj.num();
+    }
+  
+    /**
+     * Get the value of a node as a string.
+     * @param n Node to be converted to a string.  May be null.
+     * @return value of n as a string, or an empty string if n is null.
+     */
+    public String toString(org.w3c.dom.Node n)
+    {
+      // %REVIEW% You can't get much uglier than this...
+      int nodeHandle = getDTMHandleFromNode(n);
+      DTM dtm = getDTM(nodeHandle);
+      XMLString strVal = dtm.getStringValue(nodeHandle);
+      return strVal.toString();
+    }
+
+    /**
+     * Get a variable based on it's qualified name.
+     * @param qname The qualified name of the variable.
+     * @return The evaluated value of the variable.
+     * @throws javax.xml.transform.TransformerException
+     */
+
+    public final XObject getVariableOrParam(org.apache.xml.utils.QName qname)
+              throws javax.xml.transform.TransformerException
+    {
+      return m_variableStacks.getVariableOrParam(XPathContext.this, qname);
+    }
+
+  }
+
+ /**
+   * Get a DTM to be used as a container for a global Result Tree
+   * Fragment. This will always be an instance of (derived from? equivalent to?) 
+   * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX 
+   * output to it. It may be a single DTM containing for multiple fragments, 
+   * if the implementation supports that.
+   * 
+   * Note: The distinction between this method and getRTFDTM() is that the latter
+   * allocates space from the dynamic variable stack (m_rtfdtm_stack), which may
+   * be pruned away again as the templates which defined those variables are exited.
+   * Global variables may be bound late (see XUnresolvedVariable), and never want to
+   * be discarded, hence we need to allocate them separately and don't actually need
+   * a stack to track them.
+   * 
+   * @return a non-null DTM reference.
+   */
+  public DTM getGlobalRTFDTM()
+  {
+  	// We probably should _NOT_ be applying whitespace filtering at this stage!
+  	//
+  	// Some magic has been applied in DTMManagerDefault to recognize this set of options
+  	// and generate an instance of DTM which can contain multiple documents
+  	// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
+  	// I didn't want to change the manager API at this time, or expose 
+  	// too many dependencies on its internals. (Ideally, I'd like to move
+  	// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
+  	// specify the subclass here.)
+
+	// If it doesn't exist, or if the one already existing is in the middle of
+	// being constructed, we need to obtain a new DTM to write into. I'm not sure
+	// the latter will ever arise, but I'd rather be just a bit paranoid..
+	if( m_global_rtfdtm==null || m_global_rtfdtm.isTreeIncomplete() )
+	{
+  		m_global_rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
+	}
+    return m_global_rtfdtm;
+  }
+  
+
+
+
+  /**
+   * Get a DTM to be used as a container for a dynamic Result Tree
+   * Fragment. This will always be an instance of (derived from? equivalent to?) 
+   * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX 
+   * output to it. It may be a single DTM containing for multiple fragments, 
+   * if the implementation supports that.
+   * 
+   * @return a non-null DTM reference.
+   */
+  public DTM getRTFDTM()
+  {
+  	SAX2RTFDTM rtfdtm;
+
+  	// We probably should _NOT_ be applying whitespace filtering at this stage!
+  	//
+  	// Some magic has been applied in DTMManagerDefault to recognize this set of options
+  	// and generate an instance of DTM which can contain multiple documents
+  	// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
+  	// I didn't want to change the manager API at this time, or expose 
+  	// too many dependencies on its internals. (Ideally, I'd like to move
+  	// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
+  	// specify the subclass here.)
+
+	if(m_rtfdtm_stack==null)
+	{
+		m_rtfdtm_stack=new Vector();
+  		rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
+    m_rtfdtm_stack.addElement(rtfdtm);
+		++m_which_rtfdtm;
+	}
+	else if(m_which_rtfdtm<0)
+	{
+		rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(++m_which_rtfdtm);
+	}
+	else
+	{
+		rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
+  		
+	  	// It might already be under construction -- the classic example would be
+ 	 	// an xsl:variable which uses xsl:call-template as part of its value. To
+  		// handle this recursion, we have to start a new RTF DTM, pushing the old
+  		// one onto a stack so we can return to it. This is not as uncommon a case
+  		// as we might wish, unfortunately, as some folks insist on coding XSLT
+  		// as if it were a procedural language...
+  		if(rtfdtm.isTreeIncomplete())
+	  	{
+	  		if(++m_which_rtfdtm < m_rtfdtm_stack.size())
+				rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
+	  		else
+	  		{
+		  		rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
+          m_rtfdtm_stack.addElement(rtfdtm); 	
+	  		}
+ 	 	}
+	}
+		
+    return rtfdtm;
+  }
+  
+  /** Push the RTFDTM's context mark, to allows discarding RTFs added after this
+   * point. (If it doesn't exist we don't push, since we might still be able to 
+   * get away with not creating it. That requires that excessive pops be harmless.)
+   * */
+  public void pushRTFContext()
+  {
+  	m_last_pushed_rtfdtm.push(m_which_rtfdtm);
+  	if(null!=m_rtfdtm_stack)
+	  	((SAX2RTFDTM)(getRTFDTM())).pushRewindMark();
+  }
+  
+  /** Pop the RTFDTM's context mark. This discards any RTFs added after the last
+   * mark was set. 
+   * 
+   * If there is no RTF DTM, there's nothing to pop so this
+   * becomes a no-op. If pushes were issued before this was called, we count on
+   * the fact that popRewindMark is defined such that overpopping just resets
+   * to empty.
+   * 
+   * Complicating factor: We need to handle the case of popping back to a previous
+   * RTF DTM, if one of the weird produce-an-RTF-to-build-an-RTF cases arose.
+   * Basically: If pop says this DTM is now empty, then return to the previous
+   * if one exists, in whatever state we left it in. UGLY, but hopefully the
+   * situation which forces us to consider this will arise exceedingly rarely.
+   * */
+  public void popRTFContext()
+  {
+  	int previous=m_last_pushed_rtfdtm.pop();
+  	if(null==m_rtfdtm_stack)
+  		return;
+  
+  	if(m_which_rtfdtm==previous)
+  	{
+  		if(previous>=0) // guard against none-active
+  		{
+	  		boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(previous))).popRewindMark();
+  		}
+  	}
+  	else while(m_which_rtfdtm!=previous)
+  	{
+  		// Empty each DTM before popping, so it's ready for reuse
+  		// _DON'T_ pop the previous, since it's still open (which is why we
+  		// stacked up more of these) and did not receive a mark.
+  		boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark();
+  		--m_which_rtfdtm; 
+  	}
+  }
+  
+  /**
+   * Gets DTMXRTreeFrag object if one has already been created.
+   * Creates new DTMXRTreeFrag object and adds to m_DTMXRTreeFrags  HashMap,
+   * otherwise.  
+   * @param dtmIdentity
+   * @return DTMXRTreeFrag
+   */
+  public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity){
+    if(m_DTMXRTreeFrags == null){
+      m_DTMXRTreeFrags = new HashMap();     
+    }
+    
+    if(m_DTMXRTreeFrags.containsKey(new Integer(dtmIdentity))){
+       return (DTMXRTreeFrag)m_DTMXRTreeFrags.get(new Integer(dtmIdentity));
+    }else{
+      final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,this);
+      m_DTMXRTreeFrags.put(new Integer(dtmIdentity),frag);
+      return frag ;
+    }   
+  }
+ 
+  /**
+   * Cleans DTMXRTreeFrag objects by removing references 
+   * to DTM and XPathContext objects.   
+   */
+  private final void releaseDTMXRTreeFrags(){
+    if(m_DTMXRTreeFrags == null){
+      return;
+    }
+    final Iterator iter = (m_DTMXRTreeFrags.values()).iterator();
+    while(iter.hasNext()){
+      DTMXRTreeFrag frag = (DTMXRTreeFrag)iter.next();
+      frag.destruct();
+      iter.remove();
+    }
+    m_DTMXRTreeFrags = null;
+ }
+}
diff --git a/src/main/java/org/apache/xpath/XPathException.java b/src/main/java/org/apache/xpath/XPathException.java
new file mode 100644
index 0000000..315a5d6
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathException.java
@@ -0,0 +1,328 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathException.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class implements an exception object that all
+ * XPath classes will throw in case of an error.  This class
+ * extends TransformerException, and may hold other exceptions. In the
+ * case of nested exceptions, printStackTrace will dump
+ * all the traces of the nested exceptions, not just the trace
+ * of this object.
+ * @xsl.usage general
+ */
+public class XPathException extends TransformerException
+{
+    static final long serialVersionUID = 4263549717619045963L;
+
+  /** The home of the expression that caused the error.
+   *  @serial  */
+  Object m_styleNode = null;
+
+  /**
+   * Get the stylesheet node from where this error originated.
+   * @return The stylesheet node from where this error originated, or null.
+   */
+  public Object getStylesheetNode()
+  {
+    return m_styleNode;
+  }
+  
+  /**
+   * Set the stylesheet node from where this error originated.
+   * @param styleNode The stylesheet node from where this error originated, or null.
+   */
+  public void setStylesheetNode(Object styleNode)
+  {
+    m_styleNode = styleNode;
+  }
+
+
+  /** A nested exception.
+   *  @serial   */
+  protected Exception m_exception;
+
+  /**
+   * Create an XPathException object that holds
+   * an error message.
+   * @param message The error message.
+   */
+  public XPathException(String message, ExpressionNode ex)
+  {
+    super(message);
+    this.setLocator(ex);
+    setStylesheetNode(getStylesheetNode(ex));
+  }
+  
+  /**
+   * Create an XPathException object that holds
+   * an error message.
+   * @param message The error message.
+   */
+  public XPathException(String message)
+  {
+    super(message);
+  }
+
+  
+  /**
+   * Get the XSLT ElemVariable that this sub-expression references.  In order for 
+   * this to work, the SourceLocator must be the owning ElemTemplateElement.
+   * @return The dereference to the ElemVariable, or null if not found.
+   */
+  public org.w3c.dom.Node getStylesheetNode(ExpressionNode ex)
+  {
+  	
+    ExpressionNode owner = getExpressionOwner(ex);
+
+    if (null != owner && owner instanceof org.w3c.dom.Node)
+    {
+		return ((org.w3c.dom.Node)owner);
+    }
+    return null;
+
+  }
+  
+  /**
+   * Get the first non-Expression parent of this node.
+   * @return null or first ancestor that is not an Expression.
+   */
+  protected ExpressionNode getExpressionOwner(ExpressionNode ex)
+  {
+  	ExpressionNode parent = ex.exprGetParent();
+  	while((null != parent) && (parent instanceof Expression))
+  		parent = parent.exprGetParent();
+  	return parent;
+  }
+
+
+
+  /**
+   * Create an XPathException object that holds
+   * an error message and the stylesheet node that
+   * the error originated from.
+   * @param message The error message.
+   * @param styleNode The stylesheet node that the error originated from.
+   */
+  public XPathException(String message, Object styleNode)
+  {
+
+    super(message);
+
+    m_styleNode = styleNode;
+  }
+
+  /**
+   * Create an XPathException object that holds
+   * an error message, the stylesheet node that
+   * the error originated from, and another exception
+   * that caused this exception.
+   * @param message The error message.
+   * @param styleNode The stylesheet node that the error originated from.
+   * @param e The exception that caused this exception.
+   */
+  public XPathException(String message, Node styleNode, Exception e)
+  {
+
+    super(message);
+
+    m_styleNode = styleNode;
+    this.m_exception = e;
+  }
+
+  /**
+   * Create an XPathException object that holds
+   * an error message, and another exception
+   * that caused this exception.
+   * @param message The error message.
+   * @param e The exception that caused this exception.
+   */
+  public XPathException(String message, Exception e)
+  {
+
+    super(message);
+
+    this.m_exception = e;
+  }
+
+  /**
+   * Print the the trace of methods from where the error
+   * originated.  This will trace all nested exception
+   * objects, as well as this object.
+   * @param s The stream where the dump will be sent to.
+   */
+  public void printStackTrace(java.io.PrintStream s)
+  {
+
+    if (s == null)
+      s = System.err;
+
+    try
+    {
+      super.printStackTrace(s);
+    }
+    catch (Exception e){}
+
+    Throwable exception = m_exception;
+
+    for (int i = 0; (i < 10) && (null != exception); i++)
+    {
+      s.println("---------");
+      exception.printStackTrace(s);
+
+      if (exception instanceof TransformerException)
+      {
+        TransformerException se = (TransformerException) exception;
+        Throwable prev = exception;
+
+        exception = se.getException();
+
+        if (prev == exception)
+          break;
+      }
+      else
+      {
+        exception = null;
+      }
+    }
+  }
+
+  /**
+   * Find the most contained message.
+   *
+   * @return The error message of the originating exception.
+   */
+  public String getMessage()
+  {
+
+    String lastMessage = super.getMessage();
+    Throwable exception = m_exception;
+
+    while (null != exception)
+    {
+      String nextMessage = exception.getMessage();
+
+      if (null != nextMessage)
+        lastMessage = nextMessage;
+
+      if (exception instanceof TransformerException)
+      {
+        TransformerException se = (TransformerException) exception;
+        Throwable prev = exception;
+
+        exception = se.getException();
+
+        if (prev == exception)
+          break;
+      }
+      else
+      {
+        exception = null;
+      }
+    }
+
+    return (null != lastMessage) ? lastMessage : "";
+  }
+
+  /**
+   * Print the the trace of methods from where the error
+   * originated.  This will trace all nested exception
+   * objects, as well as this object.
+   * @param s The writer where the dump will be sent to.
+   */
+  public void printStackTrace(java.io.PrintWriter s)
+  {
+
+    if (s == null)
+      s = new java.io.PrintWriter(System.err);
+        
+    try
+    {
+      super.printStackTrace(s);
+    }
+    catch (Exception e){}
+    
+    
+    boolean isJdk14OrHigher = false;
+    try {
+        Throwable.class.getMethod("getCause", (Class<?>) null);
+        isJdk14OrHigher = true;
+    } catch (NoSuchMethodException nsme) {
+        // do nothing
+    }
+        
+    // The printStackTrace method of the Throwable class in jdk 1.4 
+    // and higher will include the cause when printing the backtrace.
+    // The following code is only required when using jdk 1.3 or lower               
+    if (!isJdk14OrHigher) {
+    	        
+      Throwable exception = m_exception;
+
+      for (int i = 0; (i < 10) && (null != exception); i++)
+      {
+        s.println("---------");
+
+        try
+        {
+          exception.printStackTrace(s);
+        }
+        catch (Exception e)
+        {
+          s.println("Could not print stack trace...");
+        }
+
+        if (exception instanceof TransformerException)
+        {
+          TransformerException se = (TransformerException) exception;
+          Throwable prev = exception;
+
+          exception = se.getException();
+
+          if (prev == exception)
+          {
+            exception = null;
+
+            break;
+          }
+        }
+        else
+        {
+          exception = null;
+        }
+      }
+    }
+  }
+
+  /**
+   *  Return the embedded exception, if any.
+   *  Overrides javax.xml.transform.TransformerException.getException().
+   * 
+   *  @return The embedded exception, or null if there is none.
+   */
+  public Throwable getException()
+  {
+    return m_exception;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/XPathFactory.java b/src/main/java/org/apache/xpath/XPathFactory.java
new file mode 100644
index 0000000..df7df4a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathFactory.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xml.utils.PrefixResolver;
+
+/**
+ * Factory class for creating an XPath.  Implementors of XPath derivatives
+ * will need to make a derived class of this.
+ * @xsl.usage advanced
+ */
+public interface XPathFactory
+{
+
+  /**
+   * Create an XPath.
+   *
+   * @param exprString The XPath expression string.
+   * @param locator The location of the expression string, mainly for diagnostic
+   *                purposes.
+   * @param prefixResolver This will be called in order to resolve prefixes 
+   *        to namespace URIs.
+   * @param type One of {@link org.apache.xpath.XPath#SELECT} or 
+   *             {@link org.apache.xpath.XPath#MATCH}.
+   *
+   * @return an XPath ready for execution.
+   */
+  XPath create(String exprString, SourceLocator locator,
+               PrefixResolver prefixResolver, int type);
+}
diff --git a/src/main/java/org/apache/xpath/XPathProcessorException.java b/src/main/java/org/apache/xpath/XPathProcessorException.java
new file mode 100644
index 0000000..e3dcfea
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathProcessorException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathProcessorException.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+/**
+ * Derived from XPathException in order that XPath processor
+ * exceptions may be specifically caught.
+ * @xsl.usage general
+ */
+public class XPathProcessorException extends XPathException
+{
+    static final long serialVersionUID = 1215509418326642603L;
+
+  /**
+   * Create an XPathProcessorException object that holds
+   * an error message.
+   * @param message The error message.
+   */
+  public XPathProcessorException(String message)
+  {
+    super(message);
+  }
+  
+
+  /**
+   * Create an XPathProcessorException object that holds
+   * an error message, and another exception
+   * that caused this exception.
+   * @param message The error message.
+   * @param e The exception that caused this exception.
+   */
+  public XPathProcessorException(String message, Exception e)
+  {
+    super(message, e);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/XPathVisitable.java b/src/main/java/org/apache/xpath/XPathVisitable.java
new file mode 100644
index 0000000..271d4c2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathVisitable.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathVisitable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+/**
+ * A class that implements this interface will call a XPathVisitor 
+ * for itself and members within it's heararchy.  If the XPathVisitor's 
+ * method returns false, the sub-member heararchy will not be 
+ * traversed.
+ */
+public interface XPathVisitable
+{
+	/**
+	 * This will traverse the heararchy, calling the visitor for 
+	 * each member.  If the called visitor method returns 
+	 * false, the subtree should not be called.
+	 * 
+	 * @param owner The owner of the visitor, where that path may be 
+	 *              rewritten if needed.
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callVisitors(ExpressionOwner owner, XPathVisitor visitor);
+}
+
diff --git a/src/main/java/org/apache/xpath/XPathVisitor.java b/src/main/java/org/apache/xpath/XPathVisitor.java
new file mode 100644
index 0000000..b5375b4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/XPathVisitor.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathVisitor.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath;
+
+import org.apache.xpath.axes.LocPathIterator;
+import org.apache.xpath.axes.UnionPathIterator;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.Operation;
+import org.apache.xpath.operations.UnaryOperation;
+import org.apache.xpath.operations.Variable;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.patterns.StepPattern;
+import org.apache.xpath.patterns.UnionPattern;
+
+/**
+ * A derivation from this class can be passed to a class that implements 
+ * the XPathVisitable interface, to have the appropriate method called 
+ * for each component of the XPath.  Aside from possible other uses, the 
+ * main intention is to provide a reasonable means to perform expression 
+ * rewriting.
+ * 
+ * <p>Each method has the form 
+ * <code>boolean visitComponentType(ExpressionOwner owner, ComponentType compType)</code>. 
+ * The ExpressionOwner argument is the owner of the component, and can 
+ * be used to reset the expression for rewriting.  If a method returns 
+ * false, the sub hierarchy will not be traversed.</p>
+ * 
+ * <p>This class is meant to be a base class that will be derived by concrete classes, 
+ * and doesn't much except return true for each method.</p>
+ */
+public class XPathVisitor
+{
+	/**
+	 * Visit a LocationPath.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param path The LocationPath object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitLocationPath(ExpressionOwner owner, LocPathIterator path)
+	{
+		return true;
+	}
+
+	/**
+	 * Visit a UnionPath.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param path The UnionPath object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitUnionPath(ExpressionOwner owner, UnionPathIterator path)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a step within a location path.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param step The Step object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitStep(ExpressionOwner owner, NodeTest step)
+	{
+		return true;
+	}
+		
+	/**
+	 * Visit a predicate within a location path.  Note that there isn't a 
+	 * proper unique component for predicates, and that the expression will 
+	 * be called also for whatever type Expression is.
+	 * 
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param pred The predicate object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitPredicate(ExpressionOwner owner, Expression pred)
+	{
+		return true;
+	}
+
+	/**
+	 * Visit a binary operation.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param op The operation object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitBinaryOperation(ExpressionOwner owner, Operation op)
+	{
+		return true;
+	}
+
+	/**
+	 * Visit a unary operation.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param op The operation object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitUnaryOperation(ExpressionOwner owner, UnaryOperation op)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a variable reference.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param var The variable reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitVariableRef(ExpressionOwner owner, Variable var)
+	{
+		return true;
+	}
+
+	/**
+	 * Visit a function.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param func The function reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitFunction(ExpressionOwner owner, Function func)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a match pattern.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param pattern The match pattern object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitMatchPattern(ExpressionOwner owner, StepPattern pattern)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a union pattern.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param pattern The union pattern object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitUnionPattern(ExpressionOwner owner, UnionPattern pattern)
+	{
+		return true;
+	}
+	
+	/**
+	 * Visit a string literal.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param str The string literal object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitStringLiteral(ExpressionOwner owner, XString str)
+	{
+		return true;
+	}
+
+
+	/**
+	 * Visit a number literal.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param num The number literal object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitNumberLiteral(ExpressionOwner owner, XNumber num)
+	{
+		return true;
+	}
+
+
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/AttributeIterator.java b/src/main/java/org/apache/xpath/axes/AttributeIterator.java
new file mode 100644
index 0000000..b3cc1cc
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/AttributeIterator.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AttributeIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.compiler.Compiler;
+
+/**
+ * This class implements an optimized iterator for
+ * attribute axes patterns.
+ * @see org.apache.xpath.axes#ChildTestIterator
+ * @xsl.usage advanced
+ */
+public class AttributeIterator extends ChildTestIterator
+{
+    static final long serialVersionUID = -8417986700712229686L;
+
+  /**
+   * Create a AttributeIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  AttributeIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis);
+  }
+    
+  /**
+   * Get the next node via getFirstAttribute && getNextAttribute.
+   */
+  protected int getNextNode()
+  {
+    m_lastFetched = (DTM.NULL == m_lastFetched)
+                     ? m_cdtm.getFirstAttribute(m_context)
+                     : m_cdtm.getNextAttribute(m_lastFetched);
+    return m_lastFetched;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return org.apache.xml.dtm.Axis.ATTRIBUTE;
+  }
+
+
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/AxesWalker.java b/src/main/java/org/apache/xpath/axes/AxesWalker.java
new file mode 100644
index 0000000..524d004
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/AxesWalker.java
@@ -0,0 +1,590 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: AxesWalker.java 513117 2007-03-01 03:28:52Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import java.util.Vector;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Serves as common interface for axes Walkers, and stores common
+ * state variables.
+ */
+public class AxesWalker extends PredicatedNodeTest
+        implements Cloneable, PathComponent, ExpressionOwner
+{
+    static final long serialVersionUID = -2966031951306601247L;
+  
+  /**
+   * Construct an AxesWalker using a LocPathIterator.
+   *
+   * @param locPathIterator non-null reference to the parent iterator.
+   */
+  public AxesWalker(LocPathIterator locPathIterator, int axis)
+  {
+    super( locPathIterator );
+    m_axis = axis;
+  }
+  
+  public final WalkingIterator wi()
+  {
+    return (WalkingIterator)m_lpi;
+  }
+
+  /**
+   * Initialize an AxesWalker during the parse of the XPath expression.
+   *
+   * @param compiler The Compiler object that has information about this 
+   *                 walker in the op map.
+   * @param opPos The op code position of this location step.
+   * @param stepType  The type of location step.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void init(Compiler compiler, int opPos, int stepType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    initPredicateInfo(compiler, opPos);
+
+    // int testType = compiler.getOp(nodeTestOpPos);
+  }
+
+  /**
+   * Get a cloned AxesWalker.
+   *
+   * @return A new AxesWalker that can be used without mutating this one.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+    // Do not access the location path itterator during this operation!
+    
+    AxesWalker clone = (AxesWalker) super.clone();
+
+    //clone.setCurrentNode(clone.m_root);
+
+    // clone.m_isFresh = true;
+
+    return clone;
+  }
+  
+  /**
+   * Do a deep clone of this walker, including next and previous walkers.
+   * If the this AxesWalker is on the clone list, don't clone but 
+   * return the already cloned version.
+   * 
+   * @param cloneOwner non-null reference to the cloned location path 
+   *                   iterator to which this clone will be added.
+   * @param cloneList non-null vector of sources in odd elements, and the 
+   *                  corresponding clones in even vectors.
+   * 
+   * @return non-null clone, which may be a new clone, or may be a clone 
+   *         contained on the cloneList.
+   */
+  AxesWalker cloneDeep(WalkingIterator cloneOwner, Vector cloneList)
+     throws CloneNotSupportedException
+  {
+    AxesWalker clone = findClone(this, cloneList);
+    if(null != clone)
+      return clone;
+    clone = (AxesWalker)this.clone();
+    clone.setLocPathIterator(cloneOwner);
+    if(null != cloneList)
+    {
+      cloneList.addElement(this);
+      cloneList.addElement(clone);
+    }
+    
+    if(wi().m_lastUsedWalker == this)
+      cloneOwner.m_lastUsedWalker = clone;
+      
+    if(null != m_nextWalker)
+      clone.m_nextWalker = m_nextWalker.cloneDeep(cloneOwner, cloneList);
+      
+    // If you don't check for the cloneList here, you'll go into an 
+    // recursive infinate loop.  
+    if(null != cloneList)
+    {
+      if(null != m_prevWalker)
+        clone.m_prevWalker = m_prevWalker.cloneDeep(cloneOwner, cloneList);
+    }
+    else
+    {
+      if(null != m_nextWalker)
+        clone.m_nextWalker.m_prevWalker = clone;
+    }
+    return clone;
+  }
+  
+  /**
+   * Find a clone that corresponds to the key argument.
+   * 
+   * @param key The original AxesWalker for which there may be a clone.
+   * @param cloneList vector of sources in odd elements, and the 
+   *                  corresponding clones in even vectors, may be null.
+   * 
+   * @return A clone that corresponds to the key, or null if key not found.
+   */
+  static AxesWalker findClone(AxesWalker key, Vector cloneList)
+  {
+    if(null != cloneList)
+    {
+      // First, look for clone on list.
+      int n = cloneList.size();
+      for (int i = 0; i < n; i+=2) 
+      {
+        if(key == cloneList.elementAt(i))
+          return (AxesWalker)cloneList.elementAt(i+1);
+      }
+    }
+    return null;    
+  }
+  
+  /**
+   * Detaches the walker from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state.
+   */
+  public void detach()
+  { 
+  	m_currentNode = DTM.NULL;
+  	m_dtm = null;
+  	m_traverser = null;
+  	m_isFresh = true;
+  	m_root = DTM.NULL;
+  }
+  
+  //=============== TreeWalker Implementation ===============
+
+  /**
+   * The root node of the TreeWalker, as specified in setRoot(int root).
+   * Note that this may actually be below the current node.
+   *
+   * @return The context node of the step.
+   */
+  public int getRoot()
+  {
+    return m_root;
+  }
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+  	int axis = getAxis();
+  	int bit = WalkerFactory.getAnalysisBitFromAxes(axis);
+  	return bit;
+  }
+
+  /**
+   * Set the root node of the TreeWalker.
+   * (Not part of the DOM2 TreeWalker interface).
+   *
+   * @param root The context node of this step.
+   */
+  public void setRoot(int root)
+  {
+    // %OPT% Get this directly from the lpi.
+    XPathContext xctxt = wi().getXPathContext();
+    m_dtm = xctxt.getDTM(root);
+    m_traverser = m_dtm.getAxisTraverser(m_axis);
+    m_isFresh = true;
+    m_foundLast = false;
+    m_root = root;
+    m_currentNode = root;
+
+    if (DTM.NULL == root)
+    {
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_SETTING_WALKER_ROOT_TO_NULL, null)); //"\n !!!! Error! Setting the root of a walker to null!!!");
+    }
+
+    resetProximityPositions();
+  }
+
+  /**
+   * The node at which the TreeWalker is currently positioned.
+   * <br> The value must not be null. Alterations to the DOM tree may cause
+   * the current node to no longer be accepted by the TreeWalker's
+   * associated filter. currentNode may also be explicitly set to any node,
+   * whether or not it is within the subtree specified by the root node or
+   * would be accepted by the filter and whatToShow flags. Further
+   * traversal occurs relative to currentNode even if it is not part of the
+   * current view by applying the filters in the requested direction (not
+   * changing currentNode where no traversal is possible).
+   *
+   * @return The node at which the TreeWalker is currently positioned, only null 
+   * if setRoot has not yet been called.
+   */
+  public final int getCurrentNode()
+  {
+    return m_currentNode;
+  }
+
+  /**
+   * Set the next walker in the location step chain.
+   *
+   *
+   * @param walker Reference to AxesWalker derivative, or may be null.
+   */
+  public void setNextWalker(AxesWalker walker)
+  {
+    m_nextWalker = walker;
+  }
+
+  /**
+   * Get the next walker in the location step chain.
+   *
+   *
+   * @return Reference to AxesWalker derivative, or null.
+   */
+  public AxesWalker getNextWalker()
+  {
+    return m_nextWalker;
+  }
+
+  /**
+   * Set or clear the previous walker reference in the location step chain.
+   *
+   *
+   * @param walker Reference to previous walker reference in the location 
+   *               step chain, or null.
+   */
+  public void setPrevWalker(AxesWalker walker)
+  {
+    m_prevWalker = walker;
+  }
+
+  /**
+   * Get the previous walker reference in the location step chain.
+   *
+   *
+   * @return Reference to previous walker reference in the location 
+   *               step chain, or null.
+   */
+  public AxesWalker getPrevWalker()
+  {
+    return m_prevWalker;
+  }
+
+  /**
+   * This is simply a way to bottle-neck the return of the next node, for 
+   * diagnostic purposes.
+   *
+   * @param n Node to return, or null.
+   *
+   * @return The argument.
+   */
+  private int returnNextNode(int n)
+  {
+
+    return n;
+  }
+
+  /**
+   * Get the next node in document order on the axes.
+   *
+   * @return the next node in document order on the axes, or null.
+   */
+  protected int getNextNode()
+  {
+    if (m_foundLast)
+      return DTM.NULL;
+
+    if (m_isFresh)
+    {
+      m_currentNode = m_traverser.first(m_root);
+      m_isFresh = false;
+    }
+    // I shouldn't have to do this the check for current node, I think.
+    // numbering\numbering24.xsl fails if I don't do this.  I think 
+    // it occurs as the walkers are backing up. -sb
+    else if(DTM.NULL != m_currentNode) 
+    {
+      m_currentNode = m_traverser.next(m_root, m_currentNode);
+    }
+
+    if (DTM.NULL == m_currentNode)
+      this.m_foundLast = true;
+
+    return m_currentNode;
+  }
+
+  /**
+   *  Moves the <code>TreeWalker</code> to the next visible node in document
+   * order relative to the current node, and returns the new node. If the
+   * current node has no next node,  or if the search for nextNode attempts
+   * to step upward from the TreeWalker's root node, returns
+   * <code>null</code> , and retains the current node.
+   * @return  The new node, or <code>null</code> if the current node has no
+   *   next node  in the TreeWalker's logical view.
+   */
+  public int nextNode()
+  {
+    int nextNode = DTM.NULL;
+    AxesWalker walker = wi().getLastUsedWalker();
+
+    while (true)
+    {
+      if (null == walker)
+        break;
+
+      nextNode = walker.getNextNode();
+
+      if (DTM.NULL == nextNode)
+      {
+
+        walker = walker.m_prevWalker;
+      }
+      else
+      {
+        if (walker.acceptNode(nextNode) != DTMIterator.FILTER_ACCEPT)
+        {
+          continue;
+        }
+
+        if (null == walker.m_nextWalker)
+        {
+          wi().setLastUsedWalker(walker);
+
+          // return walker.returnNextNode(nextNode);
+          break;
+        }
+        else
+        {
+          AxesWalker prev = walker;
+
+          walker = walker.m_nextWalker;
+
+          walker.setRoot(nextNode);
+
+          walker.m_prevWalker = prev;
+
+          continue;
+        }
+      }  // if(null != nextNode)
+    }  // while(null != walker)
+
+    return nextNode;
+  }
+
+  //============= End TreeWalker Implementation =============
+
+  /**
+   * Get the index of the last node that can be itterated to.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the index of the last node that can be itterated to.
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+
+    int pos = getProximityPosition();
+    
+    AxesWalker walker;
+
+    try
+    {
+      walker = (AxesWalker) clone();
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      return -1;
+    }
+
+    walker.setPredicateCount(m_predicateIndex);
+    walker.setNextWalker(null);
+    walker.setPrevWalker(null);
+
+    WalkingIterator lpi = wi();
+    AxesWalker savedWalker = lpi.getLastUsedWalker();
+
+    try
+    {
+      lpi.setLastUsedWalker(walker);
+
+      int next;
+
+      while (DTM.NULL != (next = walker.nextNode()))
+      {
+        pos++;
+      }
+
+      // TODO: Should probably save this in the iterator.
+    }
+    finally
+    {
+      lpi.setLastUsedWalker(savedWalker);
+    }
+
+    // System.out.println("pos: "+pos);
+    return pos;
+  }
+  
+  //============= State Data =============
+  
+  /**
+   * The DTM for the root.  This can not be used, or must be changed, 
+   * for the filter walker, or any walker that can have nodes 
+   * from multiple documents.
+   * Never, ever, access this value without going through getDTM(int node).
+   */
+  private DTM m_dtm;
+  
+  /**
+   * Set the DTM for this walker.
+   * 
+   * @param dtm Non-null reference to a DTM.
+   */
+  public void setDefaultDTM(DTM dtm)
+  {
+    m_dtm = dtm;
+  }
+  
+  /**
+   * Get the DTM for this walker.
+   * 
+   * @return Non-null reference to a DTM.
+   */
+  public DTM getDTM(int node)
+  {
+    //
+    return wi().getXPathContext().getDTM(node);
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * Warning: This can only be called after setRoot has been called!
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return true;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return m_axis;
+  }
+  
+  /**
+   * This will traverse the heararchy, calling the visitor for 
+   * each member.  If the called visitor method returns 
+   * false, the subtree should not be called.
+   * 
+   * @param owner The owner of the visitor, where that path may be 
+   *              rewritten if needed.
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	if(visitor.visitStep(owner, this))
+  	{
+  		callPredicateVisitors(visitor);
+  		if(null != m_nextWalker)
+  		{
+  			m_nextWalker.callVisitors(this, visitor);
+  		}
+  	}
+  }
+  
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_nextWalker;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_nextWalker = (AxesWalker)exp;
+  }
+  
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+                return false;
+
+      AxesWalker walker = (AxesWalker)expr;
+      if(this.m_axis != walker.m_axis)
+      	return false;
+
+      return true;
+    }
+
+  /**
+   *  The root node of the TreeWalker, as specified when it was created.
+   */
+  transient int m_root = DTM.NULL;
+
+  /**
+   *  The node at which the TreeWalker is currently positioned.
+   */
+  private transient int m_currentNode = DTM.NULL;
+  
+  /** True if an itteration has not begun.  */
+  transient boolean m_isFresh;
+
+  /** The next walker in the location step chain.
+   *  @serial  */
+  protected AxesWalker m_nextWalker;
+  
+  /** The previous walker in the location step chain, or null.
+   *  @serial   */
+  AxesWalker m_prevWalker;
+  
+  /** The traversal axis from where the nodes will be filtered. */
+  protected int m_axis = -1;
+
+  /** The DTM inner traversal class, that corresponds to the super axis. */
+  protected DTMAxisTraverser m_traverser; 
+}
diff --git a/src/main/java/org/apache/xpath/axes/BasicTestIterator.java b/src/main/java/org/apache/xpath/axes/BasicTestIterator.java
new file mode 100644
index 0000000..75a8135
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/BasicTestIterator.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: BasicTestIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpMap;
+
+/**
+ * Base for iterators that handle predicates.  Does the basic next 
+ * node logic, so all the derived iterator has to do is get the 
+ * next node.
+ */
+public abstract class BasicTestIterator extends LocPathIterator
+{
+    static final long serialVersionUID = 3505378079378096623L;
+  /**
+   * Create a LocPathIterator object.
+   *
+   * @param nscontext The namespace context for this iterator,
+   * should be OK if null.
+   */
+  protected BasicTestIterator()
+  {
+  }
+
+
+  /**
+   * Create a LocPathIterator object.
+   *
+   * @param nscontext The namespace context for this iterator,
+   * should be OK if null.
+   */
+  protected BasicTestIterator(PrefixResolver nscontext)
+  {
+
+    super(nscontext);
+  }
+
+  /**
+   * Create a LocPathIterator object, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected BasicTestIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, false);
+    
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+    int whatToShow = compiler.getWhatToShow(firstStepPos);
+
+    if ((0 == (whatToShow
+               & (DTMFilter.SHOW_ATTRIBUTE 
+               | DTMFilter.SHOW_NAMESPACE 
+               | DTMFilter.SHOW_ELEMENT
+               | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) 
+               || (whatToShow == DTMFilter.SHOW_ALL))
+      initNodeTest(whatToShow);
+    else
+    {
+      initNodeTest(whatToShow, compiler.getStepNS(firstStepPos),
+                              compiler.getStepLocalName(firstStepPos));
+    }
+    initPredicateInfo(compiler, firstStepPos);
+  }
+
+  /**
+   * Create a LocPathIterator object, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   * @param shouldLoadWalkers True if walkers should be
+   * loaded, or false if this is a derived iterator and
+   * it doesn't wish to load child walkers.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected BasicTestIterator(
+          Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
+            throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, shouldLoadWalkers);
+  }
+
+	
+  /**
+   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
+   * @return The next node on the axis, or DTM.NULL.
+   */
+  protected abstract int getNextNode();
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   *
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {      
+  	if(m_foundLast)
+  	{
+  		m_lastFetched = DTM.NULL;
+  		return DTM.NULL;
+  	}
+  		
+    if(DTM.NULL == m_lastFetched)
+    {
+      resetProximityPositions();
+    }
+
+    int next;
+    
+    org.apache.xpath.VariableStack vars;
+    int savedStart;
+    if (-1 != m_stackFrame)
+    {
+      vars = m_execContext.getVarStack();
+
+      // These three statements need to be combined into one operation.
+      savedStart = vars.getStackFrame();
+
+      vars.setStackFrame(m_stackFrame);
+    }
+    else
+    {
+      // Yuck.  Just to shut up the compiler!
+      vars = null;
+      savedStart = 0;
+    }
+    
+    try
+    {
+      do
+      {
+        next = getNextNode();
+  
+        if (DTM.NULL != next)
+        {
+          if(DTMIterator.FILTER_ACCEPT == acceptNode(next))
+            break;
+          else
+            continue;
+        }
+        else
+          break;
+      }
+      while (next != DTM.NULL);
+  
+      if (DTM.NULL != next)
+      {
+      	m_pos++;
+        return next;
+      }
+      else
+      {
+        m_foundLast = true;
+  
+        return DTM.NULL;
+      }
+    }
+    finally
+    {
+      if (-1 != m_stackFrame)
+      {
+        // These two statements need to be combined into one operation.
+        vars.setStackFrame(savedStart);
+      }
+    }
+  }
+  
+  /**
+   *  Get a cloned Iterator that is reset to the beginning
+   *  of the query.
+   * 
+   *  @return A cloned NodeIterator set of the start of the query.
+   * 
+   *  @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    ChildTestIterator clone = (ChildTestIterator) super.cloneWithReset();
+
+    clone.resetProximityPositions();
+
+    return clone;
+  }
+
+
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/ChildIterator.java b/src/main/java/org/apache/xpath/axes/ChildIterator.java
new file mode 100644
index 0000000..4ce7733
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/ChildIterator.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ChildIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Compiler;
+
+/**
+ * This class implements an optimized iterator for
+ * "node()" patterns, that is, any children of the
+ * context node.
+ * @see org.apache.xpath.axes.LocPathIterator
+ * @xsl.usage advanced
+ */
+public class ChildIterator extends LocPathIterator
+{
+    static final long serialVersionUID = -6935428015142993583L;
+
+  /**
+   * Create a ChildIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   * @param analysis Analysis bits of the entire pattern.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  ChildIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, false);
+
+    // This iterator matches all kinds of nodes
+    initNodeTest(DTMFilter.SHOW_ALL);
+  }
+  
+  /**
+   * Return the first node out of the nodeset, if this expression is 
+   * a nodeset expression.  This is the default implementation for 
+   * nodesets.
+   * <p>WARNING: Do not mutate this class from this function!</p>
+   * @param xctxt The XPath runtime context.
+   * @return the first node out of the nodeset, or DTM.NULL.
+   */
+  public int asNode(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException
+  {
+    int current = xctxt.getCurrentNode();
+    
+    DTM dtm = xctxt.getDTM(current);
+    
+    return dtm.getFirstChild(current);
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   *
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {
+  	if(m_foundLast)
+  		return DTM.NULL;
+
+    int next;
+
+    m_lastFetched = next = (DTM.NULL == m_lastFetched)
+                           ? m_cdtm.getFirstChild(m_context)
+                           : m_cdtm.getNextSibling(m_lastFetched);
+
+    // m_lastFetched = next;
+    if (DTM.NULL != next)
+    {
+      m_pos++;
+      return next;
+    }
+    else
+    {
+      m_foundLast = true;
+
+      return DTM.NULL;
+    }
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return org.apache.xml.dtm.Axis.CHILD;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/ChildTestIterator.java b/src/main/java/org/apache/xpath/axes/ChildTestIterator.java
new file mode 100644
index 0000000..ee33a4e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/ChildTestIterator.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ChildTestIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.compiler.Compiler;
+
+/**
+ * This class implements an optimized iterator for
+ * children patterns that have a node test, and possibly a predicate.
+ * @see org.apache.xpath.axes.BasicTestIterator
+ * @xsl.usage advanced
+ */
+public class ChildTestIterator extends BasicTestIterator
+{
+    static final long serialVersionUID = -7936835957960705722L;
+  /** The traverser to use to navigate over the descendants. */
+  transient protected DTMAxisTraverser m_traverser;
+  
+  /** The extended type ID, not set until setRoot. */
+//  protected int m_extendedTypeID;
+
+
+  /**
+   * Create a ChildTestIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  ChildTestIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis);
+  }
+  
+  /**
+   * Create a ChildTestIterator object.
+   *
+   * @param traverser Traverser that tells how the KeyIterator is to be handled.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public ChildTestIterator(DTMAxisTraverser traverser)
+  {
+
+    super(null);
+
+    m_traverser = traverser;
+  }
+
+  /**
+   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
+   * @return The next node on the axis, or DTM.NULL.
+   */
+  protected int getNextNode()
+  {                     
+    if(true /* 0 == m_extendedTypeID */)
+    {
+      m_lastFetched = (DTM.NULL == m_lastFetched)
+                   ? m_traverser.first(m_context)
+                   : m_traverser.next(m_context, m_lastFetched);
+    }
+//    else
+//    {
+//      m_lastFetched = (DTM.NULL == m_lastFetched)
+//                   ? m_traverser.first(m_context, m_extendedTypeID)
+//                   : m_traverser.next(m_context, m_lastFetched, 
+//                                      m_extendedTypeID);
+//    }
+
+    return m_lastFetched;
+  }
+
+  
+  /**
+   *  Get a cloned Iterator that is reset to the beginning
+   *  of the query.
+   * 
+   *  @return A cloned NodeIterator set of the start of the query.
+   * 
+   *  @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    ChildTestIterator clone = (ChildTestIterator) super.cloneWithReset();
+    clone.m_traverser = m_traverser;
+
+    return clone;
+  }
+  
+
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+    m_traverser = m_cdtm.getAxisTraverser(Axis.CHILD);
+    
+//    String localName = getLocalName();
+//    String namespace = getNamespace();
+//    int what = m_whatToShow;
+//    // System.out.println("what: ");
+//    // NodeTest.debugWhatToShow(what);
+//    if(DTMFilter.SHOW_ALL == what ||
+//       ((DTMFilter.SHOW_ELEMENT & what) == 0)
+//       || localName == NodeTest.WILD
+//       || namespace == NodeTest.WILD)
+//    {
+//      m_extendedTypeID = 0;
+//    }
+//    else
+//    {
+//      int type = getNodeTypeTest(what);
+//      m_extendedTypeID = m_cdtm.getExpandedTypeID(namespace, localName, type);
+//    }
+    
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return org.apache.xml.dtm.Axis.CHILD;
+  }
+
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {   
+    if(m_allowDetach)
+    {
+      m_traverser = null;
+      
+      // Always call the superclass detach last!
+      super.detach();
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/ContextNodeList.java b/src/main/java/org/apache/xpath/axes/ContextNodeList.java
new file mode 100644
index 0000000..f5e24ce
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/ContextNodeList.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ContextNodeList.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * Classes who implement this interface can be a
+ * <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
+ * also refered to here as a <term>context node list</term>.
+ * @xsl.usage advanced
+ */
+public interface ContextNodeList
+{
+
+  /**
+   * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
+   *
+   *
+   * @return The current node, or null.
+   */
+  public Node getCurrentNode();
+
+  /**
+   * Get the current position, which is one less than
+   * the next nextNode() call will retrieve.  i.e. if
+   * you call getCurrentPos() and the return is 0, the next
+   * fetch will take place at index 1.
+   *
+   * @return The position of the
+   * <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>
+   * in the  <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>.
+   */
+  public int getCurrentPos();
+
+  /**
+   * Reset the iterator.
+   */
+  public void reset();
+
+  /**
+   * If setShouldCacheNodes(true) is called, then nodes will
+   * be cached.  They are not cached by default.
+   *
+   * @param b true if the nodes should be cached.
+   */
+  public void setShouldCacheNodes(boolean b);
+
+  /**
+   * If an index is requested, NodeSetDTM will call this method
+   * to run the iterator to the index.  By default this sets
+   * m_next to the index.  If the index argument is -1, this
+   * signals that the iterator should be run to the end.
+   *
+   * @param index The index to run to, or -1 if the iterator should be run
+   *              to the end.
+   */
+  public void runTo(int index);
+
+  /**
+   * Set the current position in the node set.
+   * @param i Must be a valid index.
+   */
+  public void setCurrentPos(int i);
+
+  /**
+   * Get the length of the list.
+   *
+   * @return The number of nodes in this node list.
+   */
+  public int size();
+
+  /**
+   * Tells if this NodeSetDTM is "fresh", in other words, if
+   * the first nextNode() that is called will return the
+   * first node in the set.
+   *
+   * @return true if the iteration of this list has not yet begun.
+   */
+  public boolean isFresh();
+
+  /**
+   * Get a cloned Iterator that is reset to the start of the iteration.
+   *
+   * @return A clone of this iteration that has been reset.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public NodeIterator cloneWithReset() throws CloneNotSupportedException;
+
+  /**
+   * Get a clone of this iterator.  Be aware that this operation may be
+   * somewhat expensive.
+   *
+   *
+   * @return A clone of this object.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException;
+
+  /**
+   * Get the index of the last node in this list.
+   *
+   *
+   * @return the index of the last node in this list.
+   */
+  public int getLast();
+
+  /**
+   * Set the index of the last node in this list.
+   *
+   *
+   * @param last the index of the last node in this list.
+   */
+  public void setLast(int last);
+}
diff --git a/src/main/java/org/apache/xpath/axes/DescendantIterator.java b/src/main/java/org/apache/xpath/axes/DescendantIterator.java
new file mode 100644
index 0000000..5706125
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/DescendantIterator.java
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DescendantIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpCodes;
+import org.apache.xpath.compiler.OpMap;
+import org.apache.xpath.patterns.NodeTest;
+
+/**
+ * This class implements an optimized iterator for
+ * descendant, descendant-or-self, or "//foo" patterns.
+ * @see org.apache.xpath.axes.LocPathIterator
+ * @xsl.usage advanced
+ */
+public class DescendantIterator extends LocPathIterator
+{
+    static final long serialVersionUID = -1190338607743976938L;
+  /**
+   * Create a DescendantIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  DescendantIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+
+    super(compiler, opPos, analysis, false);
+
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+    int stepType = compiler.getOp(firstStepPos);
+
+    boolean orSelf = (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType);
+    boolean fromRoot = false;
+    if (OpCodes.FROM_SELF == stepType)
+    {
+      orSelf = true;
+      // firstStepPos += 8;
+    }
+    else if(OpCodes.FROM_ROOT == stepType)
+    {
+      fromRoot = true;
+      // Ugly code... will go away when AST work is done.
+      int nextStepPos = compiler.getNextStepPos(firstStepPos);
+      if(compiler.getOp(nextStepPos) == OpCodes.FROM_DESCENDANTS_OR_SELF)
+        orSelf = true;
+      // firstStepPos += 8;
+    }
+    
+    // Find the position of the last step.
+    int nextStepPos = firstStepPos;
+    while(true)
+    {
+      nextStepPos = compiler.getNextStepPos(nextStepPos);
+      if(nextStepPos > 0)
+      {
+        int stepOp = compiler.getOp(nextStepPos);
+        if(OpCodes.ENDOP != stepOp)
+          firstStepPos = nextStepPos;
+        else
+          break;
+      }
+      else
+        break;
+      
+    }
+    
+    // Fix for http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1336
+    if((analysis & WalkerFactory.BIT_CHILD) != 0)
+      orSelf = false;
+      
+    if(fromRoot)
+    {
+      if(orSelf)
+        m_axis = Axis.DESCENDANTSORSELFFROMROOT;
+      else
+        m_axis = Axis.DESCENDANTSFROMROOT;
+    }
+    else if(orSelf)
+      m_axis = Axis.DESCENDANTORSELF;
+    else
+      m_axis = Axis.DESCENDANT;
+
+    int whatToShow = compiler.getWhatToShow(firstStepPos);
+
+    if ((0 == (whatToShow
+               & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_ELEMENT
+                  | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) || 
+                   (whatToShow == DTMFilter.SHOW_ALL))
+      initNodeTest(whatToShow);
+    else
+    {
+      initNodeTest(whatToShow, compiler.getStepNS(firstStepPos),
+                              compiler.getStepLocalName(firstStepPos));
+    }
+    initPredicateInfo(compiler, firstStepPos);
+  }
+  
+  /**
+   * Create a DescendantIterator object.
+   *
+   */
+  public DescendantIterator()
+  {
+    super(null);
+    m_axis = Axis.DESCENDANTSORSELFFROMROOT;
+    int whatToShow = DTMFilter.SHOW_ALL;
+    initNodeTest(whatToShow);
+  }
+
+  
+  /**
+   *  Get a cloned Iterator that is reset to the beginning
+   *  of the query.
+   * 
+   *  @return A cloned NodeIterator set of the start of the query.
+   * 
+   *  @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    DescendantIterator clone = (DescendantIterator) super.cloneWithReset();
+    clone.m_traverser = m_traverser;
+
+    clone.resetProximityPositions();
+
+    return clone;
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   *
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   *
+   * @throws DOMException
+   *    INVALID_STATE_ERR: Raised if this method is called after the
+   *   <code>detach</code> method was invoked.
+   */
+  public int nextNode()
+  {
+   	if(m_foundLast)
+  		return DTM.NULL;
+
+    if(DTM.NULL == m_lastFetched)
+    {
+      resetProximityPositions();
+    }
+
+    int next;
+    
+    org.apache.xpath.VariableStack vars;
+    int savedStart;
+    if (-1 != m_stackFrame)
+    {
+      vars = m_execContext.getVarStack();
+
+      // These three statements need to be combined into one operation.
+      savedStart = vars.getStackFrame();
+
+      vars.setStackFrame(m_stackFrame);
+    }
+    else
+    {
+      // Yuck.  Just to shut up the compiler!
+      vars = null;
+      savedStart = 0;
+    }
+    
+    try
+    {
+      do
+      {
+        if(0 == m_extendedTypeID)
+        {
+          next = m_lastFetched = (DTM.NULL == m_lastFetched)
+                       ? m_traverser.first(m_context)
+                       : m_traverser.next(m_context, m_lastFetched);
+        }
+        else
+        {
+          next = m_lastFetched = (DTM.NULL == m_lastFetched)
+                       ? m_traverser.first(m_context, m_extendedTypeID)
+                       : m_traverser.next(m_context, m_lastFetched, 
+                                          m_extendedTypeID);
+        }
+  
+        if (DTM.NULL != next)
+        {
+          if(DTMIterator.FILTER_ACCEPT == acceptNode(next))
+            break;
+          else
+            continue;
+        }
+        else
+          break;
+      }
+      while (next != DTM.NULL);
+  
+      if (DTM.NULL != next)
+      {
+      	m_pos++;
+        return next;
+      }
+      else
+      {
+        m_foundLast = true;
+  
+        return DTM.NULL;
+      }
+    }
+    finally
+    {
+      if (-1 != m_stackFrame)
+      {
+        // These two statements need to be combined into one operation.
+        vars.setStackFrame(savedStart);
+      }
+    }
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+    m_traverser = m_cdtm.getAxisTraverser(m_axis);
+    
+    String localName = getLocalName();
+    String namespace = getNamespace();
+    int what = m_whatToShow;
+    // System.out.println("what: ");
+    // NodeTest.debugWhatToShow(what);
+    if(DTMFilter.SHOW_ALL == what
+       || NodeTest.WILD.equals(localName)
+       || NodeTest.WILD.equals(namespace))
+    {
+      m_extendedTypeID = 0;
+    }
+    else
+    {
+      int type = getNodeTypeTest(what);
+      m_extendedTypeID = m_cdtm.getExpandedTypeID(namespace, localName, type);
+    }
+    
+  }
+  
+  /**
+   * Return the first node out of the nodeset, if this expression is 
+   * a nodeset expression.  This is the default implementation for 
+   * nodesets.
+   * <p>WARNING: Do not mutate this class from this function!</p>
+   * @param xctxt The XPath runtime context.
+   * @return the first node out of the nodeset, or DTM.NULL.
+   */
+  public int asNode(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException
+  {
+    if(getPredicateCount() > 0)
+      return super.asNode(xctxt);
+
+    int current = xctxt.getCurrentNode();
+    
+    DTM dtm = xctxt.getDTM(current);
+    DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
+    
+    String localName = getLocalName();
+    String namespace = getNamespace();
+    int what = m_whatToShow;
+    
+    // System.out.print(" (DescendantIterator) ");
+    
+    // System.out.println("what: ");
+    // NodeTest.debugWhatToShow(what);
+    if(DTMFilter.SHOW_ALL == what
+       || localName == NodeTest.WILD
+       || namespace == NodeTest.WILD)
+    {
+      return traverser.first(current);
+    }
+    else
+    {
+      int type = getNodeTypeTest(what);
+      int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
+      return traverser.first(current, extendedType);
+    }
+  }
+  
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {
+    if (m_allowDetach) {
+      m_traverser = null;    
+      m_extendedTypeID = 0;
+
+      // Always call the superclass detach last!
+      super.detach();
+    }
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return m_axis;
+  }
+  
+  
+  /** The traverser to use to navigate over the descendants. */
+  transient protected DTMAxisTraverser m_traverser;
+  
+  /** The axis that we are traversing. */
+  protected int m_axis;
+  
+  /** The extended type ID, not set until setRoot. */
+  protected int m_extendedTypeID;
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(m_axis != ((DescendantIterator)expr).m_axis)
+  		return false;
+  		
+  	return true;
+  }
+
+  
+}
diff --git a/src/main/java/org/apache/xpath/axes/FilterExprIterator.java b/src/main/java/org/apache/xpath/axes/FilterExprIterator.java
new file mode 100644
index 0000000..60776d1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/FilterExprIterator.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XNodeSet;
+
+public class FilterExprIterator extends BasicTestIterator
+{
+    static final long serialVersionUID = 2552176105165737614L;
+  /** The contained expression. Should be non-null.
+   *  @serial   */
+  private Expression m_expr;
+
+  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
+  transient private XNodeSet m_exprObj;
+
+  private boolean m_mustHardReset = false;
+  private boolean m_canDetachNodeset = true;
+
+  /**
+   * Create a FilterExprIterator object.
+   *
+   */
+  public FilterExprIterator()
+  {
+    super(null);
+  }
+  
+  /**
+   * Create a FilterExprIterator object.
+   *
+   */
+  public FilterExprIterator(Expression expr)
+  {
+    super(null);
+    m_expr = expr;
+  }
+
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+  	super.setRoot(context, environment);
+ 	
+  	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context, 
+  	                  m_execContext, getPrefixResolver(), 
+  	                  getIsTopLevel(), m_stackFrame, m_expr);
+   }
+
+
+  /**
+   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
+   * @return The next node on the axis, or DTM.NULL.
+   */
+  protected int getNextNode()
+  {
+    if (null != m_exprObj)
+    {
+      m_lastFetched = m_exprObj.nextNode();
+    }
+    else
+      m_lastFetched = DTM.NULL;
+
+    return m_lastFetched;
+  }
+  
+  /**
+   * Detaches the walker from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state.
+   */
+  public void detach()
+  {  
+  	super.detach();
+  	m_exprObj.detach();
+  	m_exprObj = null;
+  }
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    m_expr.fixupVariables(vars, globalsSize);
+  }
+
+  /**
+   * Get the inner contained expression of this filter.
+   */
+  public Expression getInnerExpression()
+  {
+    return m_expr;
+  }
+
+  /**
+   * Set the inner contained expression of this filter.
+   */
+  public void setInnerExpression(Expression expr)
+  {
+    expr.exprSetParent(this);
+    m_expr = expr;
+  }
+
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+    if (null != m_expr && m_expr instanceof PathComponent)
+    {
+      return ((PathComponent) m_expr).getAnalysisBits();
+    }
+    return WalkerFactory.BIT_FILTER;
+  }
+
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * Warning: This can only be called after setRoot has been called!
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return m_exprObj.isDocOrdered();
+  }
+
+  class filterExprOwner implements ExpressionOwner
+  {
+    /**
+    * @see ExpressionOwner#getExpression()
+    */
+    public Expression getExpression()
+    {
+      return m_expr;
+    }
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+      exp.exprSetParent(FilterExprIterator.this);
+      m_expr = exp;
+    }
+
+  }
+
+  /**
+   * This will traverse the heararchy, calling the visitor for 
+   * each member.  If the called visitor method returns 
+   * false, the subtree should not be called.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callPredicateVisitors(XPathVisitor visitor)
+  {
+    m_expr.callVisitors(new filterExprOwner(), visitor);
+
+    super.callPredicateVisitors(visitor);
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+    if (!super.deepEquals(expr))
+      return false;
+
+    FilterExprIterator fet = (FilterExprIterator) expr;
+    if (!m_expr.deepEquals(fet.m_expr))
+      return false;
+
+    return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/FilterExprIteratorSimple.java b/src/main/java/org/apache/xpath/axes/FilterExprIteratorSimple.java
new file mode 100644
index 0000000..9f11944
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/FilterExprIteratorSimple.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FilterExprIteratorSimple.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XNodeSet;
+
+/**
+ * Class to use for one-step iteration that doesn't have a predicate, and 
+ * doesn't need to set the context.
+ */
+public class FilterExprIteratorSimple extends LocPathIterator
+{
+    static final long serialVersionUID = -6978977187025375579L;
+  /** The contained expression. Should be non-null.
+   *  @serial   */
+  private Expression m_expr;
+
+  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
+  transient private XNodeSet m_exprObj;
+
+  private boolean m_mustHardReset = false;
+  private boolean m_canDetachNodeset = true;
+
+  /**
+   * Create a FilterExprIteratorSimple object.
+   *
+   */
+  public FilterExprIteratorSimple()
+  {
+    super(null);
+  }
+  
+  /**
+   * Create a FilterExprIteratorSimple object.
+   *
+   */
+  public FilterExprIteratorSimple(Expression expr)
+  {
+    super(null);
+    m_expr = expr;
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+  	super.setRoot(context, environment);
+  	m_exprObj = executeFilterExpr(context, m_execContext, getPrefixResolver(), 
+  	                  getIsTopLevel(), m_stackFrame, m_expr);
+  }
+
+  /**
+   * Execute the expression.  Meant for reuse by other FilterExpr iterators 
+   * that are not derived from this object.
+   */
+  public static XNodeSet executeFilterExpr(int context, XPathContext xctxt, 
+  												PrefixResolver prefixResolver,
+  												boolean isTopLevel,
+  												int stackFrame,
+  												Expression expr )
+    throws org.apache.xml.utils.WrappedRuntimeException
+  {
+    PrefixResolver savedResolver = xctxt.getNamespaceContext();
+    XNodeSet result = null;
+
+    try
+    {
+      xctxt.pushCurrentNode(context);
+      xctxt.setNamespaceContext(prefixResolver);
+
+      // The setRoot operation can take place with a reset operation, 
+      // and so we may not be in the context of LocPathIterator#nextNode, 
+      // so we have to set up the variable context, execute the expression, 
+      // and then restore the variable context.
+
+      if (isTopLevel)
+      {
+        // System.out.println("calling m_expr.execute(getXPathContext())");
+        VariableStack vars = xctxt.getVarStack();
+
+        // These three statements need to be combined into one operation.
+        int savedStart = vars.getStackFrame();
+        vars.setStackFrame(stackFrame);
+
+        result = (org.apache.xpath.objects.XNodeSet) expr.execute(xctxt);
+        result.setShouldCacheNodes(true);
+
+        // These two statements need to be combined into one operation.
+        vars.setStackFrame(savedStart);
+      }
+      else
+          result = (org.apache.xpath.objects.XNodeSet) expr.execute(xctxt);
+
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: Fix...
+      throw new org.apache.xml.utils.WrappedRuntimeException(se);
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      xctxt.setNamespaceContext(savedResolver);
+    }
+    return result;
+  }
+  
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   *
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {
+  	if(m_foundLast)
+  		return DTM.NULL;
+
+    int next;
+
+    if (null != m_exprObj)
+    {
+      m_lastFetched = next = m_exprObj.nextNode();
+    }
+    else
+      m_lastFetched = next = DTM.NULL;
+
+    // m_lastFetched = next;
+    if (DTM.NULL != next)
+    {
+      m_pos++;
+      return next;
+    }
+    else
+    {
+      m_foundLast = true;
+
+      return DTM.NULL;
+    }
+  }
+  
+  /**
+   * Detaches the walker from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state.
+   */
+  public void detach()
+  {  
+    if(m_allowDetach)
+    {
+  		super.detach();
+  		m_exprObj.detach();
+  		m_exprObj = null;
+    }
+  }
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    m_expr.fixupVariables(vars, globalsSize);
+  }
+
+  /**
+   * Get the inner contained expression of this filter.
+   */
+  public Expression getInnerExpression()
+  {
+    return m_expr;
+  }
+
+  /**
+   * Set the inner contained expression of this filter.
+   */
+  public void setInnerExpression(Expression expr)
+  {
+    expr.exprSetParent(this);
+    m_expr = expr;
+  }
+
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+    if (null != m_expr && m_expr instanceof PathComponent)
+    {
+      return ((PathComponent) m_expr).getAnalysisBits();
+    }
+    return WalkerFactory.BIT_FILTER;
+  }
+
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * Warning: This can only be called after setRoot has been called!
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return m_exprObj.isDocOrdered();
+  }
+
+  class filterExprOwner implements ExpressionOwner
+  {
+    /**
+    * @see ExpressionOwner#getExpression()
+    */
+    public Expression getExpression()
+    {
+      return m_expr;
+    }
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+      exp.exprSetParent(FilterExprIteratorSimple.this);
+      m_expr = exp;
+    }
+
+  }
+
+  /**
+   * This will traverse the heararchy, calling the visitor for 
+   * each member.  If the called visitor method returns 
+   * false, the subtree should not be called.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  public void callPredicateVisitors(XPathVisitor visitor)
+  {
+    m_expr.callVisitors(new filterExprOwner(), visitor);
+
+    super.callPredicateVisitors(visitor);
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+    if (!super.deepEquals(expr))
+      return false;
+
+    FilterExprIteratorSimple fet = (FilterExprIteratorSimple) expr;
+    if (!m_expr.deepEquals(fet.m_expr))
+      return false;
+
+    return true;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+  	if(null != m_exprObj)
+    	return m_exprObj.getAxis();
+    else
+    	return Axis.FILTEREDLIST;
+  }
+
+
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/FilterExprWalker.java b/src/main/java/org/apache/xpath/axes/FilterExprWalker.java
new file mode 100644
index 0000000..cc7e7db
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/FilterExprWalker.java
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FilterExprWalker.java 469367 2006-10-31 04:41:08Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpCodes;
+import org.apache.xpath.objects.XNodeSet;
+
+/**
+ * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP,
+ * op codes.
+ * @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a>
+ */
+public class FilterExprWalker extends AxesWalker
+{
+    static final long serialVersionUID = 5457182471424488375L;
+
+  /**
+   * Construct a FilterExprWalker using a LocPathIterator.
+   *
+   * @param locPathIterator non-null reference to the parent iterator.
+   */
+  public FilterExprWalker(WalkingIterator locPathIterator)
+  {
+    super(locPathIterator, Axis.FILTEREDLIST);
+  }
+
+  /**
+   * Init a FilterExprWalker.
+   *
+   * @param compiler non-null reference to the Compiler that is constructing.
+   * @param opPos positive opcode position for this step.
+   * @param stepType The type of step.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void init(Compiler compiler, int opPos, int stepType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    super.init(compiler, opPos, stepType);
+
+    // Smooth over an anomily in the opcode map...
+    switch (stepType)
+    {
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_EXTFUNCTION :
+    	m_mustHardReset = true;
+    case OpCodes.OP_GROUP :
+    case OpCodes.OP_VARIABLE :
+      m_expr = compiler.compile(opPos);
+      m_expr.exprSetParent(this);
+      //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof org.apache.xalan.templates.FuncKey))
+      if(m_expr instanceof org.apache.xpath.operations.Variable)
+      {
+      	// hack/temp workaround
+      	m_canDetachNodeset = false;
+      }
+      break;
+    default :
+      m_expr = compiler.compile(opPos + 2);
+      m_expr.exprSetParent(this);
+    }
+//    if(m_expr instanceof WalkingIterator)
+//    {
+//      WalkingIterator wi = (WalkingIterator)m_expr;
+//      if(wi.getFirstWalker() instanceof FilterExprWalker)
+//      {
+//      	FilterExprWalker fw = (FilterExprWalker)wi.getFirstWalker();
+//      	if(null == fw.getNextWalker())
+//      	{
+//      		m_expr = fw.m_expr;
+//      		m_expr.exprSetParent(this);
+//      	}
+//      }
+//      		
+//    }
+  }
+  
+  /**
+   * Detaches the walker from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state.
+   */
+  public void detach()
+  {  
+  	super.detach();
+  	if (m_canDetachNodeset)
+  	{
+  	  m_exprObj.detach();
+  	}
+  	m_exprObj = null;
+  }
+
+  /**
+   *  Set the root node of the TreeWalker.
+   *
+   * @param root non-null reference to the root, or starting point of 
+   *        the query.
+   */
+  public void setRoot(int root)
+  {
+
+    super.setRoot(root);
+
+  	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(root, 
+  	                  m_lpi.getXPathContext(), m_lpi.getPrefixResolver(), 
+  	                  m_lpi.getIsTopLevel(), m_lpi.m_stackFrame, m_expr);
+
+  }
+
+  /**
+   * Get a cloned FilterExprWalker.
+   *
+   * @return A new FilterExprWalker that can be used without mutating this one.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    FilterExprWalker clone = (FilterExprWalker) super.clone();
+
+    if (null != m_exprObj)
+      clone.m_exprObj = (XNodeSet) m_exprObj.clone();
+
+    return clone;
+  }
+  
+  /**
+   * This method needs to override AxesWalker.acceptNode because FilterExprWalkers
+   * don't need to, and shouldn't, do a node test.
+   * @param n  The node to check to see if it passes the filter or not.
+   * @return  a constant to determine whether the node is accepted,
+   *   rejected, or skipped, as defined  above .
+   */
+  public short acceptNode(int n)
+  {
+
+    try
+    {
+      if (getPredicateCount() > 0)
+      {
+        countProximityPosition(0);
+
+        if (!executePredicates(n, m_lpi.getXPathContext()))
+          return DTMIterator.FILTER_SKIP;
+      }
+
+      return DTMIterator.FILTER_ACCEPT;
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+      throw new RuntimeException(se.getMessage());
+    }
+  }
+
+  /**
+   *  Moves the <code>TreeWalker</code> to the next visible node in document
+   * order relative to the current node, and returns the new node. If the
+   * current node has no next node,  or if the search for nextNode attempts
+   * to step upward from the TreeWalker's root node, returns
+   * <code>null</code> , and retains the current node.
+   * @return  The new node, or <code>null</code> if the current node has no
+   *   next node  in the TreeWalker's logical view.
+   */
+  public int getNextNode()
+  {
+
+    if (null != m_exprObj)
+    {
+       int next = m_exprObj.nextNode();
+       return next;
+    }
+    else
+      return DTM.NULL;
+  }
+  
+  /**
+   * Get the index of the last node that can be itterated to.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the index of the last node that can be itterated to.
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+    return m_exprObj.getLength();
+  }
+  
+  /** The contained expression. Should be non-null.
+   *  @serial   */
+  private Expression m_expr;
+
+  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
+  transient private XNodeSet m_exprObj;
+  
+  private boolean m_mustHardReset = false;
+  private boolean m_canDetachNodeset = true;
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    m_expr.fixupVariables(vars, globalsSize);
+  }
+  
+  /**
+   * Get the inner contained expression of this filter.
+   */
+  public Expression getInnerExpression()
+  {
+  	return m_expr;
+  }
+  
+  /**
+   * Set the inner contained expression of this filter.
+   */
+  public void setInnerExpression(Expression expr)
+  {
+  	expr.exprSetParent(this);
+  	m_expr = expr;
+  }
+
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+      if (null != m_expr && m_expr instanceof PathComponent)
+      {
+        return ((PathComponent) m_expr).getAnalysisBits();
+      }
+      return WalkerFactory.BIT_FILTER;
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * Warning: This can only be called after setRoot has been called!
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return m_exprObj.isDocOrdered();
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return m_exprObj.getAxis();
+  }
+  
+  class filterExprOwner implements ExpressionOwner
+  {
+      /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_expr;
+    }
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(FilterExprWalker.this);
+    	m_expr = exp;
+    }
+  }
+  
+	/**
+	 * This will traverse the heararchy, calling the visitor for 
+	 * each member.  If the called visitor method returns 
+	 * false, the subtree should not be called.
+	 * 
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callPredicateVisitors(XPathVisitor visitor)
+	{
+	  m_expr.callVisitors(new filterExprOwner(), visitor);
+	  
+	  super.callPredicateVisitors(visitor);
+	} 
+
+
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+                return false;
+
+      FilterExprWalker walker = (FilterExprWalker)expr;
+      if(!m_expr.deepEquals(walker.m_expr))
+      	return false;
+
+      return true;
+    }
+
+	
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/HasPositionalPredChecker.java b/src/main/java/org/apache/xpath/axes/HasPositionalPredChecker.java
new file mode 100644
index 0000000..3fc6424
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/HasPositionalPredChecker.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: HasPositionalPredChecker.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.functions.FuncLast;
+import org.apache.xpath.functions.FuncPosition;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.operations.Div;
+import org.apache.xpath.operations.Minus;
+import org.apache.xpath.operations.Mod;
+import org.apache.xpath.operations.Mult;
+import org.apache.xpath.operations.Plus;
+import org.apache.xpath.operations.Quo;
+import org.apache.xpath.operations.Variable;
+
+public class HasPositionalPredChecker extends XPathVisitor
+{
+	private boolean m_hasPositionalPred = false;
+	private int m_predDepth = 0;
+	
+	/**
+	 * Process the LocPathIterator to see if it contains variables 
+	 * or functions that may make it context dependent.
+	 * @param path LocPathIterator that is assumed to be absolute, but needs checking.
+	 * @return true if the path is confirmed to be absolute, false if it 
+	 * may contain context dependencies.
+	 */
+	public static boolean check(LocPathIterator path)
+	{
+		HasPositionalPredChecker hppc = new HasPositionalPredChecker();
+		path.callVisitors(null, hppc);
+		return hppc.m_hasPositionalPred;
+	}
+	
+	/**
+	 * Visit a function.
+	 * @param owner The owner of the expression, to which the expression can 
+	 *              be reset if rewriting takes place.
+	 * @param func The function reference object.
+	 * @return true if the sub expressions should be traversed.
+	 */
+	public boolean visitFunction(ExpressionOwner owner, Function func)
+	{
+		if((func instanceof FuncPosition) ||
+		   (func instanceof FuncLast))
+			m_hasPositionalPred = true;
+		return true;
+	}
+	
+//	/**
+//	 * Visit a variable reference.
+//	 * @param owner The owner of the expression, to which the expression can 
+//	 *              be reset if rewriting takes place.
+//	 * @param var The variable reference object.
+//	 * @return true if the sub expressions should be traversed.
+//	 */
+//	public boolean visitVariableRef(ExpressionOwner owner, Variable var)
+//	{
+//		m_hasPositionalPred = true;
+//		return true;
+//	}
+	
+  /**
+   * Visit a predicate within a location path.  Note that there isn't a 
+   * proper unique component for predicates, and that the expression will 
+   * be called also for whatever type Expression is.
+   * 
+   * @param owner The owner of the expression, to which the expression can 
+   *              be reset if rewriting takes place.
+   * @param pred The predicate object.
+   * @return true if the sub expressions should be traversed.
+   */
+  public boolean visitPredicate(ExpressionOwner owner, Expression pred)
+  {
+    m_predDepth++;
+
+    if(m_predDepth == 1)
+    {
+      if((pred instanceof Variable) || 
+         (pred instanceof XNumber) ||
+         (pred instanceof Div) ||
+         (pred instanceof Plus) ||
+         (pred instanceof Minus) ||
+         (pred instanceof Mod) ||
+         (pred instanceof Quo) ||
+         (pred instanceof Mult) ||
+         (pred instanceof org.apache.xpath.operations.Number) ||
+         (pred instanceof Function))
+          m_hasPositionalPred = true;
+      else
+      	pred.callVisitors(owner, this);
+    }
+
+    m_predDepth--;
+
+    // Don't go have the caller go any further down the subtree.
+    return false;
+  }
+
+
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/IteratorPool.java b/src/main/java/org/apache/xpath/axes/IteratorPool.java
new file mode 100644
index 0000000..ef97c44
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/IteratorPool.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: IteratorPool.java 475981 2006-11-16 23:35:53Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import java.util.ArrayList;
+
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.WrappedRuntimeException;
+
+/**
+ * Pool of object of a given type to pick from to help memory usage
+ * @xsl.usage internal
+ */
+public final class IteratorPool implements java.io.Serializable
+{
+    static final long serialVersionUID = -460927331149566998L;
+
+  /** 
+   * Type of objects in this pool.
+   */
+  private final DTMIterator m_orig;
+
+  /** 
+   * Stack of given objects this points to.
+   */
+  private final ArrayList m_freeStack;
+
+  /**
+   * Constructor IteratorPool
+   *
+   * @param original The original iterator from which all others will be cloned.
+   */
+  public IteratorPool(DTMIterator original)
+  {
+    m_orig = original;
+    m_freeStack = new ArrayList();
+  }
+  
+  /**
+   * Get an instance of the given object in this pool 
+   *
+   * @return An instance of the given object
+   */
+  public synchronized DTMIterator getInstanceOrThrow()
+    throws CloneNotSupportedException
+  {
+    // Check if the pool is empty.
+    if (m_freeStack.isEmpty())
+    {
+
+      // Create a new object if so.
+      return (DTMIterator)m_orig.clone();
+    }
+    else
+    {
+      // Remove object from end of free pool.
+      DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1);
+      return result;
+    }
+  }
+  
+  /**
+   * Get an instance of the given object in this pool 
+   *
+   * @return An instance of the given object
+   */
+  public synchronized DTMIterator getInstance()
+  {
+    // Check if the pool is empty.
+    if (m_freeStack.isEmpty())
+    {
+
+      // Create a new object if so.
+      try
+      {
+        return (DTMIterator)m_orig.clone();
+      }
+      catch (Exception ex)
+      {
+        throw new WrappedRuntimeException(ex);
+      }
+    }
+    else
+    {
+      // Remove object from end of free pool.
+      DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1);
+      return result;
+    }
+  }
+
+  /**
+   * Add an instance of the given object to the pool  
+   *
+   *
+   * @param obj Object to add.
+   */
+  public synchronized void freeInstance(DTMIterator obj)
+  {
+    m_freeStack.add(obj);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/axes/LocPathIterator.java b/src/main/java/org/apache/xpath/axes/LocPathIterator.java
new file mode 100644
index 0000000..214eba1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/LocPathIterator.java
@@ -0,0 +1,1033 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: LocPathIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class extends NodeSetDTM, which implements NodeIterator,
+ * and fetches nodes one at a time in document order based on a XPath
+ * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a>.
+ *
+ * <p>If setShouldCacheNodes(true) is called,
+ * as each node is iterated via nextNode(), the node is also stored
+ * in the NodeVector, so that previousNode() can easily be done, except in
+ * the case where the LocPathIterator is "owned" by a UnionPathIterator,
+ * in which case the UnionPathIterator will cache the nodes.</p>
+ * @xsl.usage advanced
+ */
+public abstract class LocPathIterator extends PredicatedNodeTest
+        implements Cloneable, DTMIterator, java.io.Serializable, PathComponent
+{
+    static final long serialVersionUID = -4602476357268405754L;
+	
+  /**
+   * Create a LocPathIterator object.
+   *
+   */
+  protected LocPathIterator()
+  {
+  }
+
+
+  /**
+   * Create a LocPathIterator object.
+   *
+   * @param nscontext The namespace context for this iterator,
+   * should be OK if null.
+   */
+  protected LocPathIterator(PrefixResolver nscontext)
+  {
+
+    setLocPathIterator(this);
+    m_prefixResolver = nscontext;
+  }
+
+  /**
+   * Create a LocPathIterator object, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected LocPathIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    this(compiler, opPos, analysis, true);
+  }
+
+  /**
+   * Create a LocPathIterator object, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   * @param shouldLoadWalkers True if walkers should be
+   * loaded, or false if this is a derived iterator and
+   * it doesn't wish to load child walkers.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected LocPathIterator(
+          Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
+            throws javax.xml.transform.TransformerException
+  {
+    setLocPathIterator(this);
+  }
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+  	int axis = getAxis();
+  	int bit = WalkerFactory.getAnalysisBitFromAxes(axis);
+  	return bit;
+  }
+  
+  /**
+   * Read the object from a serialization stream.
+   *
+   * @param stream Input stream to read from
+   *
+   * @throws java.io.IOException
+   * @throws javax.xml.transform.TransformerException
+   */
+  private void readObject(java.io.ObjectInputStream stream)
+          throws java.io.IOException, javax.xml.transform.TransformerException
+  {
+    try
+    {
+      stream.defaultReadObject();
+      m_clones =  new IteratorPool(this);
+    }
+    catch (ClassNotFoundException cnfe)
+    {
+      throw new javax.xml.transform.TransformerException(cnfe);
+    }
+  }
+  
+  /**
+   * Set the environment in which this iterator operates, which should provide:
+   * a node (the context node... same value as "root" defined below) 
+   * a pair of non-zero positive integers (the context position and the context size) 
+   * a set of variable bindings 
+   * a function library 
+   * the set of namespace declarations in scope for the expression.
+   * 
+   * <p>At this time the exact implementation of this environment is application 
+   * dependent.  Probably a proper interface will be created fairly soon.</p>
+   * 
+   * @param environment The environment object.
+   */
+  public void setEnvironment(Object environment)
+  {
+    // no-op for now.
+  }
+  
+  /**
+   * Get an instance of a DTM that "owns" a node handle.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTM using just the iterator.
+   *
+   * @param nodeHandle the nodeHandle.
+   *
+   * @return a non-null DTM reference.
+   */
+  public DTM getDTM(int nodeHandle)
+  {
+    // %OPT%
+    return m_execContext.getDTM(nodeHandle);
+  }
+  
+  /**
+   * Get an instance of the DTMManager.  Since a node 
+   * iterator may be passed without a DTMManager, this allows the 
+   * caller to easily get the DTMManager using just the iterator.
+   *
+   * @return a non-null DTMManager reference.
+   */
+  public DTMManager getDTMManager()
+  {
+    return m_execContext.getDTMManager();
+  }
+  
+  /**
+   * Execute this iterator, meaning create a clone that can
+   * store state, and initialize it for fast execution from
+   * the current runtime state.  When this is called, no actual
+   * query from the current context node is performed.
+   *
+   * @param xctxt The XPath execution context.
+   *
+   * @return An XNodeSet reference that holds this iterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    XNodeSet iter = new XNodeSet((LocPathIterator)m_clones.getInstance());
+
+    iter.setRoot(xctxt.getCurrentNode(), xctxt);
+
+    return iter;
+  }
+    
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param handler The target content handler.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   * @throws org.xml.sax.SAXException
+   */
+  public void executeCharsToContentHandler(
+          XPathContext xctxt, org.xml.sax.ContentHandler handler)
+            throws javax.xml.transform.TransformerException,
+                   org.xml.sax.SAXException
+  {
+    LocPathIterator clone = (LocPathIterator)m_clones.getInstance();
+
+    int current = xctxt.getCurrentNode();
+    clone.setRoot(current, xctxt);
+    
+    int node = clone.nextNode();
+    DTM dtm = clone.getDTM(node);
+    clone.detach();
+	
+    if(node != DTM.NULL)
+    {
+      dtm.dispatchCharactersEvents(node, handler, false);
+    }
+  }
+  
+  /**
+   * Given an select expression and a context, evaluate the XPath
+   * and return the resulting iterator.
+   * 
+   * @param xctxt The execution context.
+   * @param contextNode The node that "." expresses.
+   * @throws TransformerException thrown if the active ProblemListener decides
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage experimental
+   */
+  public DTMIterator asIterator(
+          XPathContext xctxt, int contextNode)
+            throws javax.xml.transform.TransformerException
+  {
+    XNodeSet iter = new XNodeSet((LocPathIterator)m_clones.getInstance());
+
+    iter.setRoot(contextNode, xctxt);
+
+    return iter;
+  }
+
+  
+  /**
+   * Tell if the expression is a nodeset expression.
+   * 
+   * @return true if the expression can be represented as a nodeset.
+   */
+  public boolean isNodesetExpr()
+  {
+    return true;
+  }
+  
+  /**
+   * Return the first node out of the nodeset, if this expression is 
+   * a nodeset expression.  This is the default implementation for 
+   * nodesets.  Derived classes should try and override this and return a 
+   * value without having to do a clone operation.
+   * @param xctxt The XPath runtime context.
+   * @return the first node out of the nodeset, or DTM.NULL.
+   */
+  public int asNode(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException
+  {
+    DTMIterator iter = (DTMIterator)m_clones.getInstance();
+    
+    int current = xctxt.getCurrentNode();
+    
+    iter.setRoot(current, xctxt);
+
+    int next = iter.nextNode();
+    // m_clones.freeInstance(iter);
+    iter.detach();
+    return next;
+  }
+  
+  /**
+   * Evaluate this operation directly to a boolean.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a boolean.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return (asNode(xctxt) != DTM.NULL);
+  }
+
+
+  /**
+   * Set if this is an iterator at the upper level of
+   * the XPath.
+   *
+   * @param b true if this location path is at the top level of the
+   *          expression.
+   * @xsl.usage advanced
+   */
+  public void setIsTopLevel(boolean b)
+  {
+    m_isTopLevel = b;
+  }
+
+  /**
+   * Get if this is an iterator at the upper level of
+   * the XPath.
+   *
+   * @return true if this location path is at the top level of the
+   *          expression.
+   * @xsl.usage advanced
+   */
+  public boolean getIsTopLevel()
+  {
+    return m_isTopLevel;
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+
+    m_context = context;
+    
+    XPathContext xctxt = (XPathContext)environment;
+    m_execContext = xctxt;
+    m_cdtm = xctxt.getDTM(context);
+    
+    m_currentContextNode = context; // only if top level?
+    
+    // Yech, shouldn't have to do this.  -sb
+    if(null == m_prefixResolver)
+    	m_prefixResolver = xctxt.getNamespaceContext();
+        
+    m_lastFetched = DTM.NULL;
+    m_foundLast = false;
+    m_pos = 0;
+    m_length = -1;
+
+    if (m_isTopLevel)
+      this.m_stackFrame = xctxt.getVarStack().getStackFrame();
+      
+    // reset();
+  }
+
+  /**
+   * Set the next position index of this iterator.
+   *
+   * @param next A value greater than or equal to zero that indicates the next
+   * node position to fetch.
+   */
+  protected void setNextPosition(int next)
+  {
+    assertion(false, "setNextPosition not supported in this iterator!");
+  }
+
+  /**
+   * Get the current position, which is one less than
+   * the next nextNode() call will retrieve.  i.e. if
+   * you call getCurrentPos() and the return is 0, the next
+   * fetch will take place at index 1.
+   *
+   * @return A value greater than or equal to zero that indicates the next
+   * node position to fetch.
+   */
+  public final int getCurrentPos()
+  {
+    return m_pos;
+  }
+
+
+  /**
+   * If setShouldCacheNodes(true) is called, then nodes will
+   * be cached.  They are not cached by default.
+   *
+   * @param b True if this iterator should cache nodes.
+   */
+  public void setShouldCacheNodes(boolean b)
+  {
+
+    assertion(false, "setShouldCacheNodes not supported by this iterater!");
+  }
+  
+  /**
+   * Tells if this iterator can have nodes added to it or set via 
+   * the <code>setItem(int node, int index)</code> method.
+   * 
+   * @return True if the nodelist can be mutated.
+   */
+  public boolean isMutable()
+  {
+    return false;
+  }
+
+  /**
+   * Set the current position in the node set.
+   *
+   * @param i Must be a valid index greater
+   * than or equal to zero and less than m_cachedNodes.size().
+   */
+  public void setCurrentPos(int i)
+  {
+  	assertion(false, "setCurrentPos not supported by this iterator!");
+  }
+  
+  /**
+   * Increment the current position in the node set.
+   */
+  public void incrementCurrentPos()
+  {
+  	m_pos++;
+  }
+
+
+  /**
+   * Get the length of the cached nodes.
+   *
+   * <p>Note: for the moment at least, this only returns
+   * the size of the nodes that have been fetched to date,
+   * it doesn't attempt to run to the end to make sure we
+   * have found everything.  This should be reviewed.</p>
+   *
+   * @return The size of the current cache list.
+   */
+  public int size()
+  {
+	assertion(false, "size() not supported by this iterator!");
+	return 0;
+  }
+
+  /**
+   *  Returns the <code>index</code> th item in the collection. If
+   * <code>index</code> is greater than or equal to the number of nodes in
+   * the list, this returns <code>null</code> .
+   * @param index  Index into the collection.
+   * @return  The node at the <code>index</code> th position in the
+   *   <code>NodeList</code> , or <code>null</code> if that is not a valid
+   *   index.
+   */
+  public int item(int index)
+  {
+	assertion(false, "item(int index) not supported by this iterator!");
+	return 0;
+  }
+  
+  /**
+   * Sets the node at the specified index of this vector to be the
+   * specified node. The previous component at that position is discarded.
+   *
+   * <p>The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.  
+   * The iterator must be in cached mode.</p>
+   * 
+   * <p>Meant to be used for sorted iterators.</p>
+   *
+   * @param node Node to set
+   * @param index Index of where to set the node
+   */
+  public void setItem(int node, int index)
+  {
+	assertion(false, "setItem not supported by this iterator!");
+  }
+
+  /**
+   *  The number of nodes in the list. The range of valid child node indices
+   * is 0 to <code>length-1</code> inclusive.
+   *
+   * @return The number of nodes in the list, always greater or equal to zero.
+   */
+  public int getLength()
+  {      
+    // Tell if this is being called from within a predicate.
+  	boolean isPredicateTest = (this == m_execContext.getSubContextList());
+
+    // And get how many total predicates are part of this step.
+  	int predCount = getPredicateCount();
+  	
+    // If we have already calculated the length, and the current predicate 
+    // is the first predicate, then return the length.  We don't cache 
+    // the anything but the length of the list to the first predicate.
+    if (-1 != m_length && isPredicateTest && m_predicateIndex < 1)
+  		return m_length;
+  	
+    // I'm a bit worried about this one, since it doesn't have the 
+    // checks found above.  I suspect it's fine.  -sb
+    if (m_foundLast)
+  		return m_pos;
+  		
+    // Create a clone, and count from the current position to the end 
+    // of the list, not taking into account the current predicate and 
+    // predicates after the current one.
+    int pos = (m_predicateIndex >= 0) ? getProximityPosition() : m_pos;
+              
+    LocPathIterator clone;
+
+    try
+    {
+      clone = (LocPathIterator) clone();        
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      return -1;
+    }
+
+    // We want to clip off the last predicate, but only if we are a sub 
+    // context node list, NOT if we are a context list.  See pos68 test, 
+    // also test against bug4638.
+    if (predCount > 0 && isPredicateTest)
+    {
+      // Don't call setPredicateCount, because it clones and is slower.
+      clone.m_predCount = m_predicateIndex;
+      // The line above used to be:
+      // clone.m_predCount = predCount - 1;
+      // ...which looks like a dumb bug to me. -sb
+    }
+
+    int next;
+
+    while (DTM.NULL != (next = clone.nextNode()))
+    {
+      pos++;
+    }
+    
+    if (isPredicateTest && m_predicateIndex < 1)
+      m_length = pos;
+    
+    return pos;
+  }
+
+  /**
+   * Tells if this NodeSetDTM is "fresh", in other words, if
+   * the first nextNode() that is called will return the
+   * first node in the set.
+   *
+   * @return true of nextNode has not been called.
+   */
+  public boolean isFresh()
+  {
+    return (m_pos == 0);
+  }
+
+  /**
+   *  Returns the previous node in the set and moves the position of the
+   * iterator backwards in the set.
+   * @return  The previous <code>Node</code> in the set being iterated over,
+   *   or<code>null</code> if there are no more members in that set.
+   */
+  public int previousNode()
+  {
+    throw new RuntimeException(
+      XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_ITERATE, null)); //"This NodeSetDTM can not iterate to a previous node!");
+  }
+
+  /**
+   * This attribute determines which node types are presented via the
+   * iterator. The available set of constants is defined in the
+   * <code>NodeFilter</code> interface.
+   *
+   * <p>This is somewhat useless at this time, since it doesn't
+   * really return information that tells what this iterator will
+   * show.  It is here only to fullfill the DOM NodeIterator
+   * interface.</p>
+   *
+   * @return For now, always NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_ENTITY_REFERENCE.
+   * @see org.w3c.dom.traversal.NodeIterator
+   */
+  public int getWhatToShow()
+  {
+
+    // TODO: ??
+    return DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE;
+  }
+
+  /**
+   *  The filter used to screen nodes.  Not used at this time,
+   * this is here only to fullfill the DOM NodeIterator
+   * interface.
+   *
+   * @return Always null.
+   * @see org.w3c.dom.traversal.NodeIterator
+   */
+  public DTMFilter getFilter()
+  {
+    return null;
+  }
+
+  /**
+   * The root node of the Iterator, as specified when it was created.
+   *
+   * @return The "root" of this iterator, which, in XPath terms,
+   * is the node context for this iterator.
+   */
+  public int getRoot()
+  {
+    return m_context;
+  }
+
+  /**
+   *  The value of this flag determines whether the children of entity
+   * reference nodes are visible to the iterator. If false, they will be
+   * skipped over.
+   * <br> To produce a view of the document that has entity references
+   * expanded and does not expose the entity reference node itself, use the
+   * whatToShow flags to hide the entity reference node and set
+   * expandEntityReferences to true when creating the iterator. To produce
+   * a view of the document that has entity reference nodes but no entity
+   * expansion, use the whatToShow flags to show the entity reference node
+   * and set expandEntityReferences to false.
+   *
+   * @return Always true, since entity reference nodes are not
+   * visible in the XPath model.
+   */
+  public boolean getExpandEntityReferences()
+  {
+    return true;
+  }
+  
+  /** Control over whether it is OK for detach to reset the iterator. */
+  protected boolean m_allowDetach = true;
+  
+  /**
+   * Specify if it's OK for detach to release the iterator for reuse.
+   * 
+   * @param allowRelease true if it is OK for detach to release this iterator 
+   * for pooling.
+   */
+  public void allowDetachToRelease(boolean allowRelease)
+  {
+    m_allowDetach = allowRelease;
+  }
+
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {    
+    if(m_allowDetach)
+    {
+      // sb: allow reusing of cached nodes when possible?
+      // m_cachedNodes = null;
+      m_execContext = null;
+      // m_prefixResolver = null;  sb: Why would this ever want to be null?
+      m_cdtm = null;
+      m_length = -1;
+      m_pos = 0;
+      m_lastFetched = DTM.NULL;
+      m_context = DTM.NULL;
+      m_currentContextNode = DTM.NULL;
+      
+      m_clones.freeInstance(this);
+    }
+  }
+  
+  /**
+   * Reset the iterator.
+   */
+  public void reset()
+  {
+  	assertion(false, "This iterator can not reset!");
+  }
+
+  /**
+   * Get a cloned Iterator that is reset to the beginning
+   * of the query.
+   *
+   * @return A cloned NodeIterator set of the start of the query.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+    LocPathIterator clone;
+//    clone = (LocPathIterator) clone();
+    clone = (LocPathIterator)m_clones.getInstanceOrThrow();
+    clone.m_execContext = m_execContext;
+    clone.m_cdtm = m_cdtm;
+    
+    clone.m_context = m_context;
+    clone.m_currentContextNode = m_currentContextNode;
+    clone.m_stackFrame = m_stackFrame;
+
+    // clone.reset();
+
+    return clone;
+  }
+
+//  /**
+//   * Get a cloned LocPathIterator that holds the same
+//   * position as this iterator.
+//   *
+//   * @return A clone of this iterator that holds the same node position.
+//   *
+//   * @throws CloneNotSupportedException
+//   */
+//  public Object clone() throws CloneNotSupportedException
+//  {
+//
+//    LocPathIterator clone = (LocPathIterator) super.clone();
+//
+//    return clone;
+//  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public abstract int nextNode();
+
+  /**
+   * Bottleneck the return of a next node, to make returns
+   * easier from nextNode().
+   *
+   * @param nextNode The next node found, may be null.
+   *
+   * @return The same node that was passed as an argument.
+   */
+  protected int returnNextNode(int nextNode)
+  {
+
+    if (DTM.NULL != nextNode)
+    {
+      m_pos++;
+    }
+
+    m_lastFetched = nextNode;
+
+    if (DTM.NULL == nextNode)
+      m_foundLast = true;
+
+    return nextNode;
+  }
+
+  /**
+   * Return the last fetched node.  Needed to support the UnionPathIterator.
+   *
+   * @return The last fetched node, or null if the last fetch was null.
+   */
+  public int getCurrentNode()
+  {
+    return m_lastFetched;
+  }
+
+  /**
+   * If an index is requested, NodeSetDTM will call this method
+   * to run the iterator to the index.  By default this sets
+   * m_next to the index.  If the index argument is -1, this
+   * signals that the iterator should be run to the end.
+   *
+   * @param index The index to run to, or -1 if the iterator
+   * should run to the end.
+   */
+  public void runTo(int index)
+  {
+
+    if (m_foundLast || ((index >= 0) && (index <= getCurrentPos())))
+      return;
+
+    int n;
+
+    if (-1 == index)
+    {
+      while (DTM.NULL != (n = nextNode()));
+    }
+    else
+    {
+      while (DTM.NULL != (n = nextNode()))
+      {
+        if (getCurrentPos() >= index)
+          break;
+      }
+    }
+  }
+
+  /**
+   * Tells if we've found the last node yet.
+   *
+   * @return true if the last nextNode returned null.
+   */
+  public final boolean getFoundLast()
+  {
+    return m_foundLast;
+  }
+
+  /**
+   * The XPath execution context we are operating on.
+   *
+   * @return XPath execution context this iterator is operating on,
+   * or null if setRoot has not been called.
+   */
+  public final XPathContext getXPathContext()
+  {
+    return m_execContext;
+  }
+
+  /**
+   * The node context for the iterator.
+   *
+   * @return The node context, same as getRoot().
+   */
+  public final int getContext()
+  {
+    return m_context;
+  }
+
+  /**
+   * The node context from where the expression is being
+   * executed from (i.e. for current() support).
+   *
+   * @return The top-level node context of the entire expression.
+   */
+  public final int getCurrentContextNode()
+  {
+    return m_currentContextNode;
+  }
+
+  /**
+   * Set the current context node for this iterator.
+   *
+   * @param n Must be a non-null reference to the node context.
+   */
+  public final void setCurrentContextNode(int n)
+  {
+    m_currentContextNode = n;
+  }
+  
+//  /**
+//   * Set the current context node for this iterator.
+//   *
+//   * @param n Must be a non-null reference to the node context.
+//   */
+//  public void setRoot(int n)
+//  {
+//    m_context = n;
+//    m_cdtm = m_execContext.getDTM(n);
+//  }
+
+  /**
+   * Return the saved reference to the prefix resolver that
+   * was in effect when this iterator was created.
+   *
+   * @return The prefix resolver or this iterator, which may be null.
+   */
+  public final PrefixResolver getPrefixResolver()
+  {
+  	if(null == m_prefixResolver)
+  	{
+    	m_prefixResolver = (PrefixResolver)getExpressionOwner();
+  	}
+
+    return m_prefixResolver;
+  }
+        
+//  /**
+//   * Get the analysis pattern built by the WalkerFactory.
+//   *
+//   * @return The analysis pattern built by the WalkerFactory.
+//   */
+//  int getAnalysis()
+//  {
+//    return m_analysis;
+//  }
+
+//  /**
+//   * Set the analysis pattern built by the WalkerFactory.
+//   *
+//   * @param a The analysis pattern built by the WalkerFactory.
+//   */
+//  void setAnalysis(int a)
+//  {
+//    m_analysis = a;
+//  }
+
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	 	if(visitor.visitLocationPath(owner, this))
+  	 	{
+  	 		visitor.visitStep(owner, this);
+  	 		callPredicateVisitors(visitor);
+  	 	}
+  }  
+
+  
+  //============= State Data =============
+  
+  /** 
+   * The pool for cloned iterators.  Iterators need to be cloned
+   * because the hold running state, and thus the original iterator
+   * expression from the stylesheet pool can not be used.          
+   */
+  transient protected IteratorPool m_clones = new IteratorPool(this);
+  
+  /** 
+   * The dtm of the context node.  Careful about using this... it may not 
+   * be the dtm of the current node.
+   */
+  transient protected DTM m_cdtm;
+  
+  /**
+   * The stack frame index for this iterator.
+   */
+  transient int m_stackFrame = -1;
+
+  /**
+   * Value determined at compile time, indicates that this is an
+   * iterator at the top level of the expression, rather than inside
+   * a predicate.
+   * @serial
+   */
+  private boolean m_isTopLevel = false;
+
+  /** The last node that was fetched, usually by nextNode. */
+  transient public int m_lastFetched = DTM.NULL;
+
+  /**
+   * The context node for this iterator, which doesn't change through
+   * the course of the iteration.
+   */
+  transient protected int m_context = DTM.NULL;
+
+  /**
+   * The node context from where the expression is being
+   * executed from (i.e. for current() support).  Different
+   * from m_context in that this is the context for the entire
+   * expression, rather than the context for the subexpression.
+   */
+  transient protected int m_currentContextNode = DTM.NULL;
+  
+  /**
+   * The current position of the context node.
+   */
+  transient protected int m_pos = 0;
+  
+  transient protected int m_length = -1;
+
+  /**
+   * Fast access to the current prefix resolver.  It isn't really
+   * clear that this is needed.
+   * @serial
+   */
+  private PrefixResolver m_prefixResolver;
+
+  /**
+   * The XPathContext reference, needed for execution of many
+   * operations.
+   */
+  transient protected XPathContext m_execContext;
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return true;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return -1;
+  }
+
+
+//  /**
+//   * The analysis pattern built by the WalkerFactory.
+//   * TODO: Move to LocPathIterator.
+//   * @see org.apache.xpath.axes.WalkerFactory
+//   * @serial
+//   */
+//  protected int m_analysis = 0x00000000;
+  /**
+   * @see PredicatedNodeTest#getLastPos(XPathContext)
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+    return getLength();
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/MatchPatternIterator.java b/src/main/java/org/apache/xpath/axes/MatchPatternIterator.java
new file mode 100644
index 0000000..2647d82
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/MatchPatternIterator.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: MatchPatternIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpMap;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.patterns.StepPattern;
+
+/**
+ * This class treats a 
+ * <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a> as a 
+ * filtered iteration over the tree, evaluating each node in a super axis 
+ * traversal against the LocationPath interpreted as a match pattern.  This 
+ * class is useful to find nodes in document order that are complex paths 
+ * whose steps probably criss-cross each other.
+ */
+public class MatchPatternIterator extends LocPathIterator
+{
+    static final long serialVersionUID = -5201153767396296474L;
+
+  /** This is the select pattern, translated into a match pattern. */
+  protected StepPattern m_pattern;
+
+  /** The traversal axis from where the nodes will be filtered. */
+  protected int m_superAxis = -1;
+
+  /** The DTM inner traversal class, that corresponds to the super axis. */
+  protected DTMAxisTraverser m_traverser;
+  
+  /** DEBUG flag for diagnostic dumps. */
+  private static final boolean DEBUG = false;
+  
+//  protected int m_nsElemBase = DTM.NULL;
+
+  /**
+   * Create a LocPathIterator object, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   * @param analysis Analysis bits that give general information about the 
+   * LocationPath.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  MatchPatternIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+
+    super(compiler, opPos, analysis, false);
+
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+
+    m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0); 
+
+    boolean fromRoot = false;
+    boolean walkBack = false;
+    boolean walkDescendants = false;
+    boolean walkAttributes = false;
+
+    if (0 != (analysis & (WalkerFactory.BIT_ROOT | 
+                          WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT)))
+      fromRoot = true;
+      
+    if (0 != (analysis
+              & (WalkerFactory.BIT_ANCESTOR
+                 | WalkerFactory.BIT_ANCESTOR_OR_SELF
+                 | WalkerFactory.BIT_PRECEDING
+                 | WalkerFactory.BIT_PRECEDING_SIBLING 
+                 | WalkerFactory.BIT_FOLLOWING
+                 | WalkerFactory.BIT_FOLLOWING_SIBLING
+                 | WalkerFactory.BIT_PARENT | WalkerFactory.BIT_FILTER)))
+      walkBack = true;
+
+    if (0 != (analysis
+              & (WalkerFactory.BIT_DESCENDANT_OR_SELF
+                 | WalkerFactory.BIT_DESCENDANT
+                 | WalkerFactory.BIT_CHILD)))
+      walkDescendants = true;
+
+    if (0 != (analysis
+              & (WalkerFactory.BIT_ATTRIBUTE | WalkerFactory.BIT_NAMESPACE)))
+      walkAttributes = true;
+      
+    if(false || DEBUG)
+    {
+      System.out.print("analysis: "+Integer.toBinaryString(analysis));
+      System.out.println(", "+WalkerFactory.getAnalysisString(analysis));
+    }
+      
+    if(fromRoot || walkBack)
+    {
+      if(walkAttributes)
+      {
+        m_superAxis = Axis.ALL;
+      }
+      else
+      {
+        m_superAxis = Axis.DESCENDANTSFROMROOT;
+      }
+    }
+    else if(walkDescendants)
+    {
+      if(walkAttributes)
+      {
+        m_superAxis = Axis.ALLFROMNODE;
+      }
+      else
+      {
+        m_superAxis = Axis.DESCENDANTORSELF;
+      }
+    }
+    else
+    {
+      m_superAxis = Axis.ALL;
+    }
+    if(false || DEBUG)
+    {
+      System.out.println("axis: "+Axis.getNames(m_superAxis));
+    }
+    
+  }
+  
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+    m_traverser = m_cdtm.getAxisTraverser(m_superAxis);
+  }
+
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {    
+    if(m_allowDetach)
+    {
+      m_traverser = null;
+      
+      // Always call the superclass detach last!
+      super.detach();
+    }
+  }
+  
+  /**
+   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
+   * @return The next node on the axis, or DTM.NULL.
+   */
+  protected int getNextNode()
+  {
+    m_lastFetched = (DTM.NULL == m_lastFetched)
+                     ? m_traverser.first(m_context)
+                     : m_traverser.next(m_context, m_lastFetched);
+    return m_lastFetched;
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {      
+  	if(m_foundLast)
+  		return DTM.NULL;
+
+    int next;
+    
+    org.apache.xpath.VariableStack vars;
+    int savedStart;
+    if (-1 != m_stackFrame)
+    {
+      vars = m_execContext.getVarStack();
+
+      // These three statements need to be combined into one operation.
+      savedStart = vars.getStackFrame();
+
+      vars.setStackFrame(m_stackFrame);
+    }
+    else
+    {
+      // Yuck.  Just to shut up the compiler!
+      vars = null;
+      savedStart = 0;
+    }
+    
+    try
+    {
+      if(DEBUG)
+        System.out.println("m_pattern"+m_pattern.toString());
+
+      do
+      {
+        next = getNextNode();
+  
+        if (DTM.NULL != next)
+        {
+          if(DTMIterator.FILTER_ACCEPT == acceptNode(next, m_execContext))
+            break;
+          else
+            continue;
+        }
+        else
+          break;
+      }
+      while (next != DTM.NULL);
+      
+      if (DTM.NULL != next)
+      {
+        if(DEBUG)
+        {
+          System.out.println("next: "+next);
+          System.out.println("name: "+m_cdtm.getNodeName(next));
+        }
+        incrementCurrentPos();
+  
+        return next;
+      }
+      else
+      {
+        m_foundLast = true;
+  
+        return DTM.NULL;
+      }
+    }
+    finally
+    {
+      if (-1 != m_stackFrame)
+      {
+        // These two statements need to be combined into one operation.
+        vars.setStackFrame(savedStart);
+      }
+    }
+
+  }
+  
+  /**
+   *  Test whether a specified node is visible in the logical view of a
+   * TreeWalker or NodeIterator. This function will be called by the
+   * implementation of TreeWalker and NodeIterator; it is not intended to
+   * be called directly from user code.
+   * @param n  The node to check to see if it passes the filter or not.
+   * @return  a constant to determine whether the node is accepted,
+   *   rejected, or skipped, as defined  above .
+   */
+  public short acceptNode(int n, XPathContext xctxt)
+  {
+
+    try
+    {
+      xctxt.pushCurrentNode(n);
+      xctxt.pushIteratorRoot(m_context);
+      if(DEBUG)
+      {
+        System.out.println("traverser: "+m_traverser);
+        System.out.print("node: "+n);
+        System.out.println(", "+m_cdtm.getNodeName(n));
+        // if(m_cdtm.getNodeName(n).equals("near-east"))
+        System.out.println("pattern: "+m_pattern.toString());
+        m_pattern.debugWhatToShow(m_pattern.getWhatToShow());
+      }
+      
+      XObject score = m_pattern.execute(xctxt);
+      
+      if(DEBUG)
+      {
+        // System.out.println("analysis: "+Integer.toBinaryString(m_analysis));
+        System.out.println("score: "+score);
+        System.out.println("skip: "+(score == NodeTest.SCORE_NONE));
+      }
+
+      // System.out.println("\n::acceptNode - score: "+score.num()+"::");
+      return (score == NodeTest.SCORE_NONE) ? DTMIterator.FILTER_SKIP 
+                    : DTMIterator.FILTER_ACCEPT;
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: Fix this.
+      throw new RuntimeException(se.getMessage());
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      xctxt.popIteratorRoot();
+    }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/NodeSequence.java b/src/main/java/org/apache/xpath/axes/NodeSequence.java
new file mode 100644
index 0000000..9b3e398
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/NodeSequence.java
@@ -0,0 +1,953 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeSequence.java 469367 2006-10-31 04:41:08Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import java.util.Vector;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.NodeVector;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This class is the dynamic wrapper for a Xalan DTMIterator instance, and 
+ * provides random access capabilities.
+ */
+public class NodeSequence extends XObject
+  implements DTMIterator, Cloneable, PathComponent
+{
+    static final long serialVersionUID = 3866261934726581044L;
+  /** The index of the last node in the iteration. */
+  protected int m_last = -1;
+  
+  /**
+   * The index of the next node to be fetched.  Useful if this
+   * is a cached iterator, and is being used as random access
+   * NodeList.
+   */
+  protected int m_next = 0;
+    
+  /**
+   * A cache of a list of nodes obtained from the iterator so far.
+   * This list is appended to until the iterator is exhausted and
+   * the cache is complete.
+   * <p>
+   * Multiple NodeSequence objects may share the same cache.
+   */
+  private IteratorCache m_cache;
+  
+  /**
+   * If this iterator needs to cache nodes that are fetched, they
+   * are stored in the Vector in the generic object.
+   */
+  protected NodeVector getVector() {
+      NodeVector nv = (m_cache != null) ?  m_cache.getVector() : null;
+      return nv;
+  }
+  
+  /**
+   * Get the cache (if any) of nodes obtained from
+   * the iterator so far. Note that the cache keeps
+   * growing until the iterator is walked to exhaustion,
+   * at which point the cache is "complete".
+   */
+  private IteratorCache getCache() {
+      return m_cache;
+  }
+  
+  /**
+   * Set the vector where nodes will be cached.
+   */
+  protected void SetVector(NodeVector v)
+  {
+  	setObject(v);
+  }
+
+  
+  /**
+   * If the iterator needs to cache nodes as they are fetched,
+   * then this method returns true. 
+   */
+  public boolean hasCache()
+  {
+    final NodeVector nv = getVector();
+  	return (nv != null);
+  }
+  
+  /**
+   * If this NodeSequence has a cache, and that cache is 
+   * fully populated then this method returns true, otherwise
+   * if there is no cache or it is not complete it returns false.
+   */
+  private boolean cacheComplete() {
+      final boolean complete;
+      if (m_cache != null) {
+          complete = m_cache.isComplete();
+      } else {
+          complete = false;
+      }
+      return complete;
+  }
+  
+  /**
+   * If this NodeSequence has a cache, mark that it is complete.
+   * This method should be called after the iterator is exhausted.
+   */
+  private void markCacheComplete() {
+      NodeVector nv = getVector();
+      if (nv != null) {
+          m_cache.setCacheComplete(true);
+      }      
+  }
+
+
+  /**
+   * The functional iterator that fetches nodes.
+   */
+  protected DTMIterator m_iter;
+  
+  /**
+   * Set the functional iterator that fetches nodes.
+   * @param iter The iterator that is to be contained.
+   */
+  public final void setIter(DTMIterator iter)
+  {
+  	m_iter = iter;
+  }
+  
+  /**
+   * Get the functional iterator that fetches nodes.
+   * @return The contained iterator.
+   */
+  public final DTMIterator getContainedIter()
+  {
+  	return m_iter;
+  }
+  
+  /**
+   * The DTMManager to use if we're using a NodeVector only.
+   * We may well want to do away with this, and store it in the NodeVector.
+   */
+  protected DTMManager m_dtmMgr;
+  
+  // ==== Constructors ====
+  
+  /**
+   * Create a new NodeSequence from a (already cloned) iterator.
+   * 
+   * @param iter Cloned (not static) DTMIterator.
+   * @param context The initial context node.
+   * @param xctxt The execution context.
+   * @param shouldCacheNodes True if this sequence can random access.
+   */
+  private NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes)
+  {
+  	setIter(iter);
+  	setRoot(context, xctxt);
+  	setShouldCacheNodes(shouldCacheNodes);
+  }
+  
+  /**
+   * Create a new NodeSequence from a (already cloned) iterator.
+   * 
+   * @param nodeVector
+   */
+  public NodeSequence(Object nodeVector)
+  {
+  	super(nodeVector);
+    if (nodeVector instanceof NodeVector) {
+        SetVector((NodeVector) nodeVector);
+    }
+  	if(null != nodeVector)
+  	{
+  		assertion(nodeVector instanceof NodeVector, 
+  			"Must have a NodeVector as the object for NodeSequence!");
+  		if(nodeVector instanceof DTMIterator)
+  		{
+  			setIter((DTMIterator)nodeVector);
+  			m_last = ((DTMIterator)nodeVector).getLength();
+  		}
+  		
+  	}
+  }
+  
+  /**
+   * Construct an empty XNodeSet object.  This is used to create a mutable 
+   * nodeset to which random nodes may be added.
+   */
+  private NodeSequence(DTMManager dtmMgr)
+  {
+    super(new NodeVector());
+    m_last = 0;
+    m_dtmMgr = dtmMgr;
+  }
+
+  
+  /**
+   * Create a new NodeSequence in an invalid (null) state.
+   */
+  public NodeSequence()
+  {
+      return;
+  }
+
+
+  /**
+   * @see DTMIterator#getDTM(int)
+   */
+  public DTM getDTM(int nodeHandle)
+  {
+  	DTMManager mgr = getDTMManager();
+  	if(null != mgr)
+    	return getDTMManager().getDTM(nodeHandle);
+    else
+    {
+    	assertion(false, "Can not get a DTM Unless a DTMManager has been set!");
+    	return null;
+    }
+  }
+
+  /**
+   * @see DTMIterator#getDTMManager()
+   */
+  public DTMManager getDTMManager()
+  {
+    return m_dtmMgr;
+  }
+
+  /**
+   * @see DTMIterator#getRoot()
+   */
+  public int getRoot()
+  {
+  	if(null != m_iter)
+    	return m_iter.getRoot();
+  	else
+  	{
+  		// NodeSetDTM will call this, and so it's not a good thing to throw 
+  		// an assertion here.
+  		// assertion(false, "Can not get the root from a non-iterated NodeSequence!");
+  		return DTM.NULL;
+  	}
+  }
+
+  /**
+   * @see DTMIterator#setRoot(int, Object)
+   */
+  public void setRoot(int nodeHandle, Object environment)
+  {
+  	if(null != m_iter)
+  	{
+  		XPathContext xctxt = (XPathContext)environment;
+  		m_dtmMgr = xctxt.getDTMManager();
+  		m_iter.setRoot(nodeHandle, environment);
+  		if(!m_iter.isDocOrdered())
+  		{
+  			if(!hasCache())
+  				setShouldCacheNodes(true);
+  			runTo(-1);
+  			m_next=0;
+  		}
+  	}
+  	else
+  		assertion(false, "Can not setRoot on a non-iterated NodeSequence!");
+  }
+
+  /**
+   * @see DTMIterator#reset()
+   */
+  public void reset()
+  {
+  	m_next = 0;
+  	// not resetting the iterator on purpose!!!
+  }
+
+  /**
+   * @see DTMIterator#getWhatToShow()
+   */
+  public int getWhatToShow()
+  {
+    return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE) 
+    	: m_iter.getWhatToShow();
+  }
+
+  /**
+   * @see DTMIterator#getExpandEntityReferences()
+   */
+  public boolean getExpandEntityReferences()
+  {
+  	if(null != m_iter)
+  		return m_iter.getExpandEntityReferences();
+  	else
+    	return true;
+  }
+
+  /**
+   * @see DTMIterator#nextNode()
+   */
+  public int nextNode()
+  {
+    // If the cache is on, and the node has already been found, then 
+    // just return from the list.
+    NodeVector vec = getVector();
+    if (null != vec)
+    {	
+        // There is a cache
+    	if(m_next < vec.size())
+    	{
+            // The node is in the cache, so just return it.
+			int next = vec.elementAt(m_next);
+	    	m_next++;
+	    	return next;
+    	}
+    	else if(cacheComplete() || (-1 != m_last) || (null == m_iter))
+    	{
+    		m_next++;
+    		return DTM.NULL;
+    	}
+    }
+    
+  if (null == m_iter)
+    return DTM.NULL;
+  
+ 	int next = m_iter.nextNode();
+    if(DTM.NULL != next)
+    {
+    	if(hasCache())
+    	{
+    		if(m_iter.isDocOrdered())
+    	    {
+    			getVector().addElement(next);
+    			m_next++;
+    		}
+    		else
+    		{
+    			int insertIndex = addNodeInDocOrder(next);
+    			if(insertIndex >= 0)
+    				m_next++;
+    		}
+    	}
+    	else
+    		m_next++;
+    }
+    else
+    {
+        // We have exhausted the iterator, and if there is a cache
+        // it must have all nodes in it by now, so let the cache
+        // know that it is complete.
+        markCacheComplete();
+        
+    	m_last = m_next;
+    	m_next++;
+    }
+    	
+    return next;
+  }
+
+  /**
+   * @see DTMIterator#previousNode()
+   */
+  public int previousNode()
+  {
+  	if(hasCache())
+  	{
+  		if(m_next <= 0)
+  			return DTM.NULL;
+  		else
+  		{
+  			m_next--;
+  			return item(m_next);
+  		}
+  	}
+  	else
+  	{
+	    int n = m_iter.previousNode();
+	    m_next = m_iter.getCurrentPos();
+	    return m_next;
+  	}
+  }
+
+  /**
+   * @see DTMIterator#detach()
+   */
+  public void detach()
+  {
+  	if(null != m_iter)
+  		m_iter.detach();
+  	super.detach();
+  }
+
+  /**
+   * Calling this with a value of false will cause the nodeset 
+   * to be cached.
+   * @see DTMIterator#allowDetachToRelease(boolean)
+   */
+  public void allowDetachToRelease(boolean allowRelease)
+  {
+  	if((false == allowRelease) && !hasCache())
+  	{
+  		setShouldCacheNodes(true);
+  	}
+  	
+  	if(null != m_iter)
+  		m_iter.allowDetachToRelease(allowRelease);
+  	super.allowDetachToRelease(allowRelease);
+  }
+
+  /**
+   * @see DTMIterator#getCurrentNode()
+   */
+  public int getCurrentNode()
+  {
+  	if(hasCache())
+  	{
+  		int currentIndex = m_next-1;
+  		NodeVector vec = getVector();
+  		if((currentIndex >= 0) && (currentIndex < vec.size()))
+  			return vec.elementAt(currentIndex);
+  		else
+  			return DTM.NULL;
+  	}
+  	
+  	if(null != m_iter)
+  	{
+    	return m_iter.getCurrentNode();
+  	}
+  	else
+  		return DTM.NULL;
+  }
+
+  /**
+   * @see DTMIterator#isFresh()
+   */
+  public boolean isFresh()
+  {
+    return (0 == m_next);
+  }
+
+  /**
+   * @see DTMIterator#setShouldCacheNodes(boolean)
+   */
+  public void setShouldCacheNodes(boolean b)
+  {
+    if (b)
+    {
+      if(!hasCache())
+      {
+        SetVector(new NodeVector());
+      }
+//	  else
+//	    getVector().RemoveAllNoClear();  // Is this good?
+    }
+    else
+      SetVector(null);
+  }
+
+  /**
+   * @see DTMIterator#isMutable()
+   */
+  public boolean isMutable()
+  {
+    return hasCache(); // though may be surprising if it also has an iterator!
+  }
+
+  /**
+   * @see DTMIterator#getCurrentPos()
+   */
+  public int getCurrentPos()
+  {
+    return m_next;
+  }
+
+  /**
+   * @see DTMIterator#runTo(int)
+   */
+  public void runTo(int index)
+  {
+    int n;
+    
+    if (-1 == index)
+    {
+      int pos = m_next;
+      while (DTM.NULL != (n = nextNode()));
+      m_next = pos;
+    }
+    else if(m_next == index)
+    {
+      return;
+    }
+    else if(hasCache() && m_next < getVector().size())
+    {
+      m_next = index;
+    }
+    else if((null == getVector()) && (index < m_next))
+    {
+      while ((m_next >= index) && DTM.NULL != (n = previousNode()));
+    }
+    else
+    {   
+      while ((m_next < index) && DTM.NULL != (n = nextNode()));
+    }
+    
+  }
+
+  /**
+   * @see DTMIterator#setCurrentPos(int)
+   */
+  public void setCurrentPos(int i)
+  {
+  	runTo(i);
+  }
+
+  /**
+   * @see DTMIterator#item(int)
+   */
+  public int item(int index)
+  {
+  	setCurrentPos(index);
+  	int n = nextNode();
+  	m_next = index;
+  	return n;
+  }
+
+  /**
+   * @see DTMIterator#setItem(int, int)
+   */
+  public void setItem(int node, int index)
+  {
+  	NodeVector vec = getVector();
+  	if(null != vec)
+  	{
+        int oldNode = vec.elementAt(index);
+        if (oldNode != node && m_cache.useCount() > 1) {
+            /* If we are going to set the node at the given index
+             * to a different value, and the cache is shared
+             * (has a use count greater than 1)
+             * then make a copy of the cache and use it
+             * so we don't overwrite the value for other
+             * users of the cache.
+             */
+            IteratorCache newCache = new IteratorCache();
+            final NodeVector nv;
+            try {
+                nv = (NodeVector) vec.clone();
+            } catch (CloneNotSupportedException e) {
+                // This should never happen
+                e.printStackTrace();
+                RuntimeException rte = new RuntimeException(e.getMessage()); 
+                throw rte;
+            }
+            newCache.setVector(nv);
+            newCache.setCacheComplete(true);
+            m_cache = newCache;
+            vec = nv;
+            
+            // Keep our superclass informed of the current NodeVector
+            super.setObject(nv); 
+            
+            /* When we get to here the new cache has
+             * a use count of 1 and when setting a
+             * bunch of values on the same NodeSequence,
+             * such as when sorting, we will keep setting
+             * values in that same copy which has a use count of 1.
+             */
+        }
+  		vec.setElementAt(node, index);
+  		m_last = vec.size();
+  	}
+  	else
+  		m_iter.setItem(node, index);
+  }
+
+  /**
+   * @see DTMIterator#getLength()
+   */
+  public int getLength()
+  {
+    IteratorCache cache = getCache();
+    
+  	if(cache != null)
+  	{
+        // Nodes from the iterator are cached
+        if (cache.isComplete()) {
+            // All of the nodes from the iterator are cached
+            // so just return the number of nodes in the cache
+            NodeVector nv = cache.getVector();
+            return nv.size();
+        }
+        
+        // If this NodeSequence wraps a mutable nodeset, then
+        // m_last will not reflect the size of the nodeset if
+        // it has been mutated...
+        if (m_iter instanceof NodeSetDTM)
+        {
+            return m_iter.getLength();
+        }    
+        
+	  	if(-1 == m_last)
+	  	{
+	  		int pos = m_next;
+	  		runTo(-1);
+	  		m_next = pos;
+	  	}
+	    return m_last;
+  	}
+  	else
+  	{
+  		return (-1 == m_last) ? (m_last = m_iter.getLength()) : m_last;
+  	}
+  }
+
+  /**
+   * Note: Not a deep clone.
+   * @see DTMIterator#cloneWithReset()
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+  	NodeSequence seq = (NodeSequence)super.clone();
+    seq.m_next = 0;
+    if (m_cache != null) {
+        // In making this clone of an iterator we are making
+        // another NodeSequence object it has a reference
+        // to the same IteratorCache object as the original
+        // so we need to remember that more than one
+        // NodeSequence object shares the cache.
+        m_cache.increaseUseCount();
+    }
+    
+    return seq;
+  }
+  
+  /**
+   * Get a clone of this iterator, but don't reset the iteration in the 
+   * process, so that it may be used from the current position.
+   * Note: Not a deep clone.
+   *
+   * @return A clone of this object.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+          NodeSequence clone = (NodeSequence) super.clone();
+          if (null != m_iter) clone.m_iter = (DTMIterator) m_iter.clone();
+          if (m_cache != null) {
+              // In making this clone of an iterator we are making
+              // another NodeSequence object it has a reference
+              // to the same IteratorCache object as the original
+              // so we need to remember that more than one
+              // NodeSequence object shares the cache.
+              m_cache.increaseUseCount();
+          }
+          
+          return clone;
+  }
+
+
+  /**
+   * @see DTMIterator#isDocOrdered()
+   */
+  public boolean isDocOrdered()
+  {
+  	if(null != m_iter)
+  		return m_iter.isDocOrdered();
+  	else
+    	return true; // can't be sure?
+  }
+
+  /**
+   * @see DTMIterator#getAxis()
+   */
+  public int getAxis()
+  {
+  	if(null != m_iter)
+    	return m_iter.getAxis();
+    else
+    {
+    	assertion(false, "Can not getAxis from a non-iterated node sequence!");
+    	return 0;
+    }
+  }
+
+  /**
+   * @see PathComponent#getAnalysisBits()
+   */
+  public int getAnalysisBits()
+  {
+  	if((null != m_iter) && (m_iter instanceof PathComponent))
+    	return ((PathComponent)m_iter).getAnalysisBits();
+    else
+    	return 0;
+  }
+
+  /**
+   * @see org.apache.xpath.Expression#fixupVariables(Vector, int)
+   */
+  public void fixupVariables(Vector vars, int globalsSize)
+  {
+  	super.fixupVariables(vars, globalsSize);
+  }  
+  
+  /**
+   * Add the node into a vector of nodes where it should occur in
+   * document order.
+   * @param node The node to be added.
+   * @return insertIndex.
+   * @throws RuntimeException thrown if this NodeSetDTM is not of 
+   * a mutable type.
+   */
+   protected int addNodeInDocOrder(int node)
+   {
+      assertion(hasCache(), "addNodeInDocOrder must be done on a mutable sequence!");
+
+      int insertIndex = -1;
+      
+      NodeVector vec = getVector();
+
+      // This needs to do a binary search, but a binary search 
+      // is somewhat tough because the sequence test involves 
+      // two nodes.
+      int size = vec.size(), i;
+
+      for (i = size - 1; i >= 0; i--)
+      {
+        int child = vec.elementAt(i);
+
+        if (child == node)
+        {
+          i = -2; // Duplicate, suppress insert
+
+          break;
+        }
+
+        DTM dtm = m_dtmMgr.getDTM(node);
+        if (!dtm.isNodeAfter(node, child))
+        {
+          break;
+        }
+      }
+
+      if (i != -2)
+      {
+        insertIndex = i + 1;
+
+        vec.insertElementAt(node, insertIndex);
+      }
+
+      // checkDups();
+      return insertIndex;
+    } // end addNodeInDocOrder(Vector v, Object obj)
+   
+   /**
+    * It used to be that many locations in the code simply
+    * did an assignment to this.m_obj directly, rather than
+    * calling the setObject(Object) method. The problem is
+    * that our super-class would be updated on what the 
+    * cache associated with this NodeSequence, but
+    * we wouldn't know ourselves.
+    * <p>
+    * All setting of m_obj is done through setObject() now,
+    * and this method over-rides the super-class method.
+    * So now we are in the loop have an opportunity
+    * to update some caching information.
+    *
+    */
+   protected void setObject(Object obj) {
+       if (obj instanceof NodeVector) {
+           // Keep our superclass informed of the current NodeVector
+           // ... if we don't the smoketest fails (don't know why).
+           super.setObject(obj);
+           
+           // A copy of the code of what SetVector() would do.
+           NodeVector v = (NodeVector)obj;
+           if (m_cache != null) {
+               m_cache.setVector(v);
+           } else if (v!=null) {
+               m_cache = new IteratorCache();
+               m_cache.setVector(v);
+           }
+       } else if (obj instanceof IteratorCache) {
+           IteratorCache cache = (IteratorCache) obj;
+           m_cache = cache;
+           m_cache.increaseUseCount();
+           
+           // Keep our superclass informed of the current NodeVector
+           super.setObject(cache.getVector());
+       } else {
+           super.setObject(obj);
+       }
+       
+   }
+
+   /**
+    * Each NodeSequence object has an iterator which is "walked".
+    * As an iterator is walked one obtains nodes from it.
+    * As those nodes are obtained they may be cached, making
+    * the next walking of a copy or clone of the iterator faster.
+    * This field (m_cache) is a reference to such a cache, 
+    * which is populated as the iterator is walked.
+    * <p>
+    * Note that multiple NodeSequence objects may hold a 
+    * reference to the same cache, and also 
+    * (and this is important) the same iterator.
+    * The iterator and its cache may be shared among 
+    * many NodeSequence objects.
+    * <p>
+    * If one of the NodeSequence objects walks ahead
+    * of the others it fills in the cache.
+    * As the others NodeSequence objects catch up they
+    * get their values from
+    * the cache rather than the iterator itself, so
+    * the iterator is only ever walked once and everyone
+    * benefits from the cache.
+    * <p>
+    * At some point the cache may be
+    * complete due to walking to the end of one of
+    * the copies of the iterator, and the cache is
+    * then marked as "complete".
+    * and the cache will have no more nodes added to it.
+    * <p>
+    * Its use-count is the number of NodeSequence objects that use it.
+    */
+   private final static class IteratorCache {
+       /**
+        * A list of nodes already obtained from the iterator.
+        * As the iterator is walked the nodes obtained from
+        * it are appended to this list.
+        * <p>
+        * Both an iterator and its corresponding cache can
+        * be shared by multiple NodeSequence objects.
+        * <p>
+        * For example, consider three NodeSequence objects
+        * ns1, ns2 and ns3 doing such sharing, and the
+        * nodes to be obtaind from the iterator being 
+        * the sequence { 33, 11, 44, 22, 55 }.
+        * <p>
+        * If ns3.nextNode() is called 3 times the the
+        * underlying iterator will have walked through
+        * 33, 11, 55 and these three nodes will have been put
+        * in the cache.
+        * <p>
+        * If ns2.nextNode() is called 2 times it will return
+        * 33 and 11 from the cache, leaving the iterator alone.
+        * <p>
+        * If ns1.nextNode() is called 6 times it will return
+        * 33 and 11 from the cache, then get 44, 22, 55 from
+        * the iterator, and appending 44, 22, 55 to the cache.
+        * On the sixth call it is found that the iterator is
+        * exhausted and the cache is marked complete.
+        * <p>
+        * Should ns2 or ns3 have nextNode() called they will
+        * know that the cache is complete, and they will
+        * obtain all subsequent nodes from the cache.
+        * <p>
+        * Note that the underlying iterator, though shared
+        * is only ever walked once. 
+        */
+        private NodeVector m_vec2;
+
+        /**
+         * true if the associated iterator is exhausted and
+         * all nodes obtained from it are in the cache.
+         */
+        private boolean m_isComplete2;
+
+        private int m_useCount2;
+
+        IteratorCache() {
+            m_vec2 = null;
+            m_isComplete2 = false;
+            m_useCount2 = 1;
+            return;
+        }
+
+        /**
+         * Returns count of how many NodeSequence objects share this
+         * IteratorCache object.
+         */
+        private int useCount() {
+            return m_useCount2;
+        }
+
+        /**
+         * This method is called when yet another
+         * NodeSequence object uses, or shares
+         * this same cache.
+         *
+         */
+        private void increaseUseCount() {
+            if (m_vec2 != null)
+                m_useCount2++;
+
+        }
+
+        /**
+         * Sets the NodeVector that holds the
+         * growing list of nodes as they are appended
+         * to the cached list.
+         */
+        private void setVector(NodeVector nv) {
+            m_vec2 = nv;
+            m_useCount2 = 1;
+        }
+
+        /**
+         * Get the cached list of nodes obtained from
+         * the iterator so far.
+         */
+        private NodeVector getVector() {
+            return m_vec2;
+        }
+
+        /**
+         * Call this method with 'true' if the
+         * iterator is exhausted and the cached list
+         * is complete, or no longer growing.
+         */
+        private void setCacheComplete(boolean b) {
+            m_isComplete2 = b;
+
+        }
+
+        /**
+         * Returns true if no cache is complete
+         * and immutable.
+         */
+        private boolean isComplete() {
+            return m_isComplete2;
+        }
+    }
+   
+    /**
+     * Get the cached list of nodes appended with
+     * values obtained from the iterator as
+     * a NodeSequence is walked when its
+     * nextNode() method is called.
+     */
+    protected IteratorCache getIteratorCache() {
+        return m_cache;
+    }
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/OneStepIterator.java b/src/main/java/org/apache/xpath/axes/OneStepIterator.java
new file mode 100644
index 0000000..43ae094
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/OneStepIterator.java
@@ -0,0 +1,345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OneStepIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisIterator;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpMap;
+
+/**
+ * This class implements a general iterator for
+ * those LocationSteps with only one step, and perhaps a predicate.
+ * @see org.apache.xpath.axes#LocPathIterator
+ * @xsl.usage advanced
+ */
+public class OneStepIterator extends ChildTestIterator
+{
+    static final long serialVersionUID = 4623710779664998283L;
+  /** The traversal axis from where the nodes will be filtered. */
+  protected int m_axis = -1;
+
+  /** The DTM inner traversal class, that corresponds to the super axis. */
+  protected DTMAxisIterator m_iterator;
+
+  /**
+   * Create a OneStepIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  OneStepIterator(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis);
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+    
+    m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos);
+    
+  }
+  
+  
+  /**
+   * Create a OneStepIterator object.
+   *
+   * @param iterator The DTM iterator which this iterator will use.
+   * @param axis One of Axis.Child, etc., or -1 if the axis is unknown.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public OneStepIterator(DTMAxisIterator iterator, int axis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(null);
+    
+    m_iterator = iterator;
+    m_axis = axis;
+    int whatToShow = DTMFilter.SHOW_ALL;
+    initNodeTest(whatToShow);
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+    if(m_axis > -1)
+      m_iterator = m_cdtm.getAxisIterator(m_axis);
+    m_iterator.setStartNode(m_context);
+  }
+
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {    
+    if(m_allowDetach)
+    {
+      if(m_axis > -1)
+        m_iterator = null;
+      
+      // Always call the superclass detach last!
+      super.detach();
+    }
+  }
+  
+  /**
+   * Get the next node via getFirstAttribute && getNextAttribute.
+   */
+  protected int getNextNode()
+  {
+    return m_lastFetched = m_iterator.next();
+  }
+  
+  /**
+   * Get a cloned iterator.
+   *
+   * @return A new iterator that can be used without mutating this one.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+    // Do not access the location path itterator during this operation!
+    
+    OneStepIterator clone = (OneStepIterator) super.clone();
+
+    if(m_iterator != null)
+    {
+      clone.m_iterator = m_iterator.cloneIterator();
+    }
+    return clone;
+  }
+  
+  /**
+   *  Get a cloned Iterator that is reset to the beginning
+   *  of the query.
+   * 
+   *  @return A cloned NodeIterator set of the start of the query.
+   * 
+   *  @throws CloneNotSupportedException
+   */
+  public DTMIterator cloneWithReset() throws CloneNotSupportedException
+  {
+
+    OneStepIterator clone = (OneStepIterator) super.cloneWithReset();
+    clone.m_iterator = m_iterator;
+
+    return clone;
+  }
+
+
+
+  /**
+   * Tells if this is a reverse axes.  Overrides AxesWalker#isReverseAxes.
+   *
+   * @return true for this class.
+   */
+  public boolean isReverseAxes()
+  {
+    return m_iterator.isReverse();
+  }
+
+  /**
+   * Get the current sub-context position.  In order to do the
+   * reverse axes count, for the moment this re-searches the axes
+   * up to the predicate.  An optimization on this is to cache
+   * the nodes searched, but, for the moment, this case is probably
+   * rare enough that the added complexity isn't worth it.
+   *
+   * @param predicateIndex The predicate index of the proximity position.
+   *
+   * @return The pridicate index, or -1.
+   */
+  protected int getProximityPosition(int predicateIndex)
+  {
+    if(!isReverseAxes())
+      return super.getProximityPosition(predicateIndex);
+      
+    // A negative predicate index seems to occur with
+    // (preceding-sibling::*|following-sibling::*)/ancestor::*[position()]/*[position()]
+    // -sb
+    if(predicateIndex < 0)
+      return -1;
+      
+    if (m_proximityPositions[predicateIndex] <= 0)
+    {
+      XPathContext xctxt = getXPathContext();
+      try
+      {
+        OneStepIterator clone = (OneStepIterator) this.clone();
+        
+        int root = getRoot();
+        xctxt.pushCurrentNode(root);
+        clone.setRoot(root, xctxt);
+
+        // clone.setPredicateCount(predicateIndex);
+        clone.m_predCount = predicateIndex;
+
+        // Count 'em all
+        int count = 1;
+        int next;
+
+        while (DTM.NULL != (next = clone.nextNode()))
+        {
+          count++;
+        }
+
+        m_proximityPositions[predicateIndex] += count;
+      }
+      catch (CloneNotSupportedException cnse)
+      {
+
+        // can't happen
+      }
+      finally
+      {
+        xctxt.popCurrentNode();
+      }
+    }
+
+    return m_proximityPositions[predicateIndex];
+  }
+
+  /**
+   *  The number of nodes in the list. The range of valid child node indices
+   * is 0 to <code>length-1</code> inclusive.
+   *
+   * @return The number of nodes in the list, always greater or equal to zero.
+   */
+  public int getLength()
+  {
+    if(!isReverseAxes())
+      return super.getLength();
+      
+    // Tell if this is being called from within a predicate.
+    boolean isPredicateTest = (this == m_execContext.getSubContextList());
+
+    // And get how many total predicates are part of this step.
+    int predCount = getPredicateCount();
+   
+    // If we have already calculated the length, and the current predicate 
+    // is the first predicate, then return the length.  We don't cache 
+    // the anything but the length of the list to the first predicate.
+    if (-1 != m_length && isPredicateTest && m_predicateIndex < 1)
+       return m_length;      
+
+    int count = 0;
+    
+    XPathContext xctxt = getXPathContext();
+    try
+    {
+      OneStepIterator clone = (OneStepIterator) this.cloneWithReset();
+      
+      int root = getRoot();
+      xctxt.pushCurrentNode(root);
+      clone.setRoot(root, xctxt);
+ 
+      clone.m_predCount = m_predicateIndex;
+
+      int next;
+
+      while (DTM.NULL != (next = clone.nextNode()))
+      {
+        count++;
+      }
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+       // can't happen
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+    }
+    if (isPredicateTest && m_predicateIndex < 1)
+      m_length = count;    
+      
+    return count;
+  }
+
+  /**
+   * Count backwards one proximity position.
+   *
+   * @param i The predicate index.
+   */
+  protected void countProximityPosition(int i)
+  {
+    if(!isReverseAxes())
+      super.countProximityPosition(i);
+    else if (i < m_proximityPositions.length)
+      m_proximityPositions[i]--;
+  }
+  
+  /**
+   * Reset the iterator.
+   */
+  public void reset()
+  {
+
+    super.reset();
+    if(null != m_iterator)
+      m_iterator.reset();
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return m_axis;
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(m_axis != ((OneStepIterator)expr).m_axis)
+  		return false;
+  		
+  	return true;
+  }
+
+  
+}
diff --git a/src/main/java/org/apache/xpath/axes/OneStepIteratorForward.java b/src/main/java/org/apache/xpath/axes/OneStepIteratorForward.java
new file mode 100644
index 0000000..854da45
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/OneStepIteratorForward.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OneStepIteratorForward.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xpath.Expression;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpMap;
+
+/**
+ * This class implements a general iterator for
+ * those LocationSteps with only one step, and perhaps a predicate, 
+ * that only go forward (i.e. it can not be used with ancestors, 
+ * preceding, etc.)
+ * @see org.apache.xpath.axes#ChildTestIterator
+ * @xsl.usage advanced
+ */
+public class OneStepIteratorForward extends ChildTestIterator
+{
+    static final long serialVersionUID = -1576936606178190566L;
+  /** The traversal axis from where the nodes will be filtered. */
+  protected int m_axis = -1;
+
+  /**
+   * Create a OneStepIterator object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  OneStepIteratorForward(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis);
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+    
+    m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos);
+    
+  }
+    
+  /**
+   * Create a OneStepIterator object that will just traverse the self axes.
+   * 
+   * @param axis One of the org.apache.xml.dtm.Axis integers.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public OneStepIteratorForward(int axis)
+  {
+    super(null);
+    
+    m_axis = axis;
+    int whatToShow = DTMFilter.SHOW_ALL;
+    initNodeTest(whatToShow);
+  }
+
+  
+
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+    m_traverser = m_cdtm.getAxisTraverser(m_axis);
+    
+  }
+  
+//  /**
+//   * Return the first node out of the nodeset, if this expression is 
+//   * a nodeset expression.  This is the default implementation for 
+//   * nodesets.
+//   * <p>WARNING: Do not mutate this class from this function!</p>
+//   * @param xctxt The XPath runtime context.
+//   * @return the first node out of the nodeset, or DTM.NULL.
+//   */
+//  public int asNode(XPathContext xctxt)
+//    throws javax.xml.transform.TransformerException
+//  {
+//    if(getPredicateCount() > 0)
+//      return super.asNode(xctxt);
+//      
+//    int current = xctxt.getCurrentNode();
+//    
+//    DTM dtm = xctxt.getDTM(current);
+//    DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
+//    
+//    String localName = getLocalName();
+//    String namespace = getNamespace();
+//    int what = m_whatToShow;
+//    
+//    // System.out.println("what: ");
+//    // NodeTest.debugWhatToShow(what);
+//    if(DTMFilter.SHOW_ALL == what
+//       || ((DTMFilter.SHOW_ELEMENT & what) == 0)
+//       || localName == NodeTest.WILD
+//       || namespace == NodeTest.WILD)
+//    {
+//      return traverser.first(current);
+//    }
+//    else
+//    {
+//      int type = getNodeTypeTest(what);
+//      int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
+//      return traverser.first(current, extendedType);
+//    }
+//  }
+  
+  /**
+   * Get the next node via getFirstAttribute && getNextAttribute.
+   */
+  protected int getNextNode()
+  {
+    m_lastFetched = (DTM.NULL == m_lastFetched)
+                     ? m_traverser.first(m_context)
+                     : m_traverser.next(m_context, m_lastFetched);
+    return m_lastFetched;
+  }
+  
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    return m_axis;
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(m_axis != ((OneStepIteratorForward)expr).m_axis)
+  		return false;
+  		
+  	return true;
+  }
+
+  
+}
diff --git a/src/main/java/org/apache/xpath/axes/PathComponent.java b/src/main/java/org/apache/xpath/axes/PathComponent.java
new file mode 100644
index 0000000..c7a2b85
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/PathComponent.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: PathComponent.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+/**
+ * Classes who implement this information provide information needed for 
+ * static analysis of a path component.
+ */
+public interface PathComponent
+{
+  /** 
+   * Get the analysis bits for this path component, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits();
+
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/PredicatedNodeTest.java b/src/main/java/org/apache/xpath/axes/PredicatedNodeTest.java
new file mode 100644
index 0000000..f72ea3a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/PredicatedNodeTest.java
@@ -0,0 +1,647 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: PredicatedNodeTest.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.patterns.NodeTest;
+
+public abstract class PredicatedNodeTest extends NodeTest implements SubContextList
+{
+    static final long serialVersionUID = -6193530757296377351L;
+
+  /**
+   * Construct an AxesWalker using a LocPathIterator.
+   *
+   * @param locPathIterator non-null reference to the parent iterator.
+   */
+  PredicatedNodeTest(LocPathIterator locPathIterator)
+  {
+    m_lpi = locPathIterator;
+  }
+  
+  /**
+   * Construct an AxesWalker.  The location path iterator will have to be set
+   * before use.
+   */
+  PredicatedNodeTest()
+  {
+  }
+  
+  /**
+   * Read the object from a serialization stream.
+   *
+   * @param stream Input stream to read from
+   *
+   * @throws java.io.IOException
+   * @throws javax.xml.transform.TransformerException
+   */
+  private void readObject(java.io.ObjectInputStream stream)
+          throws java.io.IOException, javax.xml.transform.TransformerException
+  {
+    try
+    {
+      stream.defaultReadObject();
+      m_predicateIndex = -1;
+      resetProximityPositions();
+    }
+    catch (ClassNotFoundException cnfe)
+    {
+      throw new javax.xml.transform.TransformerException(cnfe);
+    }
+  }
+  
+  /**
+   * Get a cloned PrdicatedNodeTest.
+   *
+   * @return A new PredicatedNodeTest that can be used without mutating this one.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+    // Do not access the location path itterator during this operation!
+    
+    PredicatedNodeTest clone = (PredicatedNodeTest) super.clone();
+
+    if ((null != this.m_proximityPositions)
+            && (this.m_proximityPositions == clone.m_proximityPositions))
+    {
+      clone.m_proximityPositions = new int[this.m_proximityPositions.length];
+
+      System.arraycopy(this.m_proximityPositions, 0,
+                       clone.m_proximityPositions, 0,
+                       this.m_proximityPositions.length);
+    }
+    
+    if(clone.m_lpi == this)
+      clone.m_lpi = (LocPathIterator)clone;
+
+    return clone;
+  }
+  
+  // Only for clones for findLastPos.  See bug4638.
+  protected int m_predCount = -1;
+
+  /**
+   * Get the number of predicates that this walker has.
+   *
+   * @return the number of predicates that this walker has.
+   */
+  public int getPredicateCount()
+  {
+    if(-1 == m_predCount)
+      return (null == m_predicates) ? 0 : m_predicates.length;
+    else
+      return m_predCount;
+  }
+
+  /**
+   * Set the number of predicates that this walker has.  This does more 
+   * that one would think, as it creates a new predicate array of the 
+   * size of the count argument, and copies count predicates into the new 
+   * one from the old, and then reassigns the predicates value.  All this 
+   * to keep from having to have a predicate count value.
+   *
+   * @param count The number of predicates, which must be equal or less 
+   *               than the existing count.
+   */
+  public void setPredicateCount(int count)
+  {
+    if(count > 0)
+    {
+      Expression[] newPredicates = new Expression[count];
+      for (int i = 0; i < count; i++) 
+      {
+        newPredicates[i] = m_predicates[i];
+      }
+      m_predicates = newPredicates;
+    }
+    else
+      m_predicates = null;
+    
+  }
+
+  /**
+   * Init predicate info.
+   *
+   * @param compiler The Compiler object that has information about this 
+   *                 walker in the op map.
+   * @param opPos The op code position of this location step.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void initPredicateInfo(Compiler compiler, int opPos)
+          throws javax.xml.transform.TransformerException
+  {
+
+    int pos = compiler.getFirstPredicateOpPos(opPos);
+
+    if(pos > 0)
+    {
+      m_predicates = compiler.getCompiledPredicates(pos);
+      if(null != m_predicates)
+      {
+      	for(int i = 0; i < m_predicates.length; i++)
+      	{
+      		m_predicates[i].exprSetParent(this);
+      	}
+      }
+    }
+  }
+
+  /**
+   * Get a predicate expression at the given index.
+   *
+   *
+   * @param index Index of the predicate.
+   *
+   * @return A predicate expression.
+   */
+  public Expression getPredicate(int index)
+  {
+    return m_predicates[index];
+  }
+  
+  /**
+   * Get the current sub-context position.
+   *
+   * @return The node position of this walker in the sub-context node list.
+   */
+  public int getProximityPosition()
+  {
+
+    // System.out.println("getProximityPosition - m_predicateIndex: "+m_predicateIndex);
+    return getProximityPosition(m_predicateIndex);
+  }
+
+  /**
+   * Get the current sub-context position.
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return The node position of this walker in the sub-context node list.
+   */
+  public int getProximityPosition(XPathContext xctxt)
+  {
+    return getProximityPosition();
+  }
+  
+  /**
+   * Get the index of the last node that can be itterated to.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the index of the last node that can be itterated to.
+   */
+  public abstract int getLastPos(XPathContext xctxt);
+
+  /**
+   * Get the current sub-context position.
+   *
+   * @param predicateIndex The index of the predicate where the proximity 
+   *                       should be taken from.
+   *
+   * @return The node position of this walker in the sub-context node list.
+   */
+  protected int getProximityPosition(int predicateIndex)
+  {
+    return (predicateIndex >= 0) ? m_proximityPositions[predicateIndex] : 0;
+  }
+
+  /**
+   * Reset the proximity positions counts.
+   */
+  public void resetProximityPositions()
+  {
+    int nPredicates = getPredicateCount();
+    if (nPredicates > 0)
+    {
+      if (null == m_proximityPositions)
+        m_proximityPositions = new int[nPredicates];
+
+      for (int i = 0; i < nPredicates; i++)
+      {
+        try
+        {
+          initProximityPosition(i);
+        }
+        catch(Exception e)
+        {
+          // TODO: Fix this...
+          throw new org.apache.xml.utils.WrappedRuntimeException(e);
+        }
+      }
+    }
+  }
+
+  /**
+   * Init the proximity position to zero for a forward axes.
+   *
+   * @param i The index into the m_proximityPositions array.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void initProximityPosition(int i) throws javax.xml.transform.TransformerException
+  {
+    m_proximityPositions[i] = 0;
+  }
+
+  /**
+   * Count forward one proximity position.
+   *
+   * @param i The index into the m_proximityPositions array, where the increment 
+   *          will occur.
+   */
+  protected void countProximityPosition(int i)
+  {
+  	// Note that in the case of a UnionChildIterator, this may be a 
+  	// static object and so m_proximityPositions may indeed be null!
+  	int[] pp = m_proximityPositions;
+    if ((null != pp) && (i < pp.length))
+      pp[i]++;
+  }
+
+  /**
+   * Tells if this is a reverse axes.
+   *
+   * @return false, unless a derived class overrides.
+   */
+  public boolean isReverseAxes()
+  {
+    return false;
+  }
+
+  /**
+   * Get which predicate is executing.
+   *
+   * @return The current predicate index, or -1 if no predicate is executing.
+   */
+  public int getPredicateIndex()
+  {
+    return m_predicateIndex;
+  }
+
+  /**
+   * Process the predicates.
+   *
+   * @param context The current context node.
+   * @param xctxt The XPath runtime context.
+   *
+   * @return the result of executing the predicate expressions.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  boolean executePredicates(int context, XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    
+    int nPredicates = getPredicateCount();
+    // System.out.println("nPredicates: "+nPredicates);
+    if (nPredicates == 0)
+      return true;
+
+    PrefixResolver savedResolver = xctxt.getNamespaceContext();
+
+    try
+    {
+      m_predicateIndex = 0;
+      xctxt.pushSubContextList(this);
+      xctxt.pushNamespaceContext(m_lpi.getPrefixResolver());
+      xctxt.pushCurrentNode(context);
+
+      for (int i = 0; i < nPredicates; i++)
+      {
+        // System.out.println("Executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
+        XObject pred = m_predicates[i].execute(xctxt);
+        // System.out.println("\nBack from executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
+        // System.out.println("pred.getType(): "+pred.getType());
+        if (XObject.CLASS_NUMBER == pred.getType())
+        {
+          if (DEBUG_PREDICATECOUNTING)
+          {
+            System.out.flush();
+            System.out.println("\n===== start predicate count ========");
+            System.out.println("m_predicateIndex: " + m_predicateIndex);
+            // System.out.println("getProximityPosition(m_predicateIndex): "
+            //                   + getProximityPosition(m_predicateIndex));
+            System.out.println("pred.num(): " + pred.num());
+          }
+
+          int proxPos = this.getProximityPosition(m_predicateIndex);
+          int predIndex = (int) pred.num();
+          if (proxPos != predIndex)
+          {
+            if (DEBUG_PREDICATECOUNTING)
+            {
+              System.out.println("\nnode context: "+nodeToString(context));
+              System.out.println("index predicate is false: "+proxPos);
+              System.out.println("\n===== end predicate count ========");
+            }
+            return false;
+          }
+          else if (DEBUG_PREDICATECOUNTING)
+          {
+            System.out.println("\nnode context: "+nodeToString(context));
+            System.out.println("index predicate is true: "+proxPos);
+            System.out.println("\n===== end predicate count ========");
+          }
+          
+          // If there is a proximity index that will not change during the 
+          // course of itteration, then we know there can be no more true 
+          // occurances of this predicate, so flag that we're done after 
+          // this.
+          //
+          // bugzilla 14365
+          // We can't set m_foundLast = true unless we're sure that -all-
+          // remaining parameters are stable, or else last() fails. Fixed so
+          // only sets m_foundLast if on the last predicate
+          if(m_predicates[i].isStableNumber() && i == nPredicates - 1)
+          {
+            m_foundLast = true;
+          }
+        }
+        else if (!pred.bool())
+          return false;
+
+        countProximityPosition(++m_predicateIndex);
+      }
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      xctxt.popNamespaceContext();
+      xctxt.popSubContextList();
+      m_predicateIndex = -1;
+    }
+
+    return true;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+
+    int nPredicates = getPredicateCount();
+
+    for (int i = 0; i < nPredicates; i++)
+    {
+      m_predicates[i].fixupVariables(vars, globalsSize);
+    }
+  }
+
+  
+  /**
+   * Diagnostics.
+   *
+   * @param n Node to give diagnostic information about, or null.
+   *
+   * @return Informative string about the argument.
+   */
+  protected String nodeToString(int n)
+  {
+    if(DTM.NULL != n)
+    {
+      DTM dtm = m_lpi.getXPathContext().getDTM(n);
+      return dtm.getNodeName(n) + "{" + (n+1) + "}";
+    }
+    else
+    {
+      return "null";
+    }
+  }
+  
+  //=============== NodeFilter Implementation ===============
+
+  /**
+   *  Test whether a specified node is visible in the logical view of a
+   * TreeWalker or NodeIterator. This function will be called by the
+   * implementation of TreeWalker and NodeIterator; it is not intended to
+   * be called directly from user code.
+   * @param n  The node to check to see if it passes the filter or not.
+   * @return  a constant to determine whether the node is accepted,
+   *   rejected, or skipped, as defined  above .
+   */
+  public short acceptNode(int n)
+  {
+
+    XPathContext xctxt = m_lpi.getXPathContext();
+
+    try
+    {
+      xctxt.pushCurrentNode(n);
+
+      XObject score = execute(xctxt, n);
+
+      // System.out.println("\n::acceptNode - score: "+score.num()+"::");
+      if (score != NodeTest.SCORE_NONE)
+      {
+        if (getPredicateCount() > 0)
+        {
+          countProximityPosition(0);
+
+          if (!executePredicates(n, xctxt))
+            return DTMIterator.FILTER_SKIP;
+        }
+
+        return DTMIterator.FILTER_ACCEPT;
+      }
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: Fix this.
+      throw new RuntimeException(se.getMessage());
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+    }
+
+    return DTMIterator.FILTER_SKIP;
+  }
+
+  
+  /**
+   * Get the owning location path iterator.
+   *
+   * @return the owning location path iterator, which should not be null.
+   */
+  public LocPathIterator getLocPathIterator()
+  {
+    return m_lpi;
+  }
+
+  /**
+   * Set the location path iterator owner for this walker.  Besides 
+   * initialization, this function is called during cloning operations.
+   *
+   * @param li non-null reference to the owning location path iterator.
+   */
+  public void setLocPathIterator(LocPathIterator li)
+  {
+    m_lpi = li;
+    if(this != li)
+      li.exprSetParent(this);
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    int n = getPredicateCount();
+    for (int i = 0; i < n; i++) 
+    {
+      if(getPredicate(i).canTraverseOutsideSubtree())
+        return true;
+    }
+    return false;
+   }
+   
+	/**
+	 * This will traverse the heararchy, calling the visitor for 
+	 * each member.  If the called visitor method returns 
+	 * false, the subtree should not be called.
+	 * 
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callPredicateVisitors(XPathVisitor visitor)
+	{
+	  if (null != m_predicates)
+	    {
+	    int n = m_predicates.length;
+	    for (int i = 0; i < n; i++)
+	      {
+	      ExpressionOwner predOwner = new PredOwner(i);
+	      if (visitor.visitPredicate(predOwner, m_predicates[i]))
+	        {
+	        m_predicates[i].callVisitors(predOwner, visitor);
+	      }
+	
+	    }
+	  }
+	} 
+	
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+            return false;
+
+      PredicatedNodeTest pnt = (PredicatedNodeTest) expr;
+      if (null != m_predicates)
+      {
+
+        int n = m_predicates.length;
+        if ((null == pnt.m_predicates) || (pnt.m_predicates.length != n))
+              return false;
+        for (int i = 0; i < n; i++)
+        {
+          if (!m_predicates[i].deepEquals(pnt.m_predicates[i]))
+          	return false; 
+        }
+      }
+      else if (null != pnt.m_predicates)
+              return false; 
+              
+      return true; 
+    }
+    
+  /** This is true if nextNode returns null. */
+  transient protected boolean m_foundLast = false;
+    
+  /** The owning location path iterator.
+   *  @serial */
+  protected LocPathIterator m_lpi;
+  
+  /**
+   * Which predicate we are executing.
+   */
+  transient int m_predicateIndex = -1;
+  
+  /** The list of predicate expressions. Is static and does not need 
+   *  to be deep cloned.
+   *  @serial 
+   */
+  private Expression[] m_predicates;
+
+  /**
+   * An array of counts that correspond to the number
+   * of predicates the step contains.
+   */
+  transient protected int[] m_proximityPositions;
+
+  /** If true, diagnostic messages about predicate execution will be posted.  */
+  static final boolean DEBUG_PREDICATECOUNTING = false;
+  
+  class PredOwner implements ExpressionOwner
+  {
+  	int m_index;
+  	
+  	PredOwner(int index)
+  	{
+  		m_index = index;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_predicates[m_index];
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(PredicatedNodeTest.this);
+    	m_predicates[m_index] = exp;
+    }
+  }
+    
+}
diff --git a/src/main/java/org/apache/xpath/axes/RTFIterator.java b/src/main/java/org/apache/xpath/axes/RTFIterator.java
new file mode 100644
index 0000000..cb018b4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/RTFIterator.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: RTFIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+
+/**
+ * This class implements an RTF Iterator. Currently exists for sole
+ * purpose of enabling EXSLT object-type function to return "RTF".
+ * 
+  * @xsl.usage advanced
+  */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.NodeSetDTM;
+
+public class RTFIterator extends NodeSetDTM {
+    static final long serialVersionUID = 7658117366258528996L;
+
+	/**
+	 * Constructor for RTFIterator
+	 */	
+	public RTFIterator(int root, DTMManager manager) {
+		super(root, manager);
+	}
+}
+
diff --git a/src/main/java/org/apache/xpath/axes/ReverseAxesWalker.java b/src/main/java/org/apache/xpath/axes/ReverseAxesWalker.java
new file mode 100644
index 0000000..4efd804
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/ReverseAxesWalker.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ReverseAxesWalker.java 513117 2007-03-01 03:28:52Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisIterator;
+import org.apache.xpath.XPathContext;
+
+/**
+ * Walker for a reverse axes.
+ * @see <a href="http://www.w3.org/TR/xpath#predicates">XPath 2.4 Predicates</a>
+ */
+public class ReverseAxesWalker extends AxesWalker
+{
+    static final long serialVersionUID = 2847007647832768941L;
+
+  /**
+   * Construct an AxesWalker using a LocPathIterator.
+   *
+   * @param locPathIterator The location path iterator that 'owns' this walker.
+   */
+  ReverseAxesWalker(LocPathIterator locPathIterator, int axis)
+  {
+    super(locPathIterator, axis);
+  }
+  
+  /**
+   * Set the root node of the TreeWalker.
+   * (Not part of the DOM2 TreeWalker interface).
+   *
+   * @param root The context node of this step.
+   */
+  public void setRoot(int root)
+  {
+    super.setRoot(root);
+    m_iterator = getDTM(root).getAxisIterator(m_axis);
+    m_iterator.setStartNode(root);
+  }
+
+  /**
+   * Detaches the walker from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state.
+   */
+  public void detach()
+  {
+    m_iterator = null;
+    super.detach();
+  }
+  
+  /**
+   * Get the next node in document order on the axes.
+   *
+   * @return the next node in document order on the axes, or null.
+   */
+  protected int getNextNode()
+  {
+    if (m_foundLast)
+      return DTM.NULL;
+
+    int next = m_iterator.next();
+    
+    if (m_isFresh)
+      m_isFresh = false;
+
+    if (DTM.NULL == next)
+      this.m_foundLast = true;
+
+    return next;
+  }
+
+
+  /**
+   * Tells if this is a reverse axes.  Overrides AxesWalker#isReverseAxes.
+   *
+   * @return true for this class.
+   */
+  public boolean isReverseAxes()
+  {
+    return true;
+  }
+
+//  /**
+//   *  Set the root node of the TreeWalker.
+//   *
+//   * @param root The context node of this step.
+//   */
+//  public void setRoot(int root)
+//  {
+//    super.setRoot(root);
+//  }
+
+  /**
+   * Get the current sub-context position.  In order to do the
+   * reverse axes count, for the moment this re-searches the axes
+   * up to the predicate.  An optimization on this is to cache
+   * the nodes searched, but, for the moment, this case is probably
+   * rare enough that the added complexity isn't worth it.
+   *
+   * @param predicateIndex The predicate index of the proximity position.
+   *
+   * @return The pridicate index, or -1.
+   */
+  protected int getProximityPosition(int predicateIndex)
+  {
+    // A negative predicate index seems to occur with
+    // (preceding-sibling::*|following-sibling::*)/ancestor::*[position()]/*[position()]
+    // -sb
+    if(predicateIndex < 0)
+      return -1;
+      
+    int count = m_proximityPositions[predicateIndex];
+      
+    if (count <= 0)
+    {
+      AxesWalker savedWalker = wi().getLastUsedWalker();
+
+      try
+      {
+        ReverseAxesWalker clone = (ReverseAxesWalker) this.clone();
+
+        clone.setRoot(this.getRoot());
+
+        clone.setPredicateCount(predicateIndex);
+
+        clone.setPrevWalker(null);
+        clone.setNextWalker(null);
+        wi().setLastUsedWalker(clone);
+
+        // Count 'em all
+        count++;
+        int next;
+
+        while (DTM.NULL != (next = clone.nextNode()))
+        {
+          count++;
+        }
+
+        m_proximityPositions[predicateIndex] = count;
+      }
+      catch (CloneNotSupportedException cnse)
+      {
+
+        // can't happen
+      }
+      finally
+      {
+        wi().setLastUsedWalker(savedWalker);
+      }
+    }
+    
+    return count;
+  }
+
+  /**
+   * Count backwards one proximity position.
+   *
+   * @param i The predicate index.
+   */
+  protected void countProximityPosition(int i)
+  {
+    if (i < m_proximityPositions.length)
+      m_proximityPositions[i]--;
+  }
+
+  /**
+   * Get the number of nodes in this node list.  The function is probably ill
+   * named?
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return the number of nodes in this node list.
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+
+    int count = 0;
+    AxesWalker savedWalker = wi().getLastUsedWalker();
+
+    try
+    {
+      ReverseAxesWalker clone = (ReverseAxesWalker) this.clone();
+
+      clone.setRoot(this.getRoot());
+
+      clone.setPredicateCount(m_predicateIndex);
+
+      clone.setPrevWalker(null);
+      clone.setNextWalker(null);
+      wi().setLastUsedWalker(clone);
+
+      // Count 'em all
+      // count = 1;
+      int next;
+
+      while (DTM.NULL != (next = clone.nextNode()))
+      {
+        count++;
+      }
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+
+      // can't happen
+    }
+    finally
+    {
+      wi().setLastUsedWalker(savedWalker);
+    }
+
+    return count;
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * Warning: This can only be called after setRoot has been called!
+   * 
+   * @return false.
+   */
+  public boolean isDocOrdered()
+  {
+    return false;  // I think.
+  }
+  
+  /** The DTM inner traversal class, that corresponds to the super axis. */
+  protected DTMAxisIterator m_iterator;
+}
diff --git a/src/main/java/org/apache/xpath/axes/SelfIteratorNoPredicate.java b/src/main/java/org/apache/xpath/axes/SelfIteratorNoPredicate.java
new file mode 100644
index 0000000..b63f8d6
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/SelfIteratorNoPredicate.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SelfIteratorNoPredicate.java 469263 2006-10-30 20:45:40Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Compiler;
+
+/**
+ * This class implements an optimized iterator for
+ * "." patterns, that is, the self axes without any predicates.  
+ * @see org.apache.xpath.axes.LocPathIterator
+ * @xsl.usage advanced
+ */
+public class SelfIteratorNoPredicate extends LocPathIterator
+{
+    static final long serialVersionUID = -4226887905279814201L;
+
+  /**
+   * Create a SelfIteratorNoPredicate object.
+   *
+   * @param compiler A reference to the Compiler that contains the op map.
+   * @param opPos The position within the op map, which contains the
+   * location path expression for this itterator.
+   * @param analysis Analysis bits.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  SelfIteratorNoPredicate(Compiler compiler, int opPos, int analysis)
+          throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, false);
+  }
+  
+  /**
+   * Create a SelfIteratorNoPredicate object.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public SelfIteratorNoPredicate()
+          throws javax.xml.transform.TransformerException
+  {
+    super(null);
+  }
+
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   *
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {
+    if (m_foundLast)
+      return DTM.NULL;
+      
+    int next;
+
+    m_lastFetched = next = (DTM.NULL == m_lastFetched)
+                           ? m_context
+                           : DTM.NULL;
+
+    // m_lastFetched = next;
+    if (DTM.NULL != next)
+    {
+      m_pos++;
+
+      return next;
+    }
+    else
+    {
+      m_foundLast = true;
+
+      return DTM.NULL;
+    }
+  }
+  
+  /**
+   * Return the first node out of the nodeset, if this expression is 
+   * a nodeset expression.  This is the default implementation for 
+   * nodesets.  Derived classes should try and override this and return a 
+   * value without having to do a clone operation.
+   * @param xctxt The XPath runtime context.
+   * @return the first node out of the nodeset, or DTM.NULL.
+   */
+  public int asNode(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException
+  {
+    return xctxt.getCurrentNode();
+  }
+  
+  /**
+   * Get the index of the last node that can be itterated to.
+   * This probably will need to be overridded by derived classes.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the index of the last node that can be itterated to.
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+    return 1;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/SubContextList.java b/src/main/java/org/apache/xpath/axes/SubContextList.java
new file mode 100644
index 0000000..e422586
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/SubContextList.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SubContextList.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xpath.XPathContext;
+ 
+/**
+ * A class that implements this interface is a sub context node list, meaning it
+ * is a node list for a location path step for a predicate.
+ * @xsl.usage advanced
+ */
+public interface SubContextList
+{
+
+  /**
+   * Get the number of nodes in the node list, which, in the XSLT 1 based 
+   * counting system, is the last index position.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return the number of nodes in the node list.
+   */
+  public int getLastPos(XPathContext xctxt);
+
+  /**
+   * Get the current sub-context position.
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return The position of the current node in the list.
+   */
+  public int getProximityPosition(XPathContext xctxt);
+}
diff --git a/src/main/java/org/apache/xpath/axes/UnionChildIterator.java b/src/main/java/org/apache/xpath/axes/UnionChildIterator.java
new file mode 100644
index 0000000..19cd4ec
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/UnionChildIterator.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: UnionChildIterator.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.patterns.NodeTest;
+
+/**
+ * This class defines a simplified type of union iterator that only 
+ * tests along the child axes.  If the conditions are right, it is 
+ * much faster than using a UnionPathIterator.
+ */
+public class UnionChildIterator extends ChildTestIterator
+{
+    static final long serialVersionUID = 3500298482193003495L;
+  /**
+   * Even though these may hold full LocPathIterators, this array does 
+   * not have to be cloned, since only the node test and predicate 
+   * portion are used, and these only need static information.  However, 
+   * also note that index predicates can not be used!
+   */
+  private PredicatedNodeTest[] m_nodeTests = null;
+
+  /**
+   * Constructor for UnionChildIterator
+   */
+  public UnionChildIterator()
+  {
+    super(null);
+  }
+
+  /**
+   * Add a node test to the union list.
+   *
+   * @param test reference to a NodeTest, which will be added 
+   * directly to the list of node tests (in other words, it will 
+   * not be cloned).  The parent of this test will be set to 
+   * this object.
+   */
+  public void addNodeTest(PredicatedNodeTest test)
+  {
+
+    // Increase array size by only 1 at a time.  Fix this
+    // if it looks to be a problem.
+    if (null == m_nodeTests)
+    {
+      m_nodeTests = new PredicatedNodeTest[1];
+      m_nodeTests[0] = test;
+    }
+    else
+    {
+      PredicatedNodeTest[] tests = m_nodeTests;
+      int len = m_nodeTests.length;
+
+      m_nodeTests = new PredicatedNodeTest[len + 1];
+
+      System.arraycopy(tests, 0, m_nodeTests, 0, len);
+
+      m_nodeTests[len] = test;
+    }
+    test.exprSetParent(this);
+  }
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    if (m_nodeTests != null) {
+      for (int i = 0; i < m_nodeTests.length; i++) {
+        m_nodeTests[i].fixupVariables(vars, globalsSize);
+      }
+    }
+  }
+
+  /**
+   * Test whether a specified node is visible in the logical view of a
+   * TreeWalker or NodeIterator. This function will be called by the
+   * implementation of TreeWalker and NodeIterator; it is not intended to
+   * be called directly from user code.
+   * @param n  The node to check to see if it passes the filter or not.
+   * @return  a constant to determine whether the node is accepted,
+   *   rejected, or skipped, as defined  above .
+   */
+  public short acceptNode(int n)
+  {
+    XPathContext xctxt = getXPathContext();
+    try
+    {
+      xctxt.pushCurrentNode(n);
+      for (int i = 0; i < m_nodeTests.length; i++)
+      {
+        PredicatedNodeTest pnt = m_nodeTests[i];
+        XObject score = pnt.execute(xctxt, n);
+        if (score != NodeTest.SCORE_NONE)
+        {
+          // Note that we are assuming there are no positional predicates!
+          if (pnt.getPredicateCount() > 0)
+          {
+            if (pnt.executePredicates(n, xctxt))
+              return DTMIterator.FILTER_ACCEPT;
+          }
+          else
+            return DTMIterator.FILTER_ACCEPT;
+
+        }
+      }
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: Fix this.
+      throw new RuntimeException(se.getMessage());
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+    }
+    return DTMIterator.FILTER_SKIP;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/UnionPathIterator.java b/src/main/java/org/apache/xpath/axes/UnionPathIterator.java
new file mode 100644
index 0000000..6d714bb
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/UnionPathIterator.java
@@ -0,0 +1,584 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: UnionPathIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpCodes;
+import org.apache.xpath.compiler.OpMap;
+
+/**
+ * This class extends NodeSetDTM, which implements DTMIterator,
+ * and fetches nodes one at a time in document order based on a XPath
+ * <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
+ * As each node is iterated via nextNode(), the node is also stored
+ * in the NodeVector, so that previousNode() can easily be done.
+ * @xsl.usage advanced
+ */
+public class UnionPathIterator extends LocPathIterator
+        implements Cloneable, DTMIterator, java.io.Serializable, PathComponent
+{
+    static final long serialVersionUID = -3910351546843826781L;
+
+  /**
+   * Constructor to create an instance which you can add location paths to.
+   */
+  public UnionPathIterator()
+  {
+
+    super();
+
+    // m_mutable = false;
+    // m_cacheNodes = false;
+    m_iterators = null;
+    m_exprs = null;
+  }
+
+  /**
+   * Initialize the context values for this expression 
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this 
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+    super.setRoot(context, environment);
+
+    try
+    {
+      if (null != m_exprs)
+      {
+        int n = m_exprs.length;
+        DTMIterator newIters[] = new DTMIterator[n];
+  
+        for (int i = 0; i < n; i++)
+        {
+          DTMIterator iter = m_exprs[i].asIterator(m_execContext, context);
+          newIters[i] = iter;
+          iter.nextNode();
+        }
+        m_iterators = newIters;
+      }
+    }
+    catch(Exception e)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(e);
+    }
+  }
+  
+  /**
+   * Add an iterator to the union list.
+   *
+   * @param expr non-null reference to a location path iterator.
+   */
+  public void addIterator(DTMIterator expr)
+  {
+
+    // Increase array size by only 1 at a time.  Fix this
+    // if it looks to be a problem.
+    if (null == m_iterators)
+    {
+      m_iterators = new DTMIterator[1];
+      m_iterators[0] = expr;
+    }
+    else
+    {
+      DTMIterator[] exprs = m_iterators;
+      int len = m_iterators.length;
+
+      m_iterators = new DTMIterator[len + 1];
+
+      System.arraycopy(exprs, 0, m_iterators, 0, len);
+
+      m_iterators[len] = expr;
+    }
+    expr.nextNode();
+    if(expr instanceof Expression)
+    	((Expression)expr).exprSetParent(this);
+  }
+  
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {
+          if(m_allowDetach && null != m_iterators){         
+                  int n = m_iterators.length;
+                  for(int i = 0; i < n; i++)
+                  {
+                          m_iterators[i].detach();
+                  }
+                  m_iterators = null;                                
+          }
+  }
+
+
+  /**
+   * Create a UnionPathIterator object, including creation 
+   * of location path iterators from the opcode list, and call back 
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating 
+   * this expression.
+   * @param opPos The position of this iterator in the 
+   * opcode list from the compiler.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public UnionPathIterator(Compiler compiler, int opPos)
+          throws javax.xml.transform.TransformerException
+  {
+
+    super();
+
+    opPos = OpMap.getFirstChildPos(opPos);
+
+    loadLocationPaths(compiler, opPos, 0);
+  }
+  
+  /**
+   * This will return an iterator capable of handling the union of paths given.
+   * 
+   * @param compiler The Compiler which is creating 
+   * this expression.
+   * @param opPos The position of this iterator in the 
+   * opcode list from the compiler.
+   * 
+   * @return Object that is derived from LocPathIterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public static LocPathIterator createUnionIterator(Compiler compiler, int opPos)
+          throws javax.xml.transform.TransformerException
+  {
+  	// For the moment, I'm going to first create a full UnionPathIterator, and 
+  	// then see if I can reduce it to a UnionChildIterator.  It would obviously 
+  	// be more effecient to just test for the conditions for a UnionChildIterator, 
+  	// and then create that directly.
+  	UnionPathIterator upi = new UnionPathIterator(compiler, opPos);
+  	int nPaths = upi.m_exprs.length;
+  	boolean isAllChildIterators = true;
+  	for(int i = 0; i < nPaths; i++)
+  	{
+  		LocPathIterator lpi = upi.m_exprs[i];
+  		
+  		if(lpi.getAxis() != Axis.CHILD)
+  		{
+  			isAllChildIterators = false;
+  			break;
+  		}
+  		else
+  		{
+  			// check for positional predicates or position function, which won't work.
+  			if(HasPositionalPredChecker.check(lpi))
+  			{
+  				isAllChildIterators = false;
+  				break;
+  			}
+  		}
+  	}
+  	if(isAllChildIterators)
+  	{
+  		UnionChildIterator uci = new UnionChildIterator();
+  		
+	  	for(int i = 0; i < nPaths; i++)
+	  	{
+	  		PredicatedNodeTest lpi = upi.m_exprs[i];
+	  		// I could strip the lpi down to a pure PredicatedNodeTest, but 
+	  		// I don't think it's worth it.  Note that the test can be used 
+	  		// as a static object... so it doesn't have to be cloned.
+	  		uci.addNodeTest(lpi);
+	  	}
+	  	return uci;
+  		
+  	}
+  	else
+  		return upi;
+  }
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+    int bits = 0;
+    
+    if (m_exprs != null)
+    {
+      int n = m_exprs.length;
+
+      for (int i = 0; i < n; i++)
+      {
+      	int bit = m_exprs[i].getAnalysisBits();
+        bits |= bit;
+      }
+    }
+
+    return bits;
+  }
+  
+  /**
+   * Read the object from a serialization stream.
+   *
+   * @param stream Input stream to read from
+   *
+   * @throws java.io.IOException
+   * @throws javax.xml.transform.TransformerException
+   */
+  private void readObject(java.io.ObjectInputStream stream)
+          throws java.io.IOException, javax.xml.transform.TransformerException
+  {
+    try
+    {
+      stream.defaultReadObject();
+      m_clones =  new IteratorPool(this);
+    }
+    catch (ClassNotFoundException cnfe)
+    {
+      throw new javax.xml.transform.TransformerException(cnfe);
+    }
+  }
+
+  /**
+   * Get a cloned LocPathIterator that holds the same 
+   * position as this iterator.
+   *
+   * @return A clone of this iterator that holds the same node position.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    UnionPathIterator clone = (UnionPathIterator) super.clone();
+    if (m_iterators != null)
+    {
+      int n = m_iterators.length;
+      
+      clone.m_iterators = new DTMIterator[n];
+
+      for (int i = 0; i < n; i++)
+      {
+        clone.m_iterators[i] = (DTMIterator)m_iterators[i].clone();
+      }
+    }
+
+    return clone;
+  }
+  
+  
+  /**
+   * Create a new location path iterator.
+   *
+   * @param compiler The Compiler which is creating 
+   * this expression.
+   * @param opPos The position of this iterator in the 
+   *
+   * @return New location path iterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected LocPathIterator createDTMIterator(
+          Compiler compiler, int opPos) throws javax.xml.transform.TransformerException
+  {
+    LocPathIterator lpi = (LocPathIterator)WalkerFactory.newDTMIterator(compiler, opPos, 
+                                      (compiler.getLocationPathDepth() <= 0));
+    return lpi;
+  }
+
+  /**
+   * Initialize the location path iterators.  Recursive.
+   *
+   * @param compiler The Compiler which is creating 
+   * this expression.
+   * @param opPos The position of this iterator in the 
+   * opcode list from the compiler.
+   * @param count The insert position of the iterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void loadLocationPaths(Compiler compiler, int opPos, int count)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // TODO: Handle unwrapped FilterExpr
+    int steptype = compiler.getOp(opPos);
+
+    if (steptype == OpCodes.OP_LOCATIONPATH)
+    {
+      loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
+
+      m_exprs[count] = createDTMIterator(compiler, opPos);
+      m_exprs[count].exprSetParent(this);
+    }
+    else
+    {
+
+      // Have to check for unwrapped functions, which the LocPathIterator
+      // doesn't handle. 
+      switch (steptype)
+      {
+      case OpCodes.OP_VARIABLE :
+      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_FUNCTION :
+      case OpCodes.OP_GROUP :
+        loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
+
+        WalkingIterator iter =
+          new WalkingIterator(compiler.getNamespaceContext());
+        iter.exprSetParent(this);
+          
+        if(compiler.getLocationPathDepth() <= 0)
+          iter.setIsTopLevel(true);
+
+        iter.m_firstWalker = new org.apache.xpath.axes.FilterExprWalker(iter);
+
+        iter.m_firstWalker.init(compiler, opPos, steptype);
+
+        m_exprs[count] = iter;
+        break;
+      default :
+        m_exprs = new LocPathIterator[count];
+      }
+    }
+  }
+
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a DTMIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {
+  	if(m_foundLast)
+  		return DTM.NULL;
+
+    // Loop through the iterators getting the current fetched 
+    // node, and get the earliest occuring in document order
+    int earliestNode = DTM.NULL;
+
+    if (null != m_iterators)
+    {
+      int n = m_iterators.length;
+      int iteratorUsed = -1;
+
+      for (int i = 0; i < n; i++)
+      {
+        int node = m_iterators[i].getCurrentNode();
+
+        if (DTM.NULL == node)
+          continue;
+        else if (DTM.NULL == earliestNode)
+        {
+          iteratorUsed = i;
+          earliestNode = node;
+        }
+        else
+        {
+          if (node == earliestNode)
+          {
+
+            // Found a duplicate, so skip past it.
+            m_iterators[i].nextNode();
+          }
+          else
+          {
+            DTM dtm = getDTM(node);
+
+            if (dtm.isNodeAfter(node, earliestNode))
+            {
+              iteratorUsed = i;
+              earliestNode = node;
+            }
+          }
+        }
+      }
+
+      if (DTM.NULL != earliestNode)
+      {
+        m_iterators[iteratorUsed].nextNode();
+
+        incrementCurrentPos();
+      }
+      else
+        m_foundLast = true;
+    }
+
+    m_lastFetched = earliestNode;
+
+    return earliestNode;
+  }
+            
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    for (int i = 0; i < m_exprs.length; i++) 
+    {
+      m_exprs[i].fixupVariables(vars, globalsSize);
+    }
+    
+  }
+  
+  /**
+   * The location path iterators, one for each
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location
+   * path</a> contained in the union expression.
+   * @serial
+   */
+  protected LocPathIterator[] m_exprs;
+
+    
+  /**
+   * The location path iterators, one for each
+   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location
+   * path</a> contained in the union expression.
+   * @serial
+   */
+  protected DTMIterator[] m_iterators;
+      
+  /**
+   * Returns the axis being iterated, if it is known.
+   * 
+   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
+   * types.
+   */
+  public int getAxis()
+  {
+    // Could be smarter.
+    return -1;
+  }
+  
+  class iterOwner implements ExpressionOwner
+  {
+  	int m_index;
+  	
+  	iterOwner(int index)
+  	{
+  		m_index = index;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_exprs[m_index];
+    }
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	
+    	if(!(exp instanceof LocPathIterator))
+    	{
+    		// Yuck.  Need FilterExprIter.  Or make it so m_exprs can be just 
+    		// plain expressions?
+    		WalkingIterator wi = new WalkingIterator(getPrefixResolver());
+    		FilterExprWalker few = new FilterExprWalker(wi);
+    		wi.setFirstWalker(few);
+    		few.setInnerExpression(exp);
+    		wi.exprSetParent(UnionPathIterator.this);
+    		few.exprSetParent(wi);
+    		exp.exprSetParent(few);
+    		exp = wi;
+    	}
+    	else
+    		exp.exprSetParent(UnionPathIterator.this);
+    	m_exprs[m_index] = (LocPathIterator)exp;
+    }
+
+  }
+
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	 	if(visitor.visitUnionPath(owner, this))
+  	 	{
+  	 		if(null != m_exprs)
+  	 		{
+  	 			int n = m_exprs.length;
+  	 			for(int i = 0; i < n; i++)
+  	 			{
+  	 				m_exprs[i].callVisitors(new iterOwner(i), visitor);
+  	 			}
+  	 		}
+  	 	}
+  }
+  
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+            return false;
+
+      UnionPathIterator upi = (UnionPathIterator) expr;
+
+      if (null != m_exprs)
+      {
+        int n = m_exprs.length;
+        
+        if((null == upi.m_exprs) || (upi.m_exprs.length != n))
+        	return false;
+        
+        for (int i = 0; i < n; i++)
+        {
+          if(!m_exprs[i].deepEquals(upi.m_exprs[i]))
+          	return false;
+        }
+      }
+      else if (null != upi.m_exprs)
+      {
+          return false;
+      }
+
+      return true;
+    }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/WalkerFactory.java b/src/main/java/org/apache/xpath/axes/WalkerFactory.java
new file mode 100644
index 0000000..363fab1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/WalkerFactory.java
@@ -0,0 +1,1825 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WalkerFactory.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.FunctionTable;
+import org.apache.xpath.compiler.OpCodes;
+import org.apache.xpath.compiler.OpMap;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.patterns.ContextMatchStepPattern;
+import org.apache.xpath.patterns.FunctionPattern;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.patterns.StepPattern;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class is both a factory for XPath location path expressions,
+ * which are built from the opcode map output, and an analysis engine
+ * for the location path expressions in order to provide optimization hints.
+ */
+public class WalkerFactory
+{
+
+  /**
+   * This method is for building an array of possible levels
+   * where the target element(s) could be found for a match.
+   * @param lpi The owning location path iterator.
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   *
+   * @return non-null AxesWalker derivative.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage advanced
+   */
+  static AxesWalker loadOneWalker(
+          WalkingIterator lpi, Compiler compiler, int stepOpCodePos)
+            throws javax.xml.transform.TransformerException
+  {
+
+    AxesWalker firstWalker = null;
+    int stepType = compiler.getOp(stepOpCodePos);
+
+    if (stepType != OpCodes.ENDOP)
+    {
+
+      // m_axesWalkers = new AxesWalker[1];
+      // As we unwind from the recursion, create the iterators.
+      firstWalker = createDefaultWalker(compiler, stepType, lpi, 0);
+
+      firstWalker.init(compiler, stepOpCodePos, stepType);
+    }
+
+    return firstWalker;
+  }
+
+  /**
+   * This method is for building an array of possible levels
+   * where the target element(s) could be found for a match.
+   * @param lpi The owning location path iterator object.
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   * @param stepIndex The top-level step index withing the iterator.
+   *
+   * @return non-null AxesWalker derivative.
+   *
+   * @throws javax.xml.transform.TransformerException
+   * @xsl.usage advanced
+   */
+  static AxesWalker loadWalkers(
+          WalkingIterator lpi, Compiler compiler, int stepOpCodePos, int stepIndex)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int stepType;
+    AxesWalker firstWalker = null;
+    AxesWalker walker, prevWalker = null;
+
+    int analysis = analyze(compiler, stepOpCodePos, stepIndex);
+
+    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
+    {
+      walker = createDefaultWalker(compiler, stepOpCodePos, lpi, analysis);
+
+      walker.init(compiler, stepOpCodePos, stepType);
+      walker.exprSetParent(lpi);
+
+      // walker.setAnalysis(analysis);
+      if (null == firstWalker)
+      {
+        firstWalker = walker;
+      }
+      else
+      {
+        prevWalker.setNextWalker(walker);
+        walker.setPrevWalker(prevWalker);
+      }
+
+      prevWalker = walker;
+      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
+
+      if (stepOpCodePos < 0)
+        break;
+    }
+
+    return firstWalker;
+  }
+  
+  public static boolean isSet(int analysis, int bits)
+  {
+    return (0 != (analysis & bits));
+  }
+  
+  public static void diagnoseIterator(String name, int analysis, Compiler compiler)
+  {
+    System.out.println(compiler.toString()+", "+name+", "
+                             + Integer.toBinaryString(analysis) + ", "
+                             + getAnalysisString(analysis));
+  }
+
+  /**
+   * Create a new LocPathIterator iterator.  The exact type of iterator
+   * returned is based on an analysis of the XPath operations.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param opPos The position of the operation code for this itterator.
+   *
+   * @return non-null reference to a LocPathIterator or derivative.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public static DTMIterator newDTMIterator(
+          Compiler compiler, int opPos,
+          boolean isTopLevel)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+    int analysis = analyze(compiler, firstStepPos, 0);
+    boolean isOneStep = isOneStep(analysis);
+    DTMIterator iter;
+
+    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
+    if (isOneStep && walksSelfOnly(analysis) && 
+        isWild(analysis) && !hasPredicate(analysis))
+    {
+      if (DEBUG_ITERATOR_CREATION)
+        diagnoseIterator("SelfIteratorNoPredicate", analysis, compiler);
+
+      // Then use a simple iteration of the attributes, with node test 
+      // and predicate testing.
+      iter = new SelfIteratorNoPredicate(compiler, opPos, analysis);
+    }
+    // Is the iteration exactly one child step?
+    else if (walksChildrenOnly(analysis) && isOneStep)
+    {
+
+      // Does the pattern specify *any* child with no predicate? (i.e. select="child::node()".
+      if (isWild(analysis) && !hasPredicate(analysis))
+      {
+        if (DEBUG_ITERATOR_CREATION)
+          diagnoseIterator("ChildIterator", analysis, compiler);
+
+        // Use simple child iteration without any test.
+        iter = new ChildIterator(compiler, opPos, analysis);
+      }
+      else
+      {
+        if (DEBUG_ITERATOR_CREATION)
+          diagnoseIterator("ChildTestIterator", analysis, compiler);
+
+        // Else use simple node test iteration with predicate test.
+        iter = new ChildTestIterator(compiler, opPos, analysis);
+      }
+    }
+    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
+    else if (isOneStep && walksAttributes(analysis))
+    {
+      if (DEBUG_ITERATOR_CREATION)
+        diagnoseIterator("AttributeIterator", analysis, compiler);
+
+      // Then use a simple iteration of the attributes, with node test 
+      // and predicate testing.
+      iter = new AttributeIterator(compiler, opPos, analysis);
+    }
+    else if(isOneStep && !walksFilteredList(analysis))
+    {
+      if( !walksNamespaces(analysis) 
+      && (walksInDocOrder(analysis) || isSet(analysis, BIT_PARENT)))
+      {
+        if (false || DEBUG_ITERATOR_CREATION)
+          diagnoseIterator("OneStepIteratorForward", analysis, compiler);
+  
+        // Then use a simple iteration of the attributes, with node test 
+        // and predicate testing.
+        iter = new OneStepIteratorForward(compiler, opPos, analysis);
+      }
+      else
+      {
+        if (false || DEBUG_ITERATOR_CREATION)
+          diagnoseIterator("OneStepIterator", analysis, compiler);
+  
+        // Then use a simple iteration of the attributes, with node test 
+        // and predicate testing.
+        iter = new OneStepIterator(compiler, opPos, analysis);
+      }
+    }
+
+    // Analysis of "//center":
+    // bits: 1001000000001010000000000000011
+    // count: 3
+    // root
+    // child:node()
+    // BIT_DESCENDANT_OR_SELF
+    // It's highly possible that we should have a seperate bit set for 
+    // "//foo" patterns.
+    // For at least the time being, we can't optimize patterns like 
+    // "//table[3]", because this has to be analyzed as 
+    // "/descendant-or-self::node()/table[3]" in order for the indexes 
+    // to work right.
+    else if (isOptimizableForDescendantIterator(compiler, firstStepPos, 0)
+              // && getStepCount(analysis) <= 3 
+              // && walksDescendants(analysis) 
+              // && walksSubtreeOnlyFromRootOrContext(analysis)
+             )
+    {
+      if (DEBUG_ITERATOR_CREATION)
+        diagnoseIterator("DescendantIterator", analysis, compiler);
+
+      iter = new DescendantIterator(compiler, opPos, analysis);
+    }
+    else
+    { 
+      if(isNaturalDocOrder(compiler, firstStepPos, 0, analysis))
+      {
+        if (false || DEBUG_ITERATOR_CREATION)
+        {
+          diagnoseIterator("WalkingIterator", analysis, compiler);
+        }
+  
+        iter = new WalkingIterator(compiler, opPos, analysis, true);
+      }
+      else
+      {
+//        if (DEBUG_ITERATOR_CREATION)
+//          diagnoseIterator("MatchPatternIterator", analysis, compiler);
+//
+//        return new MatchPatternIterator(compiler, opPos, analysis);
+        if (DEBUG_ITERATOR_CREATION)
+          diagnoseIterator("WalkingIteratorSorted", analysis, compiler);
+
+        iter = new WalkingIteratorSorted(compiler, opPos, analysis, true);
+      }
+    }
+    if(iter instanceof LocPathIterator)
+      ((LocPathIterator)iter).setIsTopLevel(isTopLevel);
+      
+    return iter;
+  }
+  
+  /**
+   * Special purpose function to see if we can optimize the pattern for 
+   * a DescendantIterator.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   *
+   * @return 32 bits as an integer that give information about the location
+   * path as a whole.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public static int getAxisFromStep(
+          Compiler compiler, int stepOpCodePos)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int stepType = compiler.getOp(stepOpCodePos);
+
+    switch (stepType)
+    {
+    case OpCodes.FROM_FOLLOWING :
+      return Axis.FOLLOWING;
+    case OpCodes.FROM_FOLLOWING_SIBLINGS :
+      return Axis.FOLLOWINGSIBLING;
+    case OpCodes.FROM_PRECEDING :
+      return Axis.PRECEDING;
+    case OpCodes.FROM_PRECEDING_SIBLINGS :
+      return Axis.PRECEDINGSIBLING;
+    case OpCodes.FROM_PARENT :
+      return Axis.PARENT;
+    case OpCodes.FROM_NAMESPACE :
+      return Axis.NAMESPACE;
+    case OpCodes.FROM_ANCESTORS :
+      return Axis.ANCESTOR;
+    case OpCodes.FROM_ANCESTORS_OR_SELF :
+      return Axis.ANCESTORORSELF;
+    case OpCodes.FROM_ATTRIBUTES :
+      return Axis.ATTRIBUTE;
+    case OpCodes.FROM_ROOT :
+      return Axis.ROOT;
+    case OpCodes.FROM_CHILDREN :
+      return Axis.CHILD;
+    case OpCodes.FROM_DESCENDANTS_OR_SELF :
+      return Axis.DESCENDANTORSELF;
+    case OpCodes.FROM_DESCENDANTS :
+      return Axis.DESCENDANT;
+    case OpCodes.FROM_SELF :
+      return Axis.SELF;
+    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_GROUP :
+    case OpCodes.OP_VARIABLE :
+      return Axis.FILTEREDLIST;
+    }
+
+    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                               //+ stepType);
+   }
+    
+    /**
+     * Get a corresponding BIT_XXX from an axis.
+     * @param axis One of Axis.ANCESTOR, etc.
+     * @return One of BIT_ANCESTOR, etc.
+     */
+    static public int getAnalysisBitFromAxes(int axis)
+    {
+      switch (axis) // Generate new traverser
+        {
+        case Axis.ANCESTOR :
+          return BIT_ANCESTOR;
+        case Axis.ANCESTORORSELF :
+          return BIT_ANCESTOR_OR_SELF;
+        case Axis.ATTRIBUTE :
+          return BIT_ATTRIBUTE;
+        case Axis.CHILD :
+          return BIT_CHILD;
+        case Axis.DESCENDANT :
+          return BIT_DESCENDANT;
+        case Axis.DESCENDANTORSELF :
+          return BIT_DESCENDANT_OR_SELF;
+        case Axis.FOLLOWING :
+          return BIT_FOLLOWING;
+        case Axis.FOLLOWINGSIBLING :
+          return BIT_FOLLOWING_SIBLING;
+        case Axis.NAMESPACE :
+        case Axis.NAMESPACEDECLS :
+          return BIT_NAMESPACE;
+        case Axis.PARENT :
+          return BIT_PARENT;
+        case Axis.PRECEDING :
+          return BIT_PRECEDING;
+        case Axis.PRECEDINGSIBLING :
+          return BIT_PRECEDING_SIBLING;
+        case Axis.SELF :
+          return BIT_SELF;
+        case Axis.ALLFROMNODE :
+          return BIT_DESCENDANT_OR_SELF;
+          // case Axis.PRECEDINGANDANCESTOR :
+        case Axis.DESCENDANTSFROMROOT :
+        case Axis.ALL :
+        case Axis.DESCENDANTSORSELFFROMROOT :
+          return BIT_ANY_DESCENDANT_FROM_ROOT;
+        case Axis.ROOT :
+          return BIT_ROOT;
+        case Axis.FILTEREDLIST :
+          return BIT_FILTER;
+        default :
+          return BIT_FILTER;
+      }
+    }
+  
+  static boolean functionProximateOrContainsProximate(Compiler compiler, 
+                                                      int opPos)
+  {
+    int endFunc = opPos + compiler.getOp(opPos + 1) - 1;
+    opPos = OpMap.getFirstChildPos(opPos);
+    int funcID = compiler.getOp(opPos);
+    //  System.out.println("funcID: "+funcID);
+    //  System.out.println("opPos: "+opPos);
+    //  System.out.println("endFunc: "+endFunc);
+    switch(funcID)
+    {
+      case FunctionTable.FUNC_LAST:
+      case FunctionTable.FUNC_POSITION:
+        return true;
+      default:
+        opPos++;
+        int i = 0;
+        for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++)
+        {
+          int innerExprOpPos = p+2;
+          int argOp = compiler.getOp(innerExprOpPos);
+          boolean prox = isProximateInnerExpr(compiler, innerExprOpPos);
+          if(prox)
+            return true;
+        }
+
+    }
+    return false;
+  }
+  
+  static boolean isProximateInnerExpr(Compiler compiler, int opPos)
+  {
+    int op = compiler.getOp(opPos);
+    int innerExprOpPos = opPos+2;
+    switch(op)
+    {
+      case OpCodes.OP_ARGUMENT:
+        if(isProximateInnerExpr(compiler, innerExprOpPos))
+          return true;
+        break;
+      case OpCodes.OP_VARIABLE:
+      case OpCodes.OP_NUMBERLIT:
+      case OpCodes.OP_LITERAL:
+      case OpCodes.OP_LOCATIONPATH:
+        break; // OK
+      case OpCodes.OP_FUNCTION:
+        boolean isProx = functionProximateOrContainsProximate(compiler, opPos);
+        if(isProx)
+          return true;
+        break;
+      case OpCodes.OP_GT:
+      case OpCodes.OP_GTE:
+      case OpCodes.OP_LT:
+      case OpCodes.OP_LTE:
+      case OpCodes.OP_EQUALS:
+        int leftPos = OpMap.getFirstChildPos(op);
+        int rightPos = compiler.getNextOpPos(leftPos);
+        isProx = isProximateInnerExpr(compiler, leftPos);
+        if(isProx)
+          return true;
+        isProx = isProximateInnerExpr(compiler, rightPos);
+        if(isProx)
+          return true;
+        break;
+      default:
+        return true; // be conservative...
+    }
+    return false;
+  }
+    
+  /**
+   * Tell if the predicates need to have proximity knowledge.
+   */
+  public static boolean mightBeProximate(Compiler compiler, int opPos, int stepType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    boolean mightBeProximate = false;
+    int argLen;
+
+    switch (stepType)
+    {
+    case OpCodes.OP_VARIABLE :
+    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_GROUP :
+      argLen = compiler.getArgLength(opPos);
+      break;
+    default :
+      argLen = compiler.getArgLengthOfStep(opPos);
+    }
+
+    int predPos = compiler.getFirstPredicateOpPos(opPos);
+    int count = 0;
+
+    while (OpCodes.OP_PREDICATE == compiler.getOp(predPos))
+    {
+      count++;
+      
+      int innerExprOpPos = predPos+2;
+      int predOp = compiler.getOp(innerExprOpPos);
+
+      switch(predOp)
+      {
+        case OpCodes.OP_VARIABLE:
+        	return true; // Would need more smarts to tell if this could be a number or not!
+        case OpCodes.OP_LOCATIONPATH:
+          // OK.
+          break;
+        case OpCodes.OP_NUMBER:
+        case OpCodes.OP_NUMBERLIT:
+          return true; // that's all she wrote!
+        case OpCodes.OP_FUNCTION:
+          boolean isProx 
+            = functionProximateOrContainsProximate(compiler, innerExprOpPos);
+          if(isProx)
+            return true;
+          break;
+        case OpCodes.OP_GT:
+        case OpCodes.OP_GTE:
+        case OpCodes.OP_LT:
+        case OpCodes.OP_LTE:
+        case OpCodes.OP_EQUALS:
+          int leftPos = OpMap.getFirstChildPos(innerExprOpPos);
+          int rightPos = compiler.getNextOpPos(leftPos);
+          isProx = isProximateInnerExpr(compiler, leftPos);
+          if(isProx)
+            return true;
+          isProx = isProximateInnerExpr(compiler, rightPos);
+          if(isProx)
+            return true;
+          break;
+        default:
+          return true; // be conservative...
+      }
+
+      predPos = compiler.getNextOpPos(predPos);
+    }
+
+    return mightBeProximate;
+  }
+  
+  /**
+   * Special purpose function to see if we can optimize the pattern for 
+   * a DescendantIterator.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   * @param stepIndex The top-level step index withing the iterator.
+   *
+   * @return 32 bits as an integer that give information about the location
+   * path as a whole.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private static boolean isOptimizableForDescendantIterator(
+          Compiler compiler, int stepOpCodePos, int stepIndex)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int stepType;
+    int stepCount = 0;
+    boolean foundDorDS = false;
+    boolean foundSelf = false;
+    boolean foundDS = false;
+    
+    int nodeTestType = OpCodes.NODETYPE_NODE;
+    
+    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
+    {
+      // The DescendantIterator can only do one node test.  If there's more 
+      // than one, use another iterator.
+      if(nodeTestType != OpCodes.NODETYPE_NODE && nodeTestType != OpCodes.NODETYPE_ROOT)
+        return false;
+        
+      stepCount++;
+      if(stepCount > 3)
+        return false;
+        
+      boolean mightBeProximate = mightBeProximate(compiler, stepOpCodePos, stepType);
+      if(mightBeProximate)
+        return false;
+
+      switch (stepType)
+      {
+      case OpCodes.FROM_FOLLOWING :
+      case OpCodes.FROM_FOLLOWING_SIBLINGS :
+      case OpCodes.FROM_PRECEDING :
+      case OpCodes.FROM_PRECEDING_SIBLINGS :
+      case OpCodes.FROM_PARENT :
+      case OpCodes.OP_VARIABLE :
+      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_FUNCTION :
+      case OpCodes.OP_GROUP :
+      case OpCodes.FROM_NAMESPACE :
+      case OpCodes.FROM_ANCESTORS :
+      case OpCodes.FROM_ANCESTORS_OR_SELF :
+      case OpCodes.FROM_ATTRIBUTES :
+      case OpCodes.MATCH_ATTRIBUTE :
+      case OpCodes.MATCH_ANY_ANCESTOR :
+      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+        return false;
+      case OpCodes.FROM_ROOT :
+        if(1 != stepCount)
+          return false;
+        break;
+      case OpCodes.FROM_CHILDREN :
+        if(!foundDS && !(foundDorDS && foundSelf))
+          return false;
+        break;
+      case OpCodes.FROM_DESCENDANTS_OR_SELF :
+        foundDS = true;
+      case OpCodes.FROM_DESCENDANTS :
+        if(3 == stepCount)
+          return false;
+        foundDorDS = true;
+        break;
+      case OpCodes.FROM_SELF :
+        if(1 != stepCount)
+          return false;
+        foundSelf = true;
+        break;
+      default :
+        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                                  // + stepType);
+      }
+      
+      nodeTestType = compiler.getStepTestType(stepOpCodePos);
+
+      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
+
+      if (nextStepOpCodePos < 0)
+        break;
+        
+      if(OpCodes.ENDOP != compiler.getOp(nextStepOpCodePos))
+      {
+        if(compiler.countPredicates(stepOpCodePos) > 0)
+        {
+          return false;
+        }
+      }
+      
+      stepOpCodePos = nextStepOpCodePos;
+    }
+
+    return true;
+  }
+
+  /**
+   * Analyze the location path and return 32 bits that give information about
+   * the location path as a whole.  See the BIT_XXX constants for meaning about
+   * each of the bits.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   * @param stepIndex The top-level step index withing the iterator.
+   *
+   * @return 32 bits as an integer that give information about the location
+   * path as a whole.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private static int analyze(
+          Compiler compiler, int stepOpCodePos, int stepIndex)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int stepType;
+    int stepCount = 0;
+    int analysisResult = 0x00000000;  // 32 bits of analysis
+
+    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
+    {
+      stepCount++;
+
+      // String namespace = compiler.getStepNS(stepOpCodePos);
+      // boolean isNSWild = (null != namespace) 
+      //                   ? namespace.equals(NodeTest.WILD) : false;
+      // String localname = compiler.getStepLocalName(stepOpCodePos);
+      // boolean isWild = (null != localname) ? localname.equals(NodeTest.WILD) : false;
+      boolean predAnalysis = analyzePredicate(compiler, stepOpCodePos,
+                                              stepType);
+
+      if (predAnalysis)
+        analysisResult |= BIT_PREDICATE;
+
+      switch (stepType)
+      {
+      case OpCodes.OP_VARIABLE :
+      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_FUNCTION :
+      case OpCodes.OP_GROUP :
+        analysisResult |= BIT_FILTER;
+        break;
+      case OpCodes.FROM_ROOT :
+        analysisResult |= BIT_ROOT;
+        break;
+      case OpCodes.FROM_ANCESTORS :
+        analysisResult |= BIT_ANCESTOR;
+        break;
+      case OpCodes.FROM_ANCESTORS_OR_SELF :
+        analysisResult |= BIT_ANCESTOR_OR_SELF;
+        break;
+      case OpCodes.FROM_ATTRIBUTES :
+        analysisResult |= BIT_ATTRIBUTE;
+        break;
+      case OpCodes.FROM_NAMESPACE :
+        analysisResult |= BIT_NAMESPACE;
+        break;
+      case OpCodes.FROM_CHILDREN :
+        analysisResult |= BIT_CHILD;
+        break;
+      case OpCodes.FROM_DESCENDANTS :
+        analysisResult |= BIT_DESCENDANT;
+        break;
+      case OpCodes.FROM_DESCENDANTS_OR_SELF :
+
+        // Use a special bit to to make sure we get the right analysis of "//foo".
+        if (2 == stepCount && BIT_ROOT == analysisResult)
+        {
+          analysisResult |= BIT_ANY_DESCENDANT_FROM_ROOT;
+        }
+
+        analysisResult |= BIT_DESCENDANT_OR_SELF;
+        break;
+      case OpCodes.FROM_FOLLOWING :
+        analysisResult |= BIT_FOLLOWING;
+        break;
+      case OpCodes.FROM_FOLLOWING_SIBLINGS :
+        analysisResult |= BIT_FOLLOWING_SIBLING;
+        break;
+      case OpCodes.FROM_PRECEDING :
+        analysisResult |= BIT_PRECEDING;
+        break;
+      case OpCodes.FROM_PRECEDING_SIBLINGS :
+        analysisResult |= BIT_PRECEDING_SIBLING;
+        break;
+      case OpCodes.FROM_PARENT :
+        analysisResult |= BIT_PARENT;
+        break;
+      case OpCodes.FROM_SELF :
+        analysisResult |= BIT_SELF;
+        break;
+      case OpCodes.MATCH_ATTRIBUTE :
+        analysisResult |= (BIT_MATCH_PATTERN | BIT_ATTRIBUTE);
+        break;
+      case OpCodes.MATCH_ANY_ANCESTOR :
+        analysisResult |= (BIT_MATCH_PATTERN | BIT_ANCESTOR);
+        break;
+      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+        analysisResult |= (BIT_MATCH_PATTERN | BIT_PARENT);
+        break;
+      default :
+        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                                   //+ stepType);
+      }
+
+      if (OpCodes.NODETYPE_NODE == compiler.getOp(stepOpCodePos + 3))  // child::node()
+      {
+        analysisResult |= BIT_NODETEST_ANY;
+      }
+
+      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
+
+      if (stepOpCodePos < 0)
+        break;
+    }
+
+    analysisResult |= (stepCount & BITS_COUNT);
+
+    return analysisResult;
+  }
+  
+  /**
+   * Tell if the given axis goes downword.  Bogus name, if you can think of 
+   * a better one, please do tell.  This really has to do with inverting 
+   * attribute axis.
+   * @param axis One of Axis.XXX.
+   * @return true if the axis is not a child axis and does not go up from 
+   * the axis root.
+   */
+  public static boolean isDownwardAxisOfMany(int axis)
+  {
+    return ((Axis.DESCENDANTORSELF == axis) ||
+          (Axis.DESCENDANT == axis) 
+          || (Axis.FOLLOWING == axis) 
+//          || (Axis.FOLLOWINGSIBLING == axis) 
+          || (Axis.PRECEDING == axis) 
+//          || (Axis.PRECEDINGSIBLING == axis)
+          );
+  }
+
+  /**
+   * Read a <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a>
+   * as a generalized match pattern.  What this means is that the LocationPath
+   * is read backwards, as a test on a given node, to see if it matches the
+   * criteria of the selection, and ends up at the context node.  Essentially,
+   * this is a backwards query from a given node, to find the context node.
+   * <p>So, the selection "foo/daz[2]" is, in non-abreviated expanded syntax,
+   * "self::node()/following-sibling::foo/child::daz[position()=2]".
+   * Taking this as a match pattern for a probable node, it works out to
+   * "self::daz/parent::foo[child::daz[position()=2 and isPrevStepNode()]
+   * precedingSibling::node()[isContextNodeOfLocationPath()]", adding magic
+   * isPrevStepNode and isContextNodeOfLocationPath operations.  Predicates in
+   * the location path have to be executed by the following step,
+   * because they have to know the context of their execution.
+   *
+   * @param mpi The MatchPatternIterator to which the steps will be attached.
+   * @param compiler The compiler that holds the syntax tree/op map to
+   * construct from.
+   * @param stepOpCodePos The current op code position within the opmap.
+   * @param stepIndex The top-level step index withing the iterator.
+   *
+   * @return A StepPattern object, which may contain relative StepPatterns.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  static StepPattern loadSteps(
+          MatchPatternIterator mpi, Compiler compiler, int stepOpCodePos, 
+                                                       int stepIndex)
+            throws javax.xml.transform.TransformerException
+  {
+    if (DEBUG_PATTERN_CREATION)
+    {
+      System.out.println("================");
+      System.out.println("loadSteps for: "+compiler.getPatternString());
+    }
+    int stepType;
+    StepPattern step = null;
+    StepPattern firstStep = null, prevStep = null;
+    int analysis = analyze(compiler, stepOpCodePos, stepIndex);
+
+    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
+    {
+      step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis,
+                                      firstStep, prevStep);
+
+      if (null == firstStep)
+      {
+        firstStep = step;
+      }
+      else
+      {
+
+        //prevStep.setNextWalker(step);
+        step.setRelativePathPattern(prevStep);
+      }
+
+      prevStep = step;
+      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
+
+      if (stepOpCodePos < 0)
+        break;
+    }
+    
+    int axis = Axis.SELF;
+    int paxis = Axis.SELF;
+    StepPattern tail = step;
+    for (StepPattern pat = step; null != pat; 
+         pat = pat.getRelativePathPattern()) 
+    {
+      int nextAxis = pat.getAxis();
+      //int nextPaxis = pat.getPredicateAxis();
+      pat.setAxis(axis);
+      
+      // The predicate axis can't be moved!!!  Test Axes103
+      // pat.setPredicateAxis(paxis);
+      
+      // If we have an attribute or namespace axis that went up, then 
+      // it won't find the attribute in the inverse, since the select-to-match
+      // axes are not invertable (an element is a parent of an attribute, but 
+      // and attribute is not a child of an element).
+      // If we don't do the magic below, then "@*/ancestor-or-self::*" gets
+      // inverted for match to "self::*/descendant-or-self::@*/parent::node()",
+      // which obviously won't work.
+      // So we will rewrite this as:
+      // "self::*/descendant-or-self::*/attribute::*/parent::node()"
+      // Child has to be rewritten a little differently:
+      // select: "@*/parent::*"
+      // inverted match: "self::*/child::@*/parent::node()"
+      // rewrite: "self::*/attribute::*/parent::node()"
+      // Axes that go down in the select, do not have to have special treatment 
+      // in the rewrite. The following inverted match will still not select 
+      // anything.
+      // select: "@*/child::*"
+      // inverted match: "self::*/parent::@*/parent::node()"
+      // Lovely business, this.
+      // -sb
+      int whatToShow = pat.getWhatToShow();
+      if(whatToShow == DTMFilter.SHOW_ATTRIBUTE || 
+         whatToShow == DTMFilter.SHOW_NAMESPACE)
+      {
+        int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ? 
+                       Axis.ATTRIBUTE : Axis.NAMESPACE;
+        if(isDownwardAxisOfMany(axis))
+        {
+          StepPattern attrPat = new StepPattern(whatToShow, 
+                                    pat.getNamespace(),
+                                    pat.getLocalName(),
+                                //newAxis, pat.getPredicateAxis);
+                                                newAxis, 0); // don't care about the predicate axis
+          XNumber score = pat.getStaticScore();
+          pat.setNamespace(null);
+          pat.setLocalName(NodeTest.WILD);
+          attrPat.setPredicates(pat.getPredicates());
+          pat.setPredicates(null);
+          pat.setWhatToShow(DTMFilter.SHOW_ELEMENT);
+          StepPattern rel = pat.getRelativePathPattern();
+          pat.setRelativePathPattern(attrPat);
+          attrPat.setRelativePathPattern(rel);
+          attrPat.setStaticScore(score);
+          
+          // This is needed to inverse a following pattern, because of the 
+          // wacky Xalan rules for following from an attribute.  See axes108.
+          // By these rules, following from an attribute is not strictly 
+          // inverseable.
+          if(Axis.PRECEDING == pat.getAxis())
+            pat.setAxis(Axis.PRECEDINGANDANCESTOR);
+            
+          else if(Axis.DESCENDANT == pat.getAxis())
+            pat.setAxis(Axis.DESCENDANTORSELF);
+          
+          pat = attrPat;
+        }
+        else if(Axis.CHILD == pat.getAxis())
+        {
+          // In this case just change the axis.
+          // pat.setWhatToShow(whatToShow);
+          pat.setAxis(Axis.ATTRIBUTE);
+        }
+      }
+      axis = nextAxis;
+      //paxis = nextPaxis;
+      tail = pat;
+    }
+    
+    if(axis < Axis.ALL)
+    {
+      StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis);
+      // We need to keep the new nodetest from affecting the score...
+      XNumber score = tail.getStaticScore();
+      tail.setRelativePathPattern(selfPattern);
+      tail.setStaticScore(score);
+      selfPattern.setStaticScore(score);
+    }        
+
+    if (DEBUG_PATTERN_CREATION)
+    {
+      System.out.println("Done loading steps: "+step.toString());
+            
+      System.out.println("");
+    }
+    return step;  // start from last pattern?? //firstStep;
+  }
+
+  /**
+   * Create a StepPattern that is contained within a LocationPath.
+   *
+   *
+   * @param compiler The compiler that holds the syntax tree/op map to
+   * construct from.
+   * @param stepOpCodePos The current op code position within the opmap.
+   * @param mpi The MatchPatternIterator to which the steps will be attached.
+   * @param analysis 32 bits of analysis, from which the type of AxesWalker
+   *                 may be influenced.
+   * @param tail The step that is the first step analyzed, but the last 
+   *                  step in the relative match linked list, i.e. the tail.
+   *                  May be null.
+   * @param head The step that is the current head of the relative 
+   *                 match step linked list.
+   *                 May be null.
+   *
+   * @return the head of the list.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private static StepPattern createDefaultStepPattern(
+          Compiler compiler, int opPos, MatchPatternIterator mpi, 
+          int analysis, StepPattern tail, StepPattern head)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int stepType = compiler.getOp(opPos);
+    boolean simpleInit = false;
+    boolean prevIsOneStepDown = true;
+    
+    int whatToShow = compiler.getWhatToShow(opPos);
+    StepPattern ai = null;
+    int axis, predicateAxis;
+    
+    switch (stepType)
+    {
+    case OpCodes.OP_VARIABLE :
+    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_GROUP :
+      prevIsOneStepDown = false;
+
+      Expression expr;
+
+      switch (stepType)
+      {
+      case OpCodes.OP_VARIABLE :
+      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_FUNCTION :
+      case OpCodes.OP_GROUP :
+        expr = compiler.compile(opPos);
+        break;
+      default :
+        expr = compiler.compile(opPos + 2);
+      }
+
+      axis = Axis.FILTEREDLIST;
+      predicateAxis = Axis.FILTEREDLIST;
+      ai = new FunctionPattern(expr, axis, predicateAxis);
+      simpleInit = true;
+      break;
+    case OpCodes.FROM_ROOT :
+      whatToShow = DTMFilter.SHOW_DOCUMENT
+                   | DTMFilter.SHOW_DOCUMENT_FRAGMENT;
+
+      axis = Axis.ROOT;
+      predicateAxis = Axis.ROOT;
+      ai = new StepPattern(DTMFilter.SHOW_DOCUMENT | 
+                                DTMFilter.SHOW_DOCUMENT_FRAGMENT,
+                                axis, predicateAxis);
+      break;
+    case OpCodes.FROM_ATTRIBUTES :
+      whatToShow = DTMFilter.SHOW_ATTRIBUTE;
+      axis = Axis.PARENT;
+      predicateAxis = Axis.ATTRIBUTE;
+      // ai = new StepPattern(whatToShow, Axis.SELF, Axis.SELF);
+      break;
+    case OpCodes.FROM_NAMESPACE :
+      whatToShow = DTMFilter.SHOW_NAMESPACE;
+      axis = Axis.PARENT;
+      predicateAxis = Axis.NAMESPACE;
+      // ai = new StepPattern(whatToShow, axis, predicateAxis);
+      break;
+    case OpCodes.FROM_ANCESTORS :
+      axis = Axis.DESCENDANT;
+      predicateAxis = Axis.ANCESTOR;
+      break;
+    case OpCodes.FROM_CHILDREN :
+      axis = Axis.PARENT;
+      predicateAxis = Axis.CHILD;
+      break;
+    case OpCodes.FROM_ANCESTORS_OR_SELF :
+      axis = Axis.DESCENDANTORSELF;
+      predicateAxis = Axis.ANCESTORORSELF;
+      break;
+    case OpCodes.FROM_SELF :
+      axis = Axis.SELF;
+      predicateAxis = Axis.SELF;
+      break;
+    case OpCodes.FROM_PARENT :
+      axis = Axis.CHILD;
+      predicateAxis = Axis.PARENT;
+      break;
+    case OpCodes.FROM_PRECEDING_SIBLINGS :
+      axis = Axis.FOLLOWINGSIBLING;
+      predicateAxis = Axis.PRECEDINGSIBLING;
+      break;
+    case OpCodes.FROM_PRECEDING :
+      axis = Axis.FOLLOWING;
+      predicateAxis = Axis.PRECEDING;
+      break;
+    case OpCodes.FROM_FOLLOWING_SIBLINGS :
+      axis = Axis.PRECEDINGSIBLING;
+      predicateAxis = Axis.FOLLOWINGSIBLING;
+      break;
+    case OpCodes.FROM_FOLLOWING :
+      axis = Axis.PRECEDING;
+      predicateAxis = Axis.FOLLOWING;
+      break;
+    case OpCodes.FROM_DESCENDANTS_OR_SELF :
+      axis = Axis.ANCESTORORSELF;
+      predicateAxis = Axis.DESCENDANTORSELF;
+      break;
+    case OpCodes.FROM_DESCENDANTS :
+      axis = Axis.ANCESTOR;
+      predicateAxis = Axis.DESCENDANT;
+      break;
+    default :
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                                 //+ stepType);
+    }
+    if(null == ai)
+    {
+      whatToShow = compiler.getWhatToShow(opPos); // %REVIEW%
+      ai = new StepPattern(whatToShow, compiler.getStepNS(opPos),
+                                compiler.getStepLocalName(opPos),
+                                axis, predicateAxis);
+    }
+   
+    if (false || DEBUG_PATTERN_CREATION)
+    {
+      System.out.print("new step: "+ ai);
+      System.out.print(", axis: " + Axis.getNames(ai.getAxis()));
+      System.out.print(", predAxis: " + Axis.getNames(ai.getAxis()));
+      System.out.print(", what: ");
+      System.out.print("    ");
+      ai.debugWhatToShow(ai.getWhatToShow());
+    }
+
+    int argLen = compiler.getFirstPredicateOpPos(opPos);
+
+    ai.setPredicates(compiler.getCompiledPredicates(argLen));
+
+    return ai;
+  }
+
+  /**
+   * Analyze a step and give information about it's predicates.  Right now this
+   * just returns true or false if the step has a predicate.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param opPos The opcode position for the step.
+   * @param stepType The type of step, one of OP_GROUP, etc.
+   *
+   * @return true if step has a predicate.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  static boolean analyzePredicate(Compiler compiler, int opPos, int stepType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    int argLen;
+
+    switch (stepType)
+    {
+    case OpCodes.OP_VARIABLE :
+    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_GROUP :
+      argLen = compiler.getArgLength(opPos);
+      break;
+    default :
+      argLen = compiler.getArgLengthOfStep(opPos);
+    }
+
+    int pos = compiler.getFirstPredicateOpPos(opPos);
+    int nPredicates = compiler.countPredicates(pos);
+
+    return (nPredicates > 0) ? true : false;
+  }
+
+  /**
+   * Create the proper Walker from the axes type.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param opPos The opcode position for the step.
+   * @param lpi The owning location path iterator.
+   * @param analysis 32 bits of analysis, from which the type of AxesWalker
+   *                 may be influenced.
+   *
+   * @return non-null reference to AxesWalker derivative.
+   * @throws RuntimeException if the input is bad.
+   */
+  private static AxesWalker createDefaultWalker(Compiler compiler, int opPos,
+          WalkingIterator lpi, int analysis)
+  {
+
+    AxesWalker ai = null;
+    int stepType = compiler.getOp(opPos);
+
+    /*
+    System.out.println("0: "+compiler.getOp(opPos));
+    System.out.println("1: "+compiler.getOp(opPos+1));
+    System.out.println("2: "+compiler.getOp(opPos+2));
+    System.out.println("3: "+compiler.getOp(opPos+3));
+    System.out.println("4: "+compiler.getOp(opPos+4));
+    System.out.println("5: "+compiler.getOp(opPos+5));
+    */
+    boolean simpleInit = false;
+    int totalNumberWalkers = (analysis & BITS_COUNT);
+    boolean prevIsOneStepDown = true;
+
+    switch (stepType)
+    {
+    case OpCodes.OP_VARIABLE :
+    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_FUNCTION :
+    case OpCodes.OP_GROUP :
+      prevIsOneStepDown = false;
+
+      if (DEBUG_WALKER_CREATION)
+        System.out.println("new walker:  FilterExprWalker: " + analysis
+                           + ", " + compiler.toString());
+
+      ai = new FilterExprWalker(lpi);
+      simpleInit = true;
+      break;
+    case OpCodes.FROM_ROOT :
+      ai = new AxesWalker(lpi, Axis.ROOT);
+      break;
+    case OpCodes.FROM_ANCESTORS :
+      prevIsOneStepDown = false;
+      ai = new ReverseAxesWalker(lpi, Axis.ANCESTOR);
+      break;
+    case OpCodes.FROM_ANCESTORS_OR_SELF :
+      prevIsOneStepDown = false;
+      ai = new ReverseAxesWalker(lpi, Axis.ANCESTORORSELF);
+      break;
+    case OpCodes.FROM_ATTRIBUTES :
+      ai = new AxesWalker(lpi, Axis.ATTRIBUTE);
+      break;
+    case OpCodes.FROM_NAMESPACE :
+      ai = new AxesWalker(lpi, Axis.NAMESPACE);
+      break;
+    case OpCodes.FROM_CHILDREN :
+      ai = new AxesWalker(lpi, Axis.CHILD);
+      break;
+    case OpCodes.FROM_DESCENDANTS :
+      prevIsOneStepDown = false;
+      ai = new AxesWalker(lpi, Axis.DESCENDANT);
+      break;
+    case OpCodes.FROM_DESCENDANTS_OR_SELF :
+      prevIsOneStepDown = false;
+      ai = new AxesWalker(lpi, Axis.DESCENDANTORSELF);
+      break;
+    case OpCodes.FROM_FOLLOWING :
+      prevIsOneStepDown = false;
+      ai = new AxesWalker(lpi, Axis.FOLLOWING);
+      break;
+    case OpCodes.FROM_FOLLOWING_SIBLINGS :
+      prevIsOneStepDown = false;
+      ai = new AxesWalker(lpi, Axis.FOLLOWINGSIBLING);
+      break;
+    case OpCodes.FROM_PRECEDING :
+      prevIsOneStepDown = false;
+      ai = new ReverseAxesWalker(lpi, Axis.PRECEDING);
+      break;
+    case OpCodes.FROM_PRECEDING_SIBLINGS :
+      prevIsOneStepDown = false;
+      ai = new ReverseAxesWalker(lpi, Axis.PRECEDINGSIBLING);
+      break;
+    case OpCodes.FROM_PARENT :
+      prevIsOneStepDown = false;
+      ai = new ReverseAxesWalker(lpi, Axis.PARENT);
+      break;
+    case OpCodes.FROM_SELF :
+      ai = new AxesWalker(lpi, Axis.SELF);
+      break;
+    default :
+      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                                 //+ stepType);
+    }
+
+    if (simpleInit)
+    {
+      ai.initNodeTest(DTMFilter.SHOW_ALL);
+    }
+    else
+    {
+      int whatToShow = compiler.getWhatToShow(opPos);
+
+      /*
+      System.out.print("construct: ");
+      NodeTest.debugWhatToShow(whatToShow);
+      System.out.println("or stuff: "+(whatToShow & (DTMFilter.SHOW_ATTRIBUTE
+                             | DTMFilter.SHOW_ELEMENT
+                             | DTMFilter.SHOW_PROCESSING_INSTRUCTION)));
+      */
+      if ((0 == (whatToShow
+                 & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_NAMESPACE | DTMFilter.SHOW_ELEMENT
+                    | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) || (whatToShow == DTMFilter.SHOW_ALL))
+        ai.initNodeTest(whatToShow);
+      else
+      {
+        ai.initNodeTest(whatToShow, compiler.getStepNS(opPos),
+                        compiler.getStepLocalName(opPos));
+      }
+    }
+
+    return ai;
+  }
+  
+  public static String getAnalysisString(int analysis)
+  {
+    StringBuffer buf = new StringBuffer();
+    buf.append("count: "+getStepCount(analysis)+" ");
+    if((analysis & BIT_NODETEST_ANY) != 0)
+    {
+      buf.append("NTANY|");
+    }
+    if((analysis & BIT_PREDICATE) != 0)
+    {
+      buf.append("PRED|");
+    }
+    if((analysis & BIT_ANCESTOR) != 0)
+    {
+      buf.append("ANC|");
+    }
+    if((analysis & BIT_ANCESTOR_OR_SELF) != 0)
+    {
+      buf.append("ANCOS|");
+    }
+    if((analysis & BIT_ATTRIBUTE) != 0)
+    {
+      buf.append("ATTR|");
+    }
+    if((analysis & BIT_CHILD) != 0)
+    {
+      buf.append("CH|");
+    }
+    if((analysis & BIT_DESCENDANT) != 0)
+    {
+      buf.append("DESC|");
+    }
+    if((analysis & BIT_DESCENDANT_OR_SELF) != 0)
+    {
+      buf.append("DESCOS|");
+    }
+    if((analysis & BIT_FOLLOWING) != 0)
+    {
+      buf.append("FOL|");
+    }
+    if((analysis & BIT_FOLLOWING_SIBLING) != 0)
+    {
+      buf.append("FOLS|");
+    }
+    if((analysis & BIT_NAMESPACE) != 0)
+    {
+      buf.append("NS|");
+    }
+    if((analysis & BIT_PARENT) != 0)
+    {
+      buf.append("P|");
+    }
+    if((analysis & BIT_PRECEDING) != 0)
+    {
+      buf.append("PREC|");
+    }
+    if((analysis & BIT_PRECEDING_SIBLING) != 0)
+    {
+      buf.append("PRECS|");
+    }
+    if((analysis & BIT_SELF) != 0)
+    {
+      buf.append(".|");
+    }
+    if((analysis & BIT_FILTER) != 0)
+    {
+      buf.append("FLT|");
+    }
+    if((analysis & BIT_ROOT) != 0)
+    {
+      buf.append("R|");
+    }
+    return buf.toString();
+  }
+
+  /** Set to true for diagnostics about walker creation */
+  static final boolean DEBUG_PATTERN_CREATION = false;
+
+  /** Set to true for diagnostics about walker creation */
+  static final boolean DEBUG_WALKER_CREATION = false;
+
+  /** Set to true for diagnostics about iterator creation */
+  static final boolean DEBUG_ITERATOR_CREATION = false;
+  
+  public static boolean hasPredicate(int analysis)
+  {
+    return (0 != (analysis & BIT_PREDICATE));
+  }
+
+  public static boolean isWild(int analysis)
+  {
+    return (0 != (analysis & BIT_NODETEST_ANY));
+  }
+
+  public static boolean walksAncestors(int analysis)
+  {
+    return isSet(analysis, BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
+  }
+  
+  public static boolean walksAttributes(int analysis)
+  {
+    return (0 != (analysis & BIT_ATTRIBUTE));
+  }
+
+  public static boolean walksNamespaces(int analysis)
+  {
+    return (0 != (analysis & BIT_NAMESPACE));
+  }  
+
+  public static boolean walksChildren(int analysis)
+  {
+    return (0 != (analysis & BIT_CHILD));
+  }
+
+  public static boolean walksDescendants(int analysis)
+  {
+    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF);
+  }
+
+  public static boolean walksSubtree(int analysis)
+  {
+    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | BIT_CHILD);
+  }
+  
+  public static boolean walksSubtreeOnlyMaybeAbsolute(int analysis)
+  {
+    return walksSubtree(analysis)
+           && !walksExtraNodes(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           ;
+  }
+  
+  public static boolean walksSubtreeOnly(int analysis)
+  {
+    return walksSubtreeOnlyMaybeAbsolute(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+
+  public static boolean walksFilteredList(int analysis)
+  {
+    return isSet(analysis, BIT_FILTER);
+  }
+  
+  public static boolean walksSubtreeOnlyFromRootOrContext(int analysis)
+  {
+    return walksSubtree(analysis)
+           && !walksExtraNodes(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isSet(analysis, BIT_FILTER) 
+           ;
+  }
+
+  public static boolean walksInDocOrder(int analysis)
+  {
+    return (walksSubtreeOnlyMaybeAbsolute(analysis)
+           || walksExtraNodesOnly(analysis)
+           || walksFollowingOnlyMaybeAbsolute(analysis)) 
+           && !isSet(analysis, BIT_FILTER) 
+           ;
+  }
+  
+  public static boolean walksFollowingOnlyMaybeAbsolute(int analysis)
+  {
+    return isSet(analysis, BIT_SELF | BIT_FOLLOWING_SIBLING | BIT_FOLLOWING)
+           && !walksSubtree(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           ;
+  }
+  
+  public static boolean walksUp(int analysis)
+  {
+    return isSet(analysis, BIT_PARENT | BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
+  }
+  
+  public static boolean walksSideways(int analysis)
+  {
+    return isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING | 
+                           BIT_PRECEDING | BIT_PRECEDING_SIBLING);
+  }
+  
+  public static boolean walksExtraNodes(int analysis)
+  {
+    return isSet(analysis, BIT_NAMESPACE | BIT_ATTRIBUTE);
+  }
+
+  public static boolean walksExtraNodesOnly(int analysis)
+  {
+    return walksExtraNodes(analysis)
+           && !isSet(analysis, BIT_SELF) 
+           && !walksSubtree(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+
+  public static boolean isAbsolute(int analysis)
+  {
+    return isSet(analysis, BIT_ROOT | BIT_FILTER);
+  }
+  
+  public static boolean walksChildrenOnly(int analysis)
+  {
+    return walksChildren(analysis)
+           && !isSet(analysis, BIT_SELF)
+           && !walksExtraNodes(analysis)
+           && !walksDescendants(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
+           ;
+  }
+  
+  public static boolean walksChildrenAndExtraAndSelfOnly(int analysis)
+  {
+    return walksChildren(analysis)
+           && !walksDescendants(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
+           ;
+  }
+  
+  public static boolean walksDescendantsAndExtraAndSelfOnly(int analysis)
+  {
+    return !walksChildren(analysis)
+           && walksDescendants(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
+           ;
+  }
+  
+  public static boolean walksSelfOnly(int analysis)
+  {
+    return isSet(analysis, BIT_SELF) 
+           && !walksSubtree(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+
+  
+  public static boolean walksUpOnly(int analysis)
+  {
+    return !walksSubtree(analysis) 
+           && walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+  
+  public static boolean walksDownOnly(int analysis)
+  {
+    return walksSubtree(analysis) 
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+
+  public static boolean walksDownExtraOnly(int analysis)
+  {
+    return walksSubtree(analysis) &&  walksExtraNodes(analysis)
+           && !walksUp(analysis) 
+           && !walksSideways(analysis) 
+           && !isAbsolute(analysis) 
+           ;
+  }
+  
+  public static boolean canSkipSubtrees(int analysis)
+  {
+    return isSet(analysis, BIT_CHILD) | walksSideways(analysis);
+  }
+  
+  public static boolean canCrissCross(int analysis)
+  {
+    // This could be done faster.  Coded for clarity.
+    if(walksSelfOnly(analysis))
+      return false;
+    else if(walksDownOnly(analysis) && !canSkipSubtrees(analysis))
+      return false;
+    else if(walksChildrenAndExtraAndSelfOnly(analysis))
+      return false;
+    else if(walksDescendantsAndExtraAndSelfOnly(analysis))
+      return false;
+    else if(walksUpOnly(analysis))
+      return false;
+    else if(walksExtraNodesOnly(analysis))
+      return false;
+    else if(walksSubtree(analysis) 
+           && (walksSideways(analysis) 
+            || walksUp(analysis) 
+            || canSkipSubtrees(analysis)))
+      return true;
+    else
+      return false;
+  }
+  
+  /**
+   * Tell if the pattern can be 'walked' with the iteration steps in natural 
+   * document order, without duplicates.
+   *
+   * @param analysis The general analysis of the pattern.
+   *
+   * @return true if the walk can be done in natural order.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  static public boolean isNaturalDocOrder(int analysis)
+  {
+    if(canCrissCross(analysis) || isSet(analysis, BIT_NAMESPACE) ||
+       walksFilteredList(analysis))
+      return false;
+      
+    if(walksInDocOrder(analysis))
+      return true;
+      
+    return false;
+  }
+  
+  /**
+   * Tell if the pattern can be 'walked' with the iteration steps in natural 
+   * document order, without duplicates.
+   *
+   * @param compiler non-null reference to compiler object that has processed
+   *                 the XPath operations into an opcode map.
+   * @param stepOpCodePos The opcode position for the step.
+   * @param stepIndex The top-level step index withing the iterator.
+   * @param analysis The general analysis of the pattern.
+   *
+   * @return true if the walk can be done in natural order.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private static boolean isNaturalDocOrder(
+          Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
+            throws javax.xml.transform.TransformerException
+  {
+    if(canCrissCross(analysis))
+      return false;
+      
+    // Namespaces can present some problems, so just punt if we're looking for 
+    // these.
+    if(isSet(analysis, BIT_NAMESPACE))
+      return false;
+      
+    // The following, preceding, following-sibling, and preceding sibling can 
+    // be found in doc order if we get to this point, but if they occur 
+    // together, they produce 
+    // duplicates, so it's better for us to eliminate this case so we don't 
+    // have to check for duplicates during runtime if we're using a 
+    // WalkingIterator.
+    if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) && 
+       isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING))
+      return  false;
+      
+    // OK, now we have to check for select="@*/axis::*" patterns, which 
+    // can also cause duplicates to happen.  But select="axis*/@::*" patterns 
+    // are OK, as are select="@foo/axis::*" patterns.
+    // Unfortunately, we can't do this just via the analysis bits.
+    
+    int stepType;
+    int stepCount = 0;
+    boolean foundWildAttribute = false;
+    
+    // Steps that can traverse anything other than down a 
+    // subtree or that can produce duplicates when used in 
+    // combonation are counted with this variable.
+    int potentialDuplicateMakingStepCount = 0;
+    
+    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
+    {        
+      stepCount++;
+        
+      switch (stepType)
+      {
+      case OpCodes.FROM_ATTRIBUTES :
+      case OpCodes.MATCH_ATTRIBUTE :
+        if(foundWildAttribute) // Maybe not needed, but be safe.
+          return false;
+        
+        // This doesn't seem to work as a test for wild card.  Hmph.
+        // int nodeTestType = compiler.getStepTestType(stepOpCodePos);  
+        
+        String localName = compiler.getStepLocalName(stepOpCodePos);
+        // System.err.println("localName: "+localName);
+        if(localName.equals("*"))
+        {
+          foundWildAttribute = true;
+        }
+        break;
+      case OpCodes.FROM_FOLLOWING :
+      case OpCodes.FROM_FOLLOWING_SIBLINGS :
+      case OpCodes.FROM_PRECEDING :
+      case OpCodes.FROM_PRECEDING_SIBLINGS :
+      case OpCodes.FROM_PARENT :
+      case OpCodes.OP_VARIABLE :
+      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_FUNCTION :
+      case OpCodes.OP_GROUP :
+      case OpCodes.FROM_NAMESPACE :
+      case OpCodes.FROM_ANCESTORS :
+      case OpCodes.FROM_ANCESTORS_OR_SELF :      
+      case OpCodes.MATCH_ANY_ANCESTOR :
+      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+      case OpCodes.FROM_DESCENDANTS_OR_SELF :
+      case OpCodes.FROM_DESCENDANTS :
+        if(potentialDuplicateMakingStepCount > 0)
+            return false;
+        potentialDuplicateMakingStepCount++;
+      case OpCodes.FROM_ROOT :
+      case OpCodes.FROM_CHILDREN :
+      case OpCodes.FROM_SELF :
+        if(foundWildAttribute)
+          return false;
+        break;
+      default :
+        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
+                                  // + stepType);
+      }
+
+      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
+
+      if (nextStepOpCodePos < 0)
+        break;
+              
+      stepOpCodePos = nextStepOpCodePos;
+    }
+
+    return true;
+  }
+  
+  public static boolean isOneStep(int analysis)
+  {
+    return (analysis & BITS_COUNT) == 0x00000001;
+  }
+
+  public static int getStepCount(int analysis)
+  {
+    return (analysis & BITS_COUNT);
+  }
+
+  /**
+   * First 8 bits are the number of top-level location steps.  Hopefully
+   *  there will never be more that 255 location steps!!!
+   */
+  public static final int BITS_COUNT = 0x000000FF;
+
+  /** 4 bits are reserved for future use. */
+  public static final int BITS_RESERVED = 0x00000F00;
+
+  /** Bit is on if the expression contains a top-level predicate. */
+  public static final int BIT_PREDICATE = (0x00001000);
+
+  /** Bit is on if any of the walkers contain an ancestor step. */
+  public static final int BIT_ANCESTOR = (0x00001000 << 1);
+
+  /** Bit is on if any of the walkers contain an ancestor-or-self step. */
+  public static final int BIT_ANCESTOR_OR_SELF = (0x00001000 << 2);
+
+  /** Bit is on if any of the walkers contain an attribute step. */
+  public static final int BIT_ATTRIBUTE = (0x00001000 << 3);
+
+  /** Bit is on if any of the walkers contain a child step. */
+  public static final int BIT_CHILD = (0x00001000 << 4);
+
+  /** Bit is on if any of the walkers contain a descendant step. */
+  public static final int BIT_DESCENDANT = (0x00001000 << 5);
+
+  /** Bit is on if any of the walkers contain a descendant-or-self step. */
+  public static final int BIT_DESCENDANT_OR_SELF = (0x00001000 << 6);
+
+  /** Bit is on if any of the walkers contain a following step. */
+  public static final int BIT_FOLLOWING = (0x00001000 << 7);
+
+  /** Bit is on if any of the walkers contain a following-sibiling step. */
+  public static final int BIT_FOLLOWING_SIBLING = (0x00001000 << 8);
+
+  /** Bit is on if any of the walkers contain a namespace step. */
+  public static final int BIT_NAMESPACE = (0x00001000 << 9);
+
+  /** Bit is on if any of the walkers contain a parent step. */
+  public static final int BIT_PARENT = (0x00001000 << 10);
+
+  /** Bit is on if any of the walkers contain a preceding step. */
+  public static final int BIT_PRECEDING = (0x00001000 << 11);
+
+  /** Bit is on if any of the walkers contain a preceding-sibling step. */
+  public static final int BIT_PRECEDING_SIBLING = (0x00001000 << 12);
+
+  /** Bit is on if any of the walkers contain a self step. */
+  public static final int BIT_SELF = (0x00001000 << 13);
+
+  /**
+   * Bit is on if any of the walkers contain a filter (i.e. id(), extension
+   *  function, etc.) step.
+   */
+  public static final int BIT_FILTER = (0x00001000 << 14);
+
+  /** Bit is on if any of the walkers contain a root step. */
+  public static final int BIT_ROOT = (0x00001000 << 15);
+
+  /**
+   * If any of these bits are on, the expression may likely traverse outside
+   *  the given subtree.
+   */
+  public static final int BITMASK_TRAVERSES_OUTSIDE_SUBTREE = (BIT_NAMESPACE  // ??
+                                                                | BIT_PRECEDING_SIBLING
+                                                                | BIT_PRECEDING
+                                                                | BIT_FOLLOWING_SIBLING
+                                                                | BIT_FOLLOWING
+                                                                | BIT_PARENT  // except parent of attrs.
+                                                                | BIT_ANCESTOR_OR_SELF
+                                                                | BIT_ANCESTOR
+                                                                | BIT_FILTER
+                                                                | BIT_ROOT);
+
+  /**
+   * Bit is on if any of the walkers can go backwards in document
+   *  order from the context node.
+   */
+  public static final int BIT_BACKWARDS_SELF = (0x00001000 << 16);
+
+  /** Found "//foo" pattern */
+  public static final int BIT_ANY_DESCENDANT_FROM_ROOT = (0x00001000 << 17);
+
+  /**
+   * Bit is on if any of the walkers contain an node() test.  This is
+   *  really only useful if the count is 1.
+   */
+  public static final int BIT_NODETEST_ANY = (0x00001000 << 18);
+
+  // can't go higher than 18!
+
+  /** Bit is on if the expression is a match pattern. */
+  public static final int BIT_MATCH_PATTERN = (0x00001000 << 19);
+}
diff --git a/src/main/java/org/apache/xpath/axes/WalkingIterator.java b/src/main/java/org/apache/xpath/axes/WalkingIterator.java
new file mode 100644
index 0000000..e82a125
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/WalkingIterator.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WalkingIterator.java 469314 2006-10-30 23:31:59Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.compiler.OpMap;
+
+/**
+ * Location path iterator that uses Walkers.
+ */
+
+public class WalkingIterator extends LocPathIterator implements ExpressionOwner
+{
+    static final long serialVersionUID = 9110225941815665906L;
+  /**
+   * Create a WalkingIterator iterator, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   * @param shouldLoadWalkers True if walkers should be
+   * loaded, or false if this is a derived iterator and
+   * it doesn't wish to load child walkers.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  WalkingIterator(
+          Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
+            throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, shouldLoadWalkers);
+    
+    int firstStepPos = OpMap.getFirstChildPos(opPos);
+
+    if (shouldLoadWalkers)
+    {
+      m_firstWalker = WalkerFactory.loadWalkers(this, compiler, firstStepPos, 0);
+      m_lastUsedWalker = m_firstWalker;
+    }
+  }
+  
+  /**
+   * Create a WalkingIterator object.
+   *
+   * @param nscontext The namespace context for this iterator,
+   * should be OK if null.
+   */
+  public WalkingIterator(PrefixResolver nscontext)
+  {
+
+    super(nscontext);
+  }
+  
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+    int bits = 0;
+    if (null != m_firstWalker)
+    {    	
+      AxesWalker walker = m_firstWalker;
+
+      while (null != walker)
+      {
+        int bit = walker.getAnalysisBits();
+        bits |= bit;
+        walker = walker.getNextWalker();
+      }       
+    }
+    return bits;
+  }
+  
+  /**
+   * Get a cloned WalkingIterator that holds the same
+   * position as this iterator.
+   *
+   * @return A clone of this iterator that holds the same node position.
+   *
+   * @throws CloneNotSupportedException
+   */
+  public Object clone() throws CloneNotSupportedException
+  {
+
+    WalkingIterator clone = (WalkingIterator) super.clone();
+
+    //    clone.m_varStackPos = this.m_varStackPos;
+    //    clone.m_varStackContext = this.m_varStackContext;
+    if (null != m_firstWalker)
+    {
+      clone.m_firstWalker = m_firstWalker.cloneDeep(clone, null);
+    }
+
+    return clone;
+  }
+  
+  /**
+   * Reset the iterator.
+   */
+  public void reset()
+  {
+
+    super.reset();
+
+    if (null != m_firstWalker)
+    {
+      m_lastUsedWalker = m_firstWalker;
+
+      m_firstWalker.setRoot(m_context);
+    }
+
+  }
+  
+  /**
+   * Initialize the context values for this expression
+   * after it is cloned.
+   *
+   * @param context The XPath runtime context for this
+   * transformation.
+   */
+  public void setRoot(int context, Object environment)
+  {
+
+    super.setRoot(context, environment);
+    
+    if(null != m_firstWalker)
+    {
+      m_firstWalker.setRoot(context);
+      m_lastUsedWalker = m_firstWalker;
+    }
+  }
+  
+  /**
+   *  Returns the next node in the set and advances the position of the
+   * iterator in the set. After a NodeIterator is created, the first call
+   * to nextNode() returns the first node in the set.
+   * @return  The next <code>Node</code> in the set being iterated over, or
+   *   <code>null</code> if there are no more members in that set.
+   */
+  public int nextNode()
+  {
+  	if(m_foundLast)
+  		return DTM.NULL;
+
+    // If the variable stack position is not -1, we'll have to 
+    // set our position in the variable stack, so our variable access 
+    // will be correct.  Iterators that are at the top level of the 
+    // expression need to reset the variable stack, while iterators 
+    // in predicates do not need to, and should not, since their execution
+    // may be much later than top-level iterators.  
+    // m_varStackPos is set in setRoot, which is called 
+    // from the execute method.
+    if (-1 == m_stackFrame)
+    {
+      return returnNextNode(m_firstWalker.nextNode());
+    }
+    else
+    {
+      VariableStack vars = m_execContext.getVarStack();
+
+      // These three statements need to be combined into one operation.
+      int savedStart = vars.getStackFrame();
+
+      vars.setStackFrame(m_stackFrame);
+
+      int n = returnNextNode(m_firstWalker.nextNode());
+
+      // These two statements need to be combined into one operation.
+      vars.setStackFrame(savedStart);
+
+      return n;
+    }
+  }
+
+  
+  /**
+   * Get the head of the walker list.
+   *
+   * @return The head of the walker list, or null
+   * if this iterator does not implement walkers.
+   * @xsl.usage advanced
+   */
+  public final AxesWalker getFirstWalker()
+  {
+    return m_firstWalker;
+  }
+  
+  /**
+   * Set the head of the walker list.
+   * 
+   * @param walker Should be a valid AxesWalker.
+   * @xsl.usage advanced
+   */
+  public final void setFirstWalker(AxesWalker walker)
+  {
+    m_firstWalker = walker;
+  }
+
+
+  /**
+   * Set the last used walker.
+   *
+   * @param walker The last used walker, or null.
+   * @xsl.usage advanced
+   */
+  public final void setLastUsedWalker(AxesWalker walker)
+  {
+    m_lastUsedWalker = walker;
+  }
+
+  /**
+   * Get the last used walker.
+   *
+   * @return The last used walker, or null.
+   * @xsl.usage advanced
+   */
+  public final AxesWalker getLastUsedWalker()
+  {
+    return m_lastUsedWalker;
+  }
+  
+  /**
+   *  Detaches the iterator from the set which it iterated over, releasing
+   * any computational resources and placing the iterator in the INVALID
+   * state. After<code>detach</code> has been invoked, calls to
+   * <code>nextNode</code> or<code>previousNode</code> will raise the
+   * exception INVALID_STATE_ERR.
+   */
+  public void detach()
+  {   
+    if(m_allowDetach)
+    {
+	  	AxesWalker walker = m_firstWalker; 
+	    while (null != walker)
+	    {
+	      walker.detach();
+	      walker = walker.getNextWalker();
+	    }
+	
+	    m_lastUsedWalker = null;
+	    
+	    // Always call the superclass detach last!
+	    super.detach();
+    }
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_predicateIndex = -1;
+
+    AxesWalker walker = m_firstWalker;
+
+    while (null != walker)
+    {
+      walker.fixupVariables(vars, globalsSize);
+      walker = walker.getNextWalker();
+    }
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	 	if(visitor.visitLocationPath(owner, this))
+  	 	{
+  	 		if(null != m_firstWalker)
+  	 		{
+  	 			m_firstWalker.callVisitors(this, visitor);
+  	 		}
+  	 	}
+  }
+
+  
+  /** The last used step walker in the walker list.
+   *  @serial */
+  protected AxesWalker m_lastUsedWalker;
+
+  /** The head of the step walker list.
+   *  @serial */
+  protected AxesWalker m_firstWalker;
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_firstWalker;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_firstWalker = (AxesWalker)exp;
+  }
+  
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+                return false;
+
+      AxesWalker walker1 = m_firstWalker;
+      AxesWalker walker2 = ((WalkingIterator)expr).m_firstWalker;
+      while ((null != walker1) && (null != walker2))
+      {
+        if(!walker1.deepEquals(walker2))
+        	return false;
+        walker1 = walker1.getNextWalker();
+        walker2 = walker2.getNextWalker();
+      }
+      
+      if((null != walker1) || (null != walker2))
+      	return false;
+
+      return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/WalkingIteratorSorted.java b/src/main/java/org/apache/xpath/axes/WalkingIteratorSorted.java
new file mode 100644
index 0000000..0878cfe
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/WalkingIteratorSorted.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WalkingIteratorSorted.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.axes;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.compiler.Compiler;
+
+/**
+ * This class iterates over set of nodes that needs to be sorted.
+ * @xsl.usage internal
+ */
+public class WalkingIteratorSorted extends WalkingIterator
+{
+    static final long serialVersionUID = -4512512007542368213L;
+
+//  /** True if the nodes will be found in document order */
+//  protected boolean m_inNaturalOrder = false;
+  
+  /** True if the nodes will be found in document order, and this can 
+   * be determined statically. */
+  protected boolean m_inNaturalOrderStatic = false;
+
+  /**
+   * Create a WalkingIteratorSorted object.
+   *
+   * @param nscontext The namespace context for this iterator,
+   * should be OK if null.
+   */
+  public WalkingIteratorSorted(PrefixResolver nscontext)
+  {
+    super(nscontext);
+  }
+
+  /**
+   * Create a WalkingIterator iterator, including creation
+   * of step walkers from the opcode list, and call back
+   * into the Compiler to create predicate expressions.
+   *
+   * @param compiler The Compiler which is creating
+   * this expression.
+   * @param opPos The position of this iterator in the
+   * opcode list from the compiler.
+   * @param shouldLoadWalkers True if walkers should be
+   * loaded, or false if this is a derived iterator and
+   * it doesn't wish to load child walkers.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  WalkingIteratorSorted(
+          Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
+            throws javax.xml.transform.TransformerException
+  {
+    super(compiler, opPos, analysis, shouldLoadWalkers);
+  }
+  
+  /**
+   * Returns true if all the nodes in the iteration well be returned in document 
+   * order.
+   * 
+   * @return true as a default.
+   */
+  public boolean isDocOrdered()
+  {
+    return m_inNaturalOrderStatic;
+  }
+
+    
+  /**
+   * Tell if the nodeset can be walked in doc order, via static analysis. 
+   *
+   *
+   * @return true if the nodeset can be walked in doc order, without sorting.
+   */
+  boolean canBeWalkedInNaturalDocOrderStatic()
+  {
+
+    if (null != m_firstWalker)
+    {
+      AxesWalker walker = m_firstWalker;
+      int prevAxis = -1;
+      boolean prevIsSimpleDownAxis = true;
+
+      for(int i = 0; null != walker; i++)
+      {
+        int axis = walker.getAxis();
+        
+        if(walker.isDocOrdered())
+        {
+          boolean isSimpleDownAxis = ((axis == Axis.CHILD)
+                                   || (axis == Axis.SELF)
+                                   || (axis == Axis.ROOT));
+          // Catching the filtered list here is only OK because
+          // FilterExprWalker#isDocOrdered() did the right thing.
+          if(isSimpleDownAxis || (axis == -1))
+            walker = walker.getNextWalker();
+          else
+          {
+            boolean isLastWalker = (null == walker.getNextWalker());
+            if(isLastWalker)
+            {
+              if(walker.isDocOrdered() && (axis == Axis.DESCENDANT || 
+                 axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
+                 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
+                return true;
+            }
+            return false;
+          }
+        }
+        else
+          return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+//  /**
+//   * NEEDSDOC Method canBeWalkedInNaturalDocOrder 
+//   *
+//   *
+//   * NEEDSDOC (canBeWalkedInNaturalDocOrder) @return
+//   */
+//  boolean canBeWalkedInNaturalDocOrder()
+//  {
+//
+//    if (null != m_firstWalker)
+//    {
+//      AxesWalker walker = m_firstWalker;
+//      int prevAxis = -1;
+//      boolean prevIsSimpleDownAxis = true;
+//
+//      for(int i = 0; null != walker; i++)
+//      {
+//        int axis = walker.getAxis();
+//        
+//        if(walker.isDocOrdered())
+//        {
+//          boolean isSimpleDownAxis = ((axis == Axis.CHILD)
+//                                   || (axis == Axis.SELF)
+//                                   || (axis == Axis.ROOT));
+//          // Catching the filtered list here is only OK because
+//          // FilterExprWalker#isDocOrdered() did the right thing.
+//          if(isSimpleDownAxis || (axis == -1))
+//            walker = walker.getNextWalker();
+//          else
+//          {
+//            boolean isLastWalker = (null == walker.getNextWalker());
+//            if(isLastWalker)
+//            {
+//              if(walker.isDocOrdered() && (axis == Axis.DESCENDANT || 
+//                 axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
+//                 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
+//                return true;
+//            }
+//            return false;
+//          }
+//        }
+//        else
+//          return false;
+//      }
+//      return true;
+//    }
+//    return false;
+//  }
+  
+  /**
+   * This function is used to perform some extra analysis of the iterator.
+   * 
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+
+    int analysis = getAnalysisBits();
+    if(WalkerFactory.isNaturalDocOrder(analysis))
+    {
+    	m_inNaturalOrderStatic = true;
+    }
+    else
+    {
+    	m_inNaturalOrderStatic = false;
+    	// System.out.println("Setting natural doc order to false: "+
+    	//    WalkerFactory.getAnalysisString(analysis));
+    }
+    
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/axes/package.html b/src/main/java/org/apache/xpath/axes/package.html
new file mode 100644
index 0000000..4fc1234
--- /dev/null
+++ b/src/main/java/org/apache/xpath/axes/package.html
@@ -0,0 +1,27 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath LocationPath support.</title>
+  <body>
+    <p>Implementation of XPath LocationPath support -- primary classes are 
+    LocPathIterator and UnionPathIterator.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/compiler/Compiler.java b/src/main/java/org/apache/xpath/compiler/Compiler.java
new file mode 100644
index 0000000..70b1ea1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/Compiler.java
@@ -0,0 +1,1268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Compiler.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.axes.UnionPathIterator;
+import org.apache.xpath.axes.WalkerFactory;
+import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.FuncExtFunctionAvailable;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.WrongNumberArgsException;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.And;
+import org.apache.xpath.operations.Div;
+import org.apache.xpath.operations.Equals;
+import org.apache.xpath.operations.Gt;
+import org.apache.xpath.operations.Gte;
+import org.apache.xpath.operations.Lt;
+import org.apache.xpath.operations.Lte;
+import org.apache.xpath.operations.Minus;
+import org.apache.xpath.operations.Mod;
+import org.apache.xpath.operations.Mult;
+import org.apache.xpath.operations.Neg;
+import org.apache.xpath.operations.NotEquals;
+import org.apache.xpath.operations.Operation;
+import org.apache.xpath.operations.Or;
+import org.apache.xpath.operations.Plus;
+import org.apache.xpath.operations.UnaryOperation;
+import org.apache.xpath.operations.Variable;
+import org.apache.xpath.patterns.FunctionPattern;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.patterns.StepPattern;
+import org.apache.xpath.patterns.UnionPattern;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * An instance of this class compiles an XPath string expression into 
+ * a Expression object.  This class compiles the string into a sequence 
+ * of operation codes (op map) and then builds from that into an Expression 
+ * tree.
+ * @xsl.usage advanced
+ */
+public class Compiler extends OpMap
+{
+
+  /**
+   * Construct a Compiler object with a specific ErrorListener and 
+   * SourceLocator where the expression is located.
+   *
+   * @param errorHandler Error listener where messages will be sent, or null 
+   *                     if messages should be sent to System err.
+   * @param locator The location object where the expression lives, which 
+   *                may be null, but which, if not null, must be valid over 
+   *                the long haul, in other words, it will not be cloned.
+   * @param fTable  The FunctionTable object where the xpath build-in 
+   *                functions are stored.
+   */
+  public Compiler(ErrorListener errorHandler, SourceLocator locator, 
+            FunctionTable fTable)
+  {
+    m_errorHandler = errorHandler;
+    m_locator = locator;
+    m_functionTable = fTable;
+  }
+
+  /**
+   * Construct a Compiler instance that has a null error listener and a 
+   * null source locator.
+   */
+  public Compiler()
+  {
+    m_errorHandler = null;
+    m_locator = null;
+  }
+
+  /**
+   * Execute the XPath object from a given opcode position.
+   * @param opPos The current position in the xpath.m_opMap array.
+   * @return The result of the XPath.
+   *
+   * @throws TransformerException if there is a syntax or other error.
+   * @xsl.usage advanced
+   */
+  public Expression compile(int opPos) throws TransformerException
+  {
+
+    int op = getOp(opPos);
+
+    Expression expr = null;
+    // System.out.println(getPatternString()+"op: "+op);
+    switch (op)
+    {
+    case OpCodes.OP_XPATH :
+      expr = compile(opPos + 2); break;
+    case OpCodes.OP_OR :
+      expr = or(opPos); break;
+    case OpCodes.OP_AND :
+      expr = and(opPos); break;
+    case OpCodes.OP_NOTEQUALS :
+      expr = notequals(opPos); break;
+    case OpCodes.OP_EQUALS :
+      expr = equals(opPos); break;
+    case OpCodes.OP_LTE :
+      expr = lte(opPos); break;
+    case OpCodes.OP_LT :
+      expr = lt(opPos); break;
+    case OpCodes.OP_GTE :
+      expr = gte(opPos); break;
+    case OpCodes.OP_GT :
+      expr = gt(opPos); break;
+    case OpCodes.OP_PLUS :
+      expr = plus(opPos); break;
+    case OpCodes.OP_MINUS :
+      expr = minus(opPos); break;
+    case OpCodes.OP_MULT :
+      expr = mult(opPos); break;
+    case OpCodes.OP_DIV :
+      expr = div(opPos); break;
+    case OpCodes.OP_MOD :
+      expr = mod(opPos); break;
+//    case OpCodes.OP_QUO :
+//      expr = quo(opPos); break;
+    case OpCodes.OP_NEG :
+      expr = neg(opPos); break;
+    case OpCodes.OP_STRING :
+      expr = string(opPos); break;
+    case OpCodes.OP_BOOL :
+      expr = bool(opPos); break;
+    case OpCodes.OP_NUMBER :
+      expr = number(opPos); break;
+    case OpCodes.OP_UNION :
+      expr = union(opPos); break;
+    case OpCodes.OP_LITERAL :
+      expr = literal(opPos); break;
+    case OpCodes.OP_VARIABLE :
+      expr = variable(opPos); break;
+    case OpCodes.OP_GROUP :
+      expr = group(opPos); break;
+    case OpCodes.OP_NUMBERLIT :
+      expr = numberlit(opPos); break;
+    case OpCodes.OP_ARGUMENT :
+      expr = arg(opPos); break;
+    case OpCodes.OP_EXTFUNCTION :
+      expr = compileExtension(opPos); break;
+    case OpCodes.OP_FUNCTION :
+      expr = compileFunction(opPos); break;
+    case OpCodes.OP_LOCATIONPATH :
+      expr = locationPath(opPos); break;
+    case OpCodes.OP_PREDICATE :
+      expr = null; break;  // should never hit this here.
+    case OpCodes.OP_MATCHPATTERN :
+      expr = matchPattern(opPos + 2); break;
+    case OpCodes.OP_LOCATIONPATHPATTERN :
+      expr = locationPathPattern(opPos); break;
+    case OpCodes.OP_QUO:
+      error(XPATHErrorResources.ER_UNKNOWN_OPCODE,
+            new Object[]{ "quo" });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
+      break;
+    default :
+      error(XPATHErrorResources.ER_UNKNOWN_OPCODE,
+            new Object[]{ Integer.toString(getOp(opPos)) });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
+    }
+//    if(null != expr)
+//      expr.setSourceLocator(m_locator);
+
+    return expr;
+  }
+
+  /**
+   * Bottle-neck compilation of an operation with left and right operands.
+   *
+   * @param operation non-null reference to parent operation.
+   * @param opPos The op map position of the parent operation.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Operation} instance.
+   *
+   * @throws TransformerException if there is a syntax or other error.
+   */
+  private Expression compileOperation(Operation operation, int opPos)
+          throws TransformerException
+  {
+
+    int leftPos = getFirstChildPos(opPos);
+    int rightPos = getNextOpPos(leftPos);
+
+    operation.setLeftRight(compile(leftPos), compile(rightPos));
+
+    return operation;
+  }
+
+  /**
+   * Bottle-neck compilation of a unary operation.
+   *
+   * @param unary The parent unary operation.
+   * @param opPos The position in the op map of the parent operation.
+   *
+   * @return The unary argument.
+   *
+   * @throws TransformerException if syntax or other error occurs.
+   */
+  private Expression compileUnary(UnaryOperation unary, int opPos)
+          throws TransformerException
+  {
+
+    int rightPos = getFirstChildPos(opPos);
+
+    unary.setRight(compile(rightPos));
+
+    return unary;
+  }
+
+  /**
+   * Compile an 'or' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Or} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression or(int opPos) throws TransformerException
+  {
+    return compileOperation(new Or(), opPos);
+  }
+
+  /**
+   * Compile an 'and' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.And} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression and(int opPos) throws TransformerException
+  {
+    return compileOperation(new And(), opPos);
+  }
+
+  /**
+   * Compile a '!=' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.NotEquals} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression notequals(int opPos) throws TransformerException
+  {
+    return compileOperation(new NotEquals(), opPos);
+  }
+
+  /**
+   * Compile a '=' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Equals} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression equals(int opPos) throws TransformerException
+  {
+    return compileOperation(new Equals(), opPos);
+  }
+
+  /**
+   * Compile a '<=' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Lte} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression lte(int opPos) throws TransformerException
+  {
+    return compileOperation(new Lte(), opPos);
+  }
+
+  /**
+   * Compile a '<' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Lt} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression lt(int opPos) throws TransformerException
+  {
+    return compileOperation(new Lt(), opPos);
+  }
+
+  /**
+   * Compile a '>=' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Gte} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression gte(int opPos) throws TransformerException
+  {
+    return compileOperation(new Gte(), opPos);
+  }
+
+  /**
+   * Compile a '>' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Gt} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression gt(int opPos) throws TransformerException
+  {
+    return compileOperation(new Gt(), opPos);
+  }
+
+  /**
+   * Compile a '+' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Plus} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression plus(int opPos) throws TransformerException
+  {
+    return compileOperation(new Plus(), opPos);
+  }
+
+  /**
+   * Compile a '-' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Minus} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression minus(int opPos) throws TransformerException
+  {
+    return compileOperation(new Minus(), opPos);
+  }
+
+  /**
+   * Compile a '*' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Mult} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression mult(int opPos) throws TransformerException
+  {
+    return compileOperation(new Mult(), opPos);
+  }
+
+  /**
+   * Compile a 'div' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Div} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression div(int opPos) throws TransformerException
+  {
+    return compileOperation(new Div(), opPos);
+  }
+
+  /**
+   * Compile a 'mod' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Mod} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression mod(int opPos) throws TransformerException
+  {
+    return compileOperation(new Mod(), opPos);
+  }
+
+  /*
+   * Compile a 'quo' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Quo} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+//  protected Expression quo(int opPos) throws TransformerException
+//  {
+//    return compileOperation(new Quo(), opPos);
+//  }
+
+  /**
+   * Compile a unary '-' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Neg} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression neg(int opPos) throws TransformerException
+  {
+    return compileUnary(new Neg(), opPos);
+  }
+
+  /**
+   * Compile a 'string(...)' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.String} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression string(int opPos) throws TransformerException
+  {
+    return compileUnary(new org.apache.xpath.operations.String(), opPos);
+  }
+
+  /**
+   * Compile a 'boolean(...)' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Bool} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression bool(int opPos) throws TransformerException
+  {
+    return compileUnary(new org.apache.xpath.operations.Bool(), opPos);
+  }
+
+  /**
+   * Compile a 'number(...)' operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Number} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression number(int opPos) throws TransformerException
+  {
+    return compileUnary(new org.apache.xpath.operations.Number(), opPos);
+  }
+
+  /**
+   * Compile a literal string value.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.objects.XString} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression literal(int opPos)
+  {
+
+    opPos = getFirstChildPos(opPos);
+
+    return (XString) getTokenQueue().elementAt(getOp(opPos));
+  }
+
+  /**
+   * Compile a literal number value.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.objects.XNumber} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression numberlit(int opPos)
+  {
+
+    opPos = getFirstChildPos(opPos);
+
+    return (XNumber) getTokenQueue().elementAt(getOp(opPos));
+  }
+
+  /**
+   * Compile a variable reference.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.operations.Variable} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression variable(int opPos) throws TransformerException
+  {
+
+    Variable var = new Variable();
+
+    opPos = getFirstChildPos(opPos);
+
+    int nsPos = getOp(opPos);
+    java.lang.String namespace 
+      = (OpCodes.EMPTY == nsPos) ? null 
+                                   : (java.lang.String) getTokenQueue().elementAt(nsPos);
+    java.lang.String localname 
+      = (java.lang.String) getTokenQueue().elementAt(getOp(opPos+1));
+    QName qname = new QName(namespace, localname);
+
+    var.setQName(qname);
+
+    return var;
+  }
+
+  /**
+   * Compile an expression group.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to the contained expression.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression group(int opPos) throws TransformerException
+  {
+
+    // no-op
+    return compile(opPos + 2);
+  }
+
+  /**
+   * Compile a function argument.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to the argument expression.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression arg(int opPos) throws TransformerException
+  {
+
+    // no-op
+    return compile(opPos + 2);
+  }
+
+  /**
+   * Compile a location path union. The UnionPathIterator itself may create
+   * {@link org.apache.xpath.axes.LocPathIterator} children.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.axes.LocPathIterator} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression union(int opPos) throws TransformerException
+  {
+    locPathDepth++;
+    try
+    {
+      return UnionPathIterator.createUnionIterator(this, opPos);
+    }
+    finally
+    {
+      locPathDepth--;
+    }
+  }
+  
+  private int locPathDepth = -1;
+  
+  /**
+   * Get the level of the location path or union being constructed.  
+   * @return 0 if it is a top-level path.
+   */
+  public int getLocationPathDepth()
+  {
+    return locPathDepth;
+  }
+
+  /**
+   * Get the function table  
+   */
+  FunctionTable getFunctionTable()
+  {
+    return m_functionTable;
+  }
+
+  /**
+   * Compile a location path.  The LocPathIterator itself may create
+   * {@link org.apache.xpath.axes.AxesWalker} children.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.axes.LocPathIterator} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  public Expression locationPath(int opPos) throws TransformerException
+  {
+    locPathDepth++;
+    try
+    {
+      DTMIterator iter = WalkerFactory.newDTMIterator(this, opPos, (locPathDepth == 0));
+      return (Expression)iter; // cast OK, I guess.
+    }
+    finally
+    {
+      locPathDepth--;
+    }
+  }
+
+  /**
+   * Compile a location step predicate expression.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return the contained predicate expression.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  public Expression predicate(int opPos) throws TransformerException
+  {
+    return compile(opPos + 2);
+  }
+
+  /**
+   * Compile an entire match pattern expression.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.patterns.UnionPattern} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression matchPattern(int opPos) throws TransformerException
+  {
+    locPathDepth++;
+    try
+    {
+      // First, count...
+      int nextOpPos = opPos;
+      int i;
+
+      for (i = 0; getOp(nextOpPos) == OpCodes.OP_LOCATIONPATHPATTERN; i++)
+      {
+        nextOpPos = getNextOpPos(nextOpPos);
+      }
+
+      if (i == 1)
+        return compile(opPos);
+
+      UnionPattern up = new UnionPattern();
+      StepPattern[] patterns = new StepPattern[i];
+
+      for (i = 0; getOp(opPos) == OpCodes.OP_LOCATIONPATHPATTERN; i++)
+      {
+        nextOpPos = getNextOpPos(opPos);
+        patterns[i] = (StepPattern) compile(opPos);
+        opPos = nextOpPos;
+      }
+
+      up.setPatterns(patterns);
+
+      return up;
+    }
+    finally
+    {
+      locPathDepth--;
+    }
+  }
+
+  /**
+   * Compile a location match pattern unit expression.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.patterns.StepPattern} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  public Expression locationPathPattern(int opPos)
+          throws TransformerException
+  {
+
+    opPos = getFirstChildPos(opPos);
+
+    return stepPattern(opPos, 0, null);
+  }
+
+  /**
+   * Get a {@link org.w3c.dom.traversal.NodeFilter} bit set that tells what 
+   * to show for a given node test.
+   *
+   * @param opPos the op map position for the location step.
+   *
+   * @return {@link org.w3c.dom.traversal.NodeFilter} bit set that tells what 
+   *         to show for a given node test.
+   */
+  public int getWhatToShow(int opPos)
+  {
+
+    int axesType = getOp(opPos);
+    int testType = getOp(opPos + 3);
+
+    // System.out.println("testType: "+testType);
+    switch (testType)
+    {
+    case OpCodes.NODETYPE_COMMENT :
+      return DTMFilter.SHOW_COMMENT;
+    case OpCodes.NODETYPE_TEXT :
+//      return DTMFilter.SHOW_TEXT | DTMFilter.SHOW_COMMENT;
+      return DTMFilter.SHOW_TEXT | DTMFilter.SHOW_CDATA_SECTION ;
+    case OpCodes.NODETYPE_PI :
+      return DTMFilter.SHOW_PROCESSING_INSTRUCTION;
+    case OpCodes.NODETYPE_NODE :
+//      return DTMFilter.SHOW_ALL;
+      switch (axesType)
+      {
+      case OpCodes.FROM_NAMESPACE:
+        return DTMFilter.SHOW_NAMESPACE;
+      case OpCodes.FROM_ATTRIBUTES :
+      case OpCodes.MATCH_ATTRIBUTE :
+        return DTMFilter.SHOW_ATTRIBUTE;
+      case OpCodes.FROM_SELF:
+      case OpCodes.FROM_ANCESTORS_OR_SELF:
+      case OpCodes.FROM_DESCENDANTS_OR_SELF:
+        return DTMFilter.SHOW_ALL;
+      default:
+        if (getOp(0) == OpCodes.OP_MATCHPATTERN)
+          return ~DTMFilter.SHOW_ATTRIBUTE
+                  & ~DTMFilter.SHOW_DOCUMENT
+                  & ~DTMFilter.SHOW_DOCUMENT_FRAGMENT;
+        else
+          return ~DTMFilter.SHOW_ATTRIBUTE;
+      }
+    case OpCodes.NODETYPE_ROOT :
+      return DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT;
+    case OpCodes.NODETYPE_FUNCTEST :
+      return NodeTest.SHOW_BYFUNCTION;
+    case OpCodes.NODENAME :
+      switch (axesType)
+      {
+      case OpCodes.FROM_NAMESPACE :
+        return DTMFilter.SHOW_NAMESPACE;
+      case OpCodes.FROM_ATTRIBUTES :
+      case OpCodes.MATCH_ATTRIBUTE :
+        return DTMFilter.SHOW_ATTRIBUTE;
+
+      // break;
+      case OpCodes.MATCH_ANY_ANCESTOR :
+      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+        return DTMFilter.SHOW_ELEMENT;
+
+      // break;
+      default :
+        return DTMFilter.SHOW_ELEMENT;
+      }
+    default :
+      // System.err.println("We should never reach here.");
+      return DTMFilter.SHOW_ALL;
+    }
+  }
+  
+private static final boolean DEBUG = false;
+
+  /**
+   * Compile a step pattern unit expression, used for both location paths 
+   * and match patterns.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   * @param stepCount The number of steps to expect.
+   * @param ancestorPattern The owning StepPattern, which may be null.
+   *
+   * @return reference to {@link org.apache.xpath.patterns.StepPattern} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected StepPattern stepPattern(
+          int opPos, int stepCount, StepPattern ancestorPattern)
+            throws TransformerException
+  {
+
+    int startOpPos = opPos;
+    int stepType = getOp(opPos);
+
+    if (OpCodes.ENDOP == stepType)
+    {
+      return null;
+    }
+    
+    boolean addMagicSelf = true;
+
+    int endStep = getNextOpPos(opPos);
+
+    // int nextStepType = getOpMap()[endStep];
+    StepPattern pattern;
+    
+    // boolean isSimple = ((OpCodes.ENDOP == nextStepType) && (stepCount == 0));
+    int argLen;
+
+    switch (stepType)
+    {
+    case OpCodes.OP_FUNCTION :
+      if(DEBUG)
+        System.out.println("MATCH_FUNCTION: "+m_currentPattern); 
+      addMagicSelf = false;
+      argLen = getOp(opPos + OpMap.MAPINDEX_LENGTH);
+      pattern = new FunctionPattern(compileFunction(opPos), Axis.PARENT, Axis.CHILD);
+      break;
+    case OpCodes.FROM_ROOT :
+      if(DEBUG)
+        System.out.println("FROM_ROOT, "+m_currentPattern);
+      addMagicSelf = false;
+      argLen = getArgLengthOfStep(opPos);
+      opPos = getFirstChildPosOfStep(opPos);
+      pattern = new StepPattern(DTMFilter.SHOW_DOCUMENT | 
+                                DTMFilter.SHOW_DOCUMENT_FRAGMENT,
+                                Axis.PARENT, Axis.CHILD);
+      break;
+    case OpCodes.MATCH_ATTRIBUTE :
+     if(DEBUG)
+        System.out.println("MATCH_ATTRIBUTE: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
+      argLen = getArgLengthOfStep(opPos);
+      opPos = getFirstChildPosOfStep(opPos);
+      pattern = new StepPattern(DTMFilter.SHOW_ATTRIBUTE,
+                                getStepNS(startOpPos),
+                                getStepLocalName(startOpPos),
+                                Axis.PARENT, Axis.ATTRIBUTE);
+      break;
+    case OpCodes.MATCH_ANY_ANCESTOR :
+      if(DEBUG)
+        System.out.println("MATCH_ANY_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
+      argLen = getArgLengthOfStep(opPos);
+      opPos = getFirstChildPosOfStep(opPos);
+      int what = getWhatToShow(startOpPos);
+      // bit-o-hackery, but this code is due for the morgue anyway...
+      if(0x00000500 == what)
+        addMagicSelf = false;
+      pattern = new StepPattern(getWhatToShow(startOpPos),
+                                        getStepNS(startOpPos),
+                                        getStepLocalName(startOpPos),
+                                        Axis.ANCESTOR, Axis.CHILD);
+      break;
+    case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+      if(DEBUG)
+        System.out.println("MATCH_IMMEDIATE_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
+      argLen = getArgLengthOfStep(opPos);
+      opPos = getFirstChildPosOfStep(opPos);
+      pattern = new StepPattern(getWhatToShow(startOpPos),
+                                getStepNS(startOpPos),
+                                getStepLocalName(startOpPos),
+                                Axis.PARENT, Axis.CHILD);
+      break;
+    default :
+      error(XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION, null);  //"unknown match operation!");
+
+      return null;
+    }
+
+    pattern.setPredicates(getCompiledPredicates(opPos + argLen));
+    if(null == ancestorPattern)
+    {
+      // This is the magic and invisible "." at the head of every 
+      // match pattern, and corresponds to the current node in the context 
+      // list, from where predicates are counted.
+      // So, in order to calculate "foo[3]", it has to count from the 
+      // current node in the context list, so, from that current node, 
+      // the full pattern is really "self::node()/child::foo[3]".  If you 
+      // translate this to a select pattern from the node being tested, 
+      // which is really how we're treating match patterns, it works out to 
+      // self::foo/parent::node[child::foo[3]]", or close enough.
+	/*      if(addMagicSelf && pattern.getPredicateCount() > 0)
+      {
+        StepPattern selfPattern = new StepPattern(DTMFilter.SHOW_ALL, 
+                                                  Axis.PARENT, Axis.CHILD);
+        // We need to keep the new nodetest from affecting the score...
+        XNumber score = pattern.getStaticScore();
+        pattern.setRelativePathPattern(selfPattern);
+        pattern.setStaticScore(score);
+        selfPattern.setStaticScore(score);
+	}*/
+    }
+    else
+    {
+      // System.out.println("Setting "+ancestorPattern+" as relative to "+pattern);
+      pattern.setRelativePathPattern(ancestorPattern);
+    }
+
+    StepPattern relativePathPattern = stepPattern(endStep, stepCount + 1,
+                                        pattern);
+
+    return (null != relativePathPattern) ? relativePathPattern : pattern;
+  }
+
+  /**
+   * Compile a zero or more predicates for a given match pattern.
+   * 
+   * @param opPos The position of the first predicate the m_opMap array.
+   *
+   * @return reference to array of {@link org.apache.xpath.Expression} instances.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  public Expression[] getCompiledPredicates(int opPos)
+          throws TransformerException
+  {
+
+    int count = countPredicates(opPos);
+
+    if (count > 0)
+    {
+      Expression[] predicates = new Expression[count];
+
+      compilePredicates(opPos, predicates);
+
+      return predicates;
+    }
+
+    return null;
+  }
+
+  /**
+   * Count the number of predicates in the step.
+   *
+   * @param opPos The position of the first predicate the m_opMap array.
+   *
+   * @return The number of predicates for this step.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  public int countPredicates(int opPos) throws TransformerException
+  {
+
+    int count = 0;
+
+    while (OpCodes.OP_PREDICATE == getOp(opPos))
+    {
+      count++;
+
+      opPos = getNextOpPos(opPos);
+    }
+
+    return count;
+  }
+
+  /**
+   * Compiles predicates in the step.
+   *
+   * @param opPos The position of the first predicate the m_opMap array.
+   * @param predicates An empty pre-determined array of 
+   *            {@link org.apache.xpath.Expression}s, that will be filled in.
+   *
+   * @throws TransformerException
+   */
+  private void compilePredicates(int opPos, Expression[] predicates)
+          throws TransformerException
+  {
+
+    for (int i = 0; OpCodes.OP_PREDICATE == getOp(opPos); i++)
+    {
+      predicates[i] = predicate(opPos);
+      opPos = getNextOpPos(opPos);
+    }
+  }
+
+  /**
+   * Compile a built-in XPath function.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.functions.Function} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  Expression compileFunction(int opPos) throws TransformerException
+  {
+
+    int endFunc = opPos + getOp(opPos + 1) - 1;
+
+    opPos = getFirstChildPos(opPos);
+
+    int funcID = getOp(opPos);
+
+    opPos++;
+
+    if (-1 != funcID)
+    {
+      Function func = m_functionTable.getFunction(funcID);
+      
+      /**
+       * It is a trick for function-available. Since the function table is an
+       * instance field, insert this table at compilation time for later usage
+       */
+      
+      if (func instanceof FuncExtFunctionAvailable)
+          ((FuncExtFunctionAvailable) func).setFunctionTable(m_functionTable);
+
+      func.postCompileStep(this);
+      
+      try
+      {
+        int i = 0;
+
+        for (int p = opPos; p < endFunc; p = getNextOpPos(p), i++)
+        {
+
+          // System.out.println("argPos: "+ p);
+          // System.out.println("argCode: "+ m_opMap[p]);
+          func.setArg(compile(p), i);
+        }
+
+        func.checkNumberArgs(i);
+      }
+      catch (WrongNumberArgsException wnae)
+      {
+        java.lang.String name = m_functionTable.getFunctionName(funcID);
+
+        m_errorHandler.fatalError( new TransformerException(
+                  XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ONLY_ALLOWS, 
+                      new Object[]{name, wnae.getMessage()}), m_locator)); 
+              //"name + " only allows " + wnae.getMessage() + " arguments", m_locator));
+      }
+
+      return func;
+    }
+    else
+    {
+      error(XPATHErrorResources.ER_FUNCTION_TOKEN_NOT_FOUND, null);  //"function token not found.");
+
+      return null;
+    }
+  }
+
+  // The current id for extension functions.
+  private static long s_nextMethodId = 0;
+
+  /**
+   * Get the next available method id
+   */
+  synchronized private long getNextMethodId()
+  {
+    if (s_nextMethodId == Long.MAX_VALUE)
+      s_nextMethodId = 0;
+    
+    return s_nextMethodId++;
+  }
+  
+  /**
+   * Compile an extension function.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return reference to {@link org.apache.xpath.functions.FuncExtFunction} instance.
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  private Expression compileExtension(int opPos)
+          throws TransformerException
+  {
+
+    int endExtFunc = opPos + getOp(opPos + 1) - 1;
+
+    opPos = getFirstChildPos(opPos);
+
+    java.lang.String ns = (java.lang.String) getTokenQueue().elementAt(getOp(opPos));
+
+    opPos++;
+
+    java.lang.String funcName =
+      (java.lang.String) getTokenQueue().elementAt(getOp(opPos));
+
+    opPos++;
+
+    // We create a method key to uniquely identify this function so that we
+    // can cache the object needed to invoke it.  This way, we only pay the
+    // reflection overhead on the first call.
+
+    Function extension = new FuncExtFunction(ns, funcName, String.valueOf(getNextMethodId()));
+
+    try
+    {
+      int i = 0;
+
+      while (opPos < endExtFunc)
+      {
+        int nextOpPos = getNextOpPos(opPos);
+
+        extension.setArg(this.compile(opPos), i);
+
+        opPos = nextOpPos;
+
+        i++;
+      }
+    }
+    catch (WrongNumberArgsException wnae)
+    {
+      ;  // should never happen
+    }
+
+    return extension;
+  }
+
+  /**
+   * Warn the user of an problem.
+   *
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  public void warn(String msg, Object[] args) throws TransformerException
+  {
+
+    java.lang.String fmsg = XSLMessages.createXPATHWarning(msg, args);
+
+    if (null != m_errorHandler)
+    {
+      m_errorHandler.warning(new TransformerException(fmsg, m_locator));
+    }
+    else
+    {
+      System.out.println(fmsg
+                          +"; file "+m_locator.getSystemId()
+                          +"; line "+m_locator.getLineNumber()
+                          +"; column "+m_locator.getColumnNumber());
+    }
+  }
+
+  /**
+   * Tell the user of an assertion error, and probably throw an
+   * exception.
+   *
+   * @param b  If false, a runtime exception will be thrown.
+   * @param msg The assertion message, which should be informative.
+   * 
+   * @throws RuntimeException if the b argument is false.
+   */
+  public void assertion(boolean b, java.lang.String msg)
+  {
+
+    if (!b)
+    {
+      java.lang.String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ msg });
+
+      throw new RuntimeException(fMsg);
+    }
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  public void error(String msg, Object[] args) throws TransformerException
+  {
+
+    java.lang.String fmsg = XSLMessages.createXPATHMessage(msg, args);
+    
+
+    if (null != m_errorHandler)
+    {
+      m_errorHandler.fatalError(new TransformerException(fmsg, m_locator));
+    }
+    else
+    {
+
+      // System.out.println(te.getMessage()
+      //                    +"; file "+te.getSystemId()
+      //                    +"; line "+te.getLineNumber()
+      //                    +"; column "+te.getColumnNumber());
+      throw new TransformerException(fmsg, (SAXSourceLocator)m_locator);
+    }
+  }
+
+  /**
+   * The current prefixResolver for the execution context.
+   */
+  private PrefixResolver m_currentPrefixResolver = null;
+
+  /**
+   * Get the current namespace context for the xpath.
+   *
+   * @return The current prefix resolver, *may* be null, though hopefully not.
+   */
+  public PrefixResolver getNamespaceContext()
+  {
+    return m_currentPrefixResolver;
+  }
+
+  /**
+   * Set the current namespace context for the xpath.
+   *
+   * @param pr The resolver for prefixes in the XPath expression.
+   */
+  public void setNamespaceContext(PrefixResolver pr)
+  {
+    m_currentPrefixResolver = pr;
+  }
+
+  /** The error listener where errors will be sent.  If this is null, errors 
+   *  and warnings will be sent to System.err.  May be null.    */
+  ErrorListener m_errorHandler;
+
+  /** The source locator for the expression being compiled.  May be null. */
+  SourceLocator m_locator;
+  
+  /**
+   * The FunctionTable for all xpath build-in functions
+   */
+  private FunctionTable m_functionTable;
+}
diff --git a/src/main/java/org/apache/xpath/compiler/FunctionTable.java b/src/main/java/org/apache/xpath/compiler/FunctionTable.java
new file mode 100644
index 0000000..1ffb564
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/FunctionTable.java
@@ -0,0 +1,407 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FunctionTable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.functions.Function;
+import java.util.HashMap;
+import javax.xml.transform.TransformerException;
+
+/**
+ * The function table for XPath.
+ */
+public class FunctionTable
+{
+
+  /** The 'current()' id. */
+  public static final int FUNC_CURRENT = 0;
+
+  /** The 'last()' id. */
+  public static final int FUNC_LAST = 1;
+
+  /** The 'position()' id. */
+  public static final int FUNC_POSITION = 2;
+
+  /** The 'count()' id. */
+  public static final int FUNC_COUNT = 3;
+
+  /** The 'id()' id. */
+  public static final int FUNC_ID = 4;
+
+  /** The 'key()' id (XSLT). */
+  public static final int FUNC_KEY = 5;
+
+  /** The 'local-name()' id. */
+  public static final int FUNC_LOCAL_PART = 7;
+
+  /** The 'namespace-uri()' id. */
+  public static final int FUNC_NAMESPACE = 8;
+
+  /** The 'name()' id. */
+  public static final int FUNC_QNAME = 9;
+
+  /** The 'generate-id()' id. */
+  public static final int FUNC_GENERATE_ID = 10;
+
+  /** The 'not()' id. */
+  public static final int FUNC_NOT = 11;
+
+  /** The 'true()' id. */
+  public static final int FUNC_TRUE = 12;
+
+  /** The 'false()' id. */
+  public static final int FUNC_FALSE = 13;
+
+  /** The 'boolean()' id. */
+  public static final int FUNC_BOOLEAN = 14;
+
+  /** The 'number()' id. */
+  public static final int FUNC_NUMBER = 15;
+
+  /** The 'floor()' id. */
+  public static final int FUNC_FLOOR = 16;
+
+  /** The 'ceiling()' id. */
+  public static final int FUNC_CEILING = 17;
+
+  /** The 'round()' id. */
+  public static final int FUNC_ROUND = 18;
+
+  /** The 'sum()' id. */
+  public static final int FUNC_SUM = 19;
+
+  /** The 'string()' id. */
+  public static final int FUNC_STRING = 20;
+
+  /** The 'starts-with()' id. */
+  public static final int FUNC_STARTS_WITH = 21;
+
+  /** The 'contains()' id. */
+  public static final int FUNC_CONTAINS = 22;
+
+  /** The 'substring-before()' id. */
+  public static final int FUNC_SUBSTRING_BEFORE = 23;
+
+  /** The 'substring-after()' id. */
+  public static final int FUNC_SUBSTRING_AFTER = 24;
+
+  /** The 'normalize-space()' id. */
+  public static final int FUNC_NORMALIZE_SPACE = 25;
+
+  /** The 'translate()' id. */
+  public static final int FUNC_TRANSLATE = 26;
+
+  /** The 'concat()' id. */
+  public static final int FUNC_CONCAT = 27;
+
+  /** The 'substring()' id. */
+  public static final int FUNC_SUBSTRING = 29;
+
+  /** The 'string-length()' id. */
+  public static final int FUNC_STRING_LENGTH = 30;
+
+  /** The 'system-property()' id. */
+  public static final int FUNC_SYSTEM_PROPERTY = 31;
+
+  /** The 'lang()' id. */
+  public static final int FUNC_LANG = 32;
+
+  /** The 'function-available()' id (XSLT). */
+  public static final int FUNC_EXT_FUNCTION_AVAILABLE = 33;
+
+  /** The 'element-available()' id (XSLT). */
+  public static final int FUNC_EXT_ELEM_AVAILABLE = 34;
+
+  /** The 'unparsed-entity-uri()' id (XSLT). */
+  public static final int FUNC_UNPARSED_ENTITY_URI = 36;
+
+  // Proprietary
+
+  /** The 'document-location()' id (Proprietary). */
+  public static final int FUNC_DOCLOCATION = 35;
+
+  /**
+   * The function table.
+   */
+  private static Class m_functions[];
+
+  /** Table of function name to function ID associations. */
+  private static HashMap m_functionID = new HashMap();
+    
+  /**
+   * The function table contains customized functions
+   */
+  private Class m_functions_customer[] = new Class[NUM_ALLOWABLE_ADDINS];
+
+  /**
+   * Table of function name to function ID associations for customized functions
+   */
+  private HashMap m_functionID_customer = new HashMap();
+  
+  /**
+   * Number of built in functions.  Be sure to update this as
+   * built-in functions are added.
+   */
+  private static final int NUM_BUILT_IN_FUNCS = 37;
+
+  /**
+   * Number of built-in functions that may be added.
+   */
+  private static final int NUM_ALLOWABLE_ADDINS = 30;
+
+  /**
+   * The index to the next free function index.
+   */
+  private int m_funcNextFreeIndex = NUM_BUILT_IN_FUNCS;
+  
+  static
+  {
+    m_functions = new Class[NUM_BUILT_IN_FUNCS];
+    m_functions[FUNC_CURRENT] = org.apache.xpath.functions.FuncCurrent.class;
+    m_functions[FUNC_LAST] = org.apache.xpath.functions.FuncLast.class;
+    m_functions[FUNC_POSITION] = org.apache.xpath.functions.FuncPosition.class;
+    m_functions[FUNC_COUNT] = org.apache.xpath.functions.FuncCount.class;
+    m_functions[FUNC_ID] = org.apache.xpath.functions.FuncId.class;
+    m_functions[FUNC_KEY] =
+      org.apache.xalan.templates.FuncKey.class;
+    m_functions[FUNC_LOCAL_PART] = 
+      org.apache.xpath.functions.FuncLocalPart.class;
+    m_functions[FUNC_NAMESPACE] = 
+      org.apache.xpath.functions.FuncNamespace.class;
+    m_functions[FUNC_QNAME] = org.apache.xpath.functions.FuncQname.class;
+    m_functions[FUNC_GENERATE_ID] = 
+      org.apache.xpath.functions.FuncGenerateId.class;
+    m_functions[FUNC_NOT] = org.apache.xpath.functions.FuncNot.class;
+    m_functions[FUNC_TRUE] = org.apache.xpath.functions.FuncTrue.class;
+    m_functions[FUNC_FALSE] = org.apache.xpath.functions.FuncFalse.class;
+    m_functions[FUNC_BOOLEAN] = org.apache.xpath.functions.FuncBoolean.class;
+    m_functions[FUNC_LANG] = org.apache.xpath.functions.FuncLang.class;
+    m_functions[FUNC_NUMBER] = org.apache.xpath.functions.FuncNumber.class;
+    m_functions[FUNC_FLOOR] = org.apache.xpath.functions.FuncFloor.class;
+    m_functions[FUNC_CEILING] = org.apache.xpath.functions.FuncCeiling.class;
+    m_functions[FUNC_ROUND] = org.apache.xpath.functions.FuncRound.class;
+    m_functions[FUNC_SUM] = org.apache.xpath.functions.FuncSum.class;
+    m_functions[FUNC_STRING] = org.apache.xpath.functions.FuncString.class;
+    m_functions[FUNC_STARTS_WITH] = 
+      org.apache.xpath.functions.FuncStartsWith.class;
+    m_functions[FUNC_CONTAINS] = org.apache.xpath.functions.FuncContains.class;
+    m_functions[FUNC_SUBSTRING_BEFORE] = 
+      org.apache.xpath.functions.FuncSubstringBefore.class;
+    m_functions[FUNC_SUBSTRING_AFTER] = 
+      org.apache.xpath.functions.FuncSubstringAfter.class;
+    m_functions[FUNC_NORMALIZE_SPACE] = 
+      org.apache.xpath.functions.FuncNormalizeSpace.class;
+    m_functions[FUNC_TRANSLATE] = 
+      org.apache.xpath.functions.FuncTranslate.class;
+    m_functions[FUNC_CONCAT] = org.apache.xpath.functions.FuncConcat.class;
+    m_functions[FUNC_SYSTEM_PROPERTY] = 
+      org.apache.xpath.functions.FuncSystemProperty.class;
+    m_functions[FUNC_EXT_FUNCTION_AVAILABLE] =
+      org.apache.xpath.functions.FuncExtFunctionAvailable.class;
+    m_functions[FUNC_EXT_ELEM_AVAILABLE] =
+      org.apache.xpath.functions.FuncExtElementAvailable.class;
+    m_functions[FUNC_SUBSTRING] = 
+      org.apache.xpath.functions.FuncSubstring.class;
+    m_functions[FUNC_STRING_LENGTH] = 
+      org.apache.xpath.functions.FuncStringLength.class;
+    m_functions[FUNC_DOCLOCATION] = 
+      org.apache.xpath.functions.FuncDoclocation.class;
+    m_functions[FUNC_UNPARSED_ENTITY_URI] =
+      org.apache.xpath.functions.FuncUnparsedEntityURI.class;
+  }
+
+  static{
+          m_functionID.put(Keywords.FUNC_CURRENT_STRING,
+                          new Integer(FunctionTable.FUNC_CURRENT));
+          m_functionID.put(Keywords.FUNC_LAST_STRING,
+                          new Integer(FunctionTable.FUNC_LAST));
+          m_functionID.put(Keywords.FUNC_POSITION_STRING,
+                          new Integer(FunctionTable.FUNC_POSITION));
+          m_functionID.put(Keywords.FUNC_COUNT_STRING,
+                          new Integer(FunctionTable.FUNC_COUNT));
+          m_functionID.put(Keywords.FUNC_ID_STRING,
+                          new Integer(FunctionTable.FUNC_ID));
+          m_functionID.put(Keywords.FUNC_KEY_STRING,
+                          new Integer(FunctionTable.FUNC_KEY));
+          m_functionID.put(Keywords.FUNC_LOCAL_PART_STRING,
+                          new Integer(FunctionTable.FUNC_LOCAL_PART));
+          m_functionID.put(Keywords.FUNC_NAMESPACE_STRING,
+                          new Integer(FunctionTable.FUNC_NAMESPACE));
+          m_functionID.put(Keywords.FUNC_NAME_STRING,
+                          new Integer(FunctionTable.FUNC_QNAME));
+          m_functionID.put(Keywords.FUNC_GENERATE_ID_STRING,
+                          new Integer(FunctionTable.FUNC_GENERATE_ID));
+          m_functionID.put(Keywords.FUNC_NOT_STRING,
+                          new Integer(FunctionTable.FUNC_NOT));
+          m_functionID.put(Keywords.FUNC_TRUE_STRING,
+                          new Integer(FunctionTable.FUNC_TRUE));
+          m_functionID.put(Keywords.FUNC_FALSE_STRING,
+                          new Integer(FunctionTable.FUNC_FALSE));
+          m_functionID.put(Keywords.FUNC_BOOLEAN_STRING,
+                          new Integer(FunctionTable.FUNC_BOOLEAN));
+          m_functionID.put(Keywords.FUNC_LANG_STRING,
+                          new Integer(FunctionTable.FUNC_LANG));
+          m_functionID.put(Keywords.FUNC_NUMBER_STRING,
+                          new Integer(FunctionTable.FUNC_NUMBER));
+          m_functionID.put(Keywords.FUNC_FLOOR_STRING,
+                          new Integer(FunctionTable.FUNC_FLOOR));
+          m_functionID.put(Keywords.FUNC_CEILING_STRING,
+                          new Integer(FunctionTable.FUNC_CEILING));
+          m_functionID.put(Keywords.FUNC_ROUND_STRING,
+                          new Integer(FunctionTable.FUNC_ROUND));
+          m_functionID.put(Keywords.FUNC_SUM_STRING,
+                          new Integer(FunctionTable.FUNC_SUM));
+          m_functionID.put(Keywords.FUNC_STRING_STRING,
+                          new Integer(FunctionTable.FUNC_STRING));
+          m_functionID.put(Keywords.FUNC_STARTS_WITH_STRING,
+                          new Integer(FunctionTable.FUNC_STARTS_WITH));
+          m_functionID.put(Keywords.FUNC_CONTAINS_STRING,
+                          new Integer(FunctionTable.FUNC_CONTAINS));
+          m_functionID.put(Keywords.FUNC_SUBSTRING_BEFORE_STRING,
+                          new Integer(FunctionTable.FUNC_SUBSTRING_BEFORE));
+          m_functionID.put(Keywords.FUNC_SUBSTRING_AFTER_STRING,
+                          new Integer(FunctionTable.FUNC_SUBSTRING_AFTER));
+          m_functionID.put(Keywords.FUNC_NORMALIZE_SPACE_STRING,
+                          new Integer(FunctionTable.FUNC_NORMALIZE_SPACE));
+          m_functionID.put(Keywords.FUNC_TRANSLATE_STRING,
+                          new Integer(FunctionTable.FUNC_TRANSLATE));
+          m_functionID.put(Keywords.FUNC_CONCAT_STRING,
+                          new Integer(FunctionTable.FUNC_CONCAT));
+          m_functionID.put(Keywords.FUNC_SYSTEM_PROPERTY_STRING,
+                          new Integer(FunctionTable.FUNC_SYSTEM_PROPERTY));
+          m_functionID.put(Keywords.FUNC_EXT_FUNCTION_AVAILABLE_STRING,
+                        new Integer(FunctionTable.FUNC_EXT_FUNCTION_AVAILABLE));
+          m_functionID.put(Keywords.FUNC_EXT_ELEM_AVAILABLE_STRING,
+                          new Integer(FunctionTable.FUNC_EXT_ELEM_AVAILABLE));
+          m_functionID.put(Keywords.FUNC_SUBSTRING_STRING,
+                          new Integer(FunctionTable.FUNC_SUBSTRING));
+          m_functionID.put(Keywords.FUNC_STRING_LENGTH_STRING,
+                          new Integer(FunctionTable.FUNC_STRING_LENGTH));
+          m_functionID.put(Keywords.FUNC_UNPARSED_ENTITY_URI_STRING,
+                          new Integer(FunctionTable.FUNC_UNPARSED_ENTITY_URI));
+          m_functionID.put(Keywords.FUNC_DOCLOCATION_STRING,
+                          new Integer(FunctionTable.FUNC_DOCLOCATION));          
+  }
+  
+  public FunctionTable(){
+  }
+  
+  /**
+   * Return the name of the a function in the static table. Needed to avoid
+   * making the table publicly available.
+   */
+  String getFunctionName(int funcID) {
+      if (funcID < NUM_BUILT_IN_FUNCS) return m_functions[funcID].getName();
+      else return m_functions_customer[funcID - NUM_BUILT_IN_FUNCS].getName();
+  }
+
+  /**
+   * Obtain a new Function object from a function ID.
+   *
+   * @param which  The function ID, which may correspond to one of the FUNC_XXX 
+   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
+   *    be a value installed by an external module. 
+   *
+   * @return a a new Function instance.
+   *
+   * @throws javax.xml.transform.TransformerException if ClassNotFoundException, 
+   *    IllegalAccessException, or InstantiationException is thrown.
+   */
+  Function getFunction(int which)
+          throws javax.xml.transform.TransformerException
+  {
+          try{
+              if (which < NUM_BUILT_IN_FUNCS) 
+                  return (Function) m_functions[which].newInstance();
+              else 
+                  return (Function) m_functions_customer[
+                      which-NUM_BUILT_IN_FUNCS].newInstance();                  
+          }catch (IllegalAccessException ex){
+                  throw new TransformerException(ex.getMessage());
+          }catch (InstantiationException ex){
+                  throw new TransformerException(ex.getMessage());
+          }
+  }
+  
+  /**
+   * Obtain a function ID from a given function name
+   * @param key the function name in a java.lang.String format.
+   * @return a function ID, which may correspond to one of the FUNC_XXX values
+   * found in {@link org.apache.xpath.compiler.FunctionTable}, but may be a 
+   * value installed by an external module.
+   */
+  Object getFunctionID(String key){
+          Object id = m_functionID_customer.get(key);
+          if (null == id) id = m_functionID.get(key);
+          return id;
+  }
+  
+  /**
+   * Install a built-in function.
+   * @param name The unqualified name of the function, must not be null
+   * @param func A Implementation of an XPath Function object.
+   * @return the position of the function in the internal index.
+   */
+  public int installFunction(String name, Class func)
+  {
+
+    int funcIndex;
+    Object funcIndexObj = getFunctionID(name);
+
+    if (null != funcIndexObj)
+    {
+      funcIndex = ((Integer) funcIndexObj).intValue();
+      
+      if (funcIndex < NUM_BUILT_IN_FUNCS){
+              funcIndex = m_funcNextFreeIndex++;
+              m_functionID_customer.put(name, new Integer(funcIndex)); 
+      }
+      m_functions_customer[funcIndex - NUM_BUILT_IN_FUNCS] = func;          
+    }
+    else
+    {
+            funcIndex = m_funcNextFreeIndex++;
+                          
+            m_functions_customer[funcIndex-NUM_BUILT_IN_FUNCS] = func;
+                    
+            m_functionID_customer.put(name, 
+                new Integer(funcIndex));   
+    }
+    return funcIndex;
+  }
+
+  /**
+   * Tell if a built-in, non-namespaced function is available.
+   *
+   * @param methName The local name of the function.
+   *
+   * @return True if the function can be executed.
+   */
+  public boolean functionAvailable(String methName)
+  {
+      Object tblEntry = m_functionID.get(methName);
+      if (null != tblEntry) return true;
+      else{
+              tblEntry = m_functionID_customer.get(methName);
+              return (null != tblEntry)? true : false;
+      }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/compiler/Keywords.java b/src/main/java/org/apache/xpath/compiler/Keywords.java
new file mode 100644
index 0000000..b624a87
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/Keywords.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Keywords.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+import java.util.Hashtable;
+
+/**
+ * Table of strings to operation code lookups.
+ * @xsl.usage internal
+ */
+public class Keywords
+{
+
+  /** Table of keywords to opcode associations. */
+  private static Hashtable m_keywords = new Hashtable();
+
+  /** Table of axes names to opcode associations. */
+  private static Hashtable m_axisnames = new Hashtable();
+
+  /** Table of function name to function ID associations. */
+  private static Hashtable m_nodetests = new Hashtable();
+
+  /** Table of node type strings to opcode associations. */
+  private static Hashtable m_nodetypes = new Hashtable();
+
+  /** ancestor axes string. */
+  private static final String FROM_ANCESTORS_STRING = "ancestor";
+
+  /** ancestor-or-self axes string. */
+  private static final String FROM_ANCESTORS_OR_SELF_STRING =
+    "ancestor-or-self";
+
+  /** attribute axes string. */
+  private static final String FROM_ATTRIBUTES_STRING = "attribute";
+
+  /** child axes string. */
+  private static final String FROM_CHILDREN_STRING = "child";
+
+  /** descendant-or-self axes string. */
+  private static final String FROM_DESCENDANTS_STRING = "descendant";
+
+  /** ancestor axes string. */
+  private static final String FROM_DESCENDANTS_OR_SELF_STRING =
+    "descendant-or-self";
+
+  /** following axes string. */
+  private static final String FROM_FOLLOWING_STRING = "following";
+
+  /** following-sibling axes string. */
+  private static final String FROM_FOLLOWING_SIBLINGS_STRING =
+    "following-sibling";
+
+  /** parent axes string. */
+  private static final String FROM_PARENT_STRING = "parent";
+
+  /** preceding axes string. */
+  private static final String FROM_PRECEDING_STRING = "preceding";
+
+  /** preceding-sibling axes string. */
+  private static final String FROM_PRECEDING_SIBLINGS_STRING =
+    "preceding-sibling";
+
+  /** self axes string. */
+  private static final String FROM_SELF_STRING = "self";
+
+  /** namespace axes string. */
+  private static final String FROM_NAMESPACE_STRING = "namespace";
+
+  /** self axes abreviated string. */
+  private static final String FROM_SELF_ABBREVIATED_STRING = ".";
+
+  /** comment node test string. */
+  private static final String NODETYPE_COMMENT_STRING = "comment";
+
+  /** text node test string. */
+  private static final String NODETYPE_TEXT_STRING = "text";
+
+  /** processing-instruction node test string. */
+  private static final String NODETYPE_PI_STRING = "processing-instruction";
+
+  /** Any node test string. */
+  private static final String NODETYPE_NODE_STRING = "node";
+
+  /** Wildcard element string. */
+  private static final String NODETYPE_ANYELEMENT_STRING = "*";
+
+  /** current function string. */
+  public static final String FUNC_CURRENT_STRING = "current";
+
+  /** last function string. */
+  public static final String FUNC_LAST_STRING = "last";
+
+  /** position function string. */
+  public static final String FUNC_POSITION_STRING = "position";
+
+  /** count function string. */
+  public static final String FUNC_COUNT_STRING = "count";
+
+  /** id function string. */
+  static final String FUNC_ID_STRING = "id";
+
+  /** key function string (XSLT). */
+  public static final String FUNC_KEY_STRING = "key";
+
+  /** local-name function string. */
+  public static final String FUNC_LOCAL_PART_STRING = "local-name";
+
+  /** namespace-uri function string. */
+  public static final String FUNC_NAMESPACE_STRING = "namespace-uri";
+
+  /** name function string. */
+  public static final String FUNC_NAME_STRING = "name";
+
+  /** generate-id function string (XSLT). */
+  public static final String FUNC_GENERATE_ID_STRING = "generate-id";
+
+  /** not function string. */
+  public static final String FUNC_NOT_STRING = "not";
+
+  /** true function string. */
+  public static final String FUNC_TRUE_STRING = "true";
+
+  /** false function string. */
+  public static final String FUNC_FALSE_STRING = "false";
+
+  /** boolean function string. */
+  public static final String FUNC_BOOLEAN_STRING = "boolean";
+
+  /** lang function string. */
+  public static final String FUNC_LANG_STRING = "lang";
+
+  /** number function string. */
+  public static final String FUNC_NUMBER_STRING = "number";
+
+  /** floor function string. */
+  public static final String FUNC_FLOOR_STRING = "floor";
+
+  /** ceiling function string. */
+  public static final String FUNC_CEILING_STRING = "ceiling";
+
+  /** round function string. */
+  public static final String FUNC_ROUND_STRING = "round";
+
+  /** sum function string. */
+  public static final String FUNC_SUM_STRING = "sum";
+
+  /** string function string. */
+  public static final String FUNC_STRING_STRING = "string";
+
+  /** starts-with function string. */
+  public static final String FUNC_STARTS_WITH_STRING = "starts-with";
+
+  /** contains function string. */
+  public static final String FUNC_CONTAINS_STRING = "contains";
+
+  /** substring-before function string. */
+  public static final String FUNC_SUBSTRING_BEFORE_STRING =
+    "substring-before";
+
+  /** substring-after function string. */
+  public static final String FUNC_SUBSTRING_AFTER_STRING = "substring-after";
+
+  /** normalize-space function string. */
+  public static final String FUNC_NORMALIZE_SPACE_STRING = "normalize-space";
+
+  /** translate function string. */
+  public static final String FUNC_TRANSLATE_STRING = "translate";
+
+  /** concat function string. */
+  public static final String FUNC_CONCAT_STRING = "concat";
+
+  /** system-property function string. */
+  public static final String FUNC_SYSTEM_PROPERTY_STRING = "system-property";
+
+  /** function-available function string (XSLT). */
+  public static final String FUNC_EXT_FUNCTION_AVAILABLE_STRING =
+    "function-available";
+
+  /** element-available function string (XSLT). */
+  public static final String FUNC_EXT_ELEM_AVAILABLE_STRING =
+    "element-available";
+
+  /** substring function string. */
+  public static final String FUNC_SUBSTRING_STRING = "substring";
+
+  /** string-length function string. */
+  public static final String FUNC_STRING_LENGTH_STRING = "string-length";
+
+  /** unparsed-entity-uri function string (XSLT). */
+  public static final String FUNC_UNPARSED_ENTITY_URI_STRING =
+    "unparsed-entity-uri";
+
+  // Proprietary, built in functions
+
+  /** current function string (Proprietary). */
+  public static final String FUNC_DOCLOCATION_STRING = "document-location";
+
+  static
+  {
+    m_axisnames.put(FROM_ANCESTORS_STRING,
+                    new Integer(OpCodes.FROM_ANCESTORS));
+    m_axisnames.put(FROM_ANCESTORS_OR_SELF_STRING,
+                    new Integer(OpCodes.FROM_ANCESTORS_OR_SELF));
+    m_axisnames.put(FROM_ATTRIBUTES_STRING,
+                    new Integer(OpCodes.FROM_ATTRIBUTES));
+    m_axisnames.put(FROM_CHILDREN_STRING,
+                    new Integer(OpCodes.FROM_CHILDREN));
+    m_axisnames.put(FROM_DESCENDANTS_STRING,
+                    new Integer(OpCodes.FROM_DESCENDANTS));
+    m_axisnames.put(FROM_DESCENDANTS_OR_SELF_STRING,
+                    new Integer(OpCodes.FROM_DESCENDANTS_OR_SELF));
+    m_axisnames.put(FROM_FOLLOWING_STRING,
+                    new Integer(OpCodes.FROM_FOLLOWING));
+    m_axisnames.put(FROM_FOLLOWING_SIBLINGS_STRING,
+                    new Integer(OpCodes.FROM_FOLLOWING_SIBLINGS));
+    m_axisnames.put(FROM_PARENT_STRING,
+                    new Integer(OpCodes.FROM_PARENT));
+    m_axisnames.put(FROM_PRECEDING_STRING,
+                    new Integer(OpCodes.FROM_PRECEDING));
+    m_axisnames.put(FROM_PRECEDING_SIBLINGS_STRING,
+                    new Integer(OpCodes.FROM_PRECEDING_SIBLINGS));
+    m_axisnames.put(FROM_SELF_STRING,
+                    new Integer(OpCodes.FROM_SELF));
+    m_axisnames.put(FROM_NAMESPACE_STRING,
+                    new Integer(OpCodes.FROM_NAMESPACE));
+    m_nodetypes.put(NODETYPE_COMMENT_STRING,
+                    new Integer(OpCodes.NODETYPE_COMMENT));
+    m_nodetypes.put(NODETYPE_TEXT_STRING,
+                    new Integer(OpCodes.NODETYPE_TEXT));
+    m_nodetypes.put(NODETYPE_PI_STRING,
+                    new Integer(OpCodes.NODETYPE_PI));
+    m_nodetypes.put(NODETYPE_NODE_STRING,
+                    new Integer(OpCodes.NODETYPE_NODE));
+    m_nodetypes.put(NODETYPE_ANYELEMENT_STRING,
+                    new Integer(OpCodes.NODETYPE_ANYELEMENT));
+    m_keywords.put(FROM_SELF_ABBREVIATED_STRING,
+                   new Integer(OpCodes.FROM_SELF));
+    m_keywords.put(FUNC_ID_STRING,
+                   new Integer(FunctionTable.FUNC_ID));
+    m_keywords.put(FUNC_KEY_STRING,
+                   new Integer(FunctionTable.FUNC_KEY));
+
+    m_nodetests.put(NODETYPE_COMMENT_STRING,
+                    new Integer(OpCodes.NODETYPE_COMMENT));
+    m_nodetests.put(NODETYPE_TEXT_STRING,
+                    new Integer(OpCodes.NODETYPE_TEXT));
+    m_nodetests.put(NODETYPE_PI_STRING,
+                    new Integer(OpCodes.NODETYPE_PI));
+    m_nodetests.put(NODETYPE_NODE_STRING,
+                    new Integer(OpCodes.NODETYPE_NODE));
+  }
+  
+  static Object getAxisName(String key){
+          return m_axisnames.get(key);
+  }
+  
+  static Object lookupNodeTest(String key){
+          return m_nodetests.get(key);
+  }
+  
+  static Object getKeyWord(String key){
+          return m_keywords.get(key);
+  }
+  
+  static Object getNodeType(String key){
+          return m_nodetypes.get(key);
+  }      
+}
diff --git a/src/main/java/org/apache/xpath/compiler/Lexer.java b/src/main/java/org/apache/xpath/compiler/Lexer.java
new file mode 100644
index 0000000..008ac43
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/Lexer.java
@@ -0,0 +1,669 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Lexer.java 524810 2007-04-02 15:51:55Z zongaro $
+ */
+package org.apache.xpath.compiler;
+
+import java.util.Vector;
+
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class is in charge of lexical processing of the XPath
+ * expression into tokens.
+ */
+class Lexer
+{
+
+  /**
+   * The target XPath.
+   */
+  private Compiler m_compiler;
+
+  /**
+   * The prefix resolver to map prefixes to namespaces in the XPath.
+   */
+  PrefixResolver m_namespaceContext;
+
+  /**
+   * The XPath processor object.
+   */
+  XPathParser m_processor;
+
+  /**
+   * This value is added to each element name in the TARGETEXTRA
+   * that is a 'target' (right-most top-level element name).
+   */
+  static final int TARGETEXTRA = 10000;
+
+  /**
+   * Ignore this, it is going away.
+   * This holds a map to the m_tokenQueue that tells where the top-level elements are.
+   * It is used for pattern matching so the m_tokenQueue can be walked backwards.
+   * Each element that is a 'target', (right-most top level element name) has
+   * TARGETEXTRA added to it.
+   *
+   */
+  private int m_patternMap[] = new int[100];
+
+  /**
+   * Ignore this, it is going away.
+   * The number of elements that m_patternMap maps;
+   */
+  private int m_patternMapSize;
+
+  /**
+   * Create a Lexer object.
+   *
+   * @param compiler The owning compiler for this lexer.
+   * @param resolver The prefix resolver for mapping qualified name prefixes 
+   *                 to namespace URIs.
+   * @param xpathProcessor The parser that is processing strings to opcodes.
+   */
+  Lexer(Compiler compiler, PrefixResolver resolver,
+        XPathParser xpathProcessor)
+  {
+
+    m_compiler = compiler;
+    m_namespaceContext = resolver;
+    m_processor = xpathProcessor;
+  }
+
+  /**
+   * Walk through the expression and build a token queue, and a map of the top-level
+   * elements.
+   * @param pat XSLT Expression.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  void tokenize(String pat) throws javax.xml.transform.TransformerException
+  {
+    tokenize(pat, null);
+  }
+
+  /**
+   * Walk through the expression and build a token queue, and a map of the top-level
+   * elements.
+   * @param pat XSLT Expression.
+   * @param targetStrings Vector to hold Strings, may be null.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  void tokenize(String pat, Vector targetStrings)
+          throws javax.xml.transform.TransformerException
+  {
+
+    m_compiler.m_currentPattern = pat;
+    m_patternMapSize = 0; 
+
+    // This needs to grow too.  Use a conservative estimate that the OpMapVector
+    // needs about five time the length of the input path expression - to a
+    // maximum of MAXTOKENQUEUESIZE*5.  If the OpMapVector needs to grow, grow
+    // it freely (second argument to constructor).
+    int initTokQueueSize = ((pat.length() < OpMap.MAXTOKENQUEUESIZE)
+                                 ? pat.length() :  OpMap.MAXTOKENQUEUESIZE) * 5;
+    m_compiler.m_opMap = new OpMapVector(initTokQueueSize,
+                                         OpMap.BLOCKTOKENQUEUESIZE * 5,
+                                         OpMap.MAPINDEX_LENGTH);
+
+    int nChars = pat.length();
+    int startSubstring = -1; 
+    int posOfNSSep = -1;
+    boolean isStartOfPat = true;
+    boolean isAttrName = false;
+    boolean isNum = false;
+
+    // Nesting of '[' so we can know if the given element should be
+    // counted inside the m_patternMap.
+    int nesting = 0;
+
+    // char[] chars = pat.toCharArray();
+    for (int i = 0; i < nChars; i++)
+    {
+      char c = pat.charAt(i);
+
+      switch (c)
+      {
+      case '\"' :
+      {
+        if (startSubstring != -1)
+        {
+          isNum = false;
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+          isAttrName = false;
+
+          if (-1 != posOfNSSep)
+          {
+            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
+          }
+          else
+          {
+            addToTokenQueue(pat.substring(startSubstring, i));
+          }
+        }
+
+        startSubstring = i;
+
+        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\"'); i++);
+
+        if (c == '\"' && i < nChars)
+        {
+          addToTokenQueue(pat.substring(startSubstring, i + 1));
+
+          startSubstring = -1;
+        }
+        else
+        {
+          m_processor.error(XPATHErrorResources.ER_EXPECTED_DOUBLE_QUOTE,
+                            null);  //"misquoted literal... expected double quote!");
+        }
+      }
+      break;
+      case '\'' :
+        if (startSubstring != -1)
+        {
+          isNum = false;
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+          isAttrName = false;
+
+          if (-1 != posOfNSSep)
+          {
+            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
+          }
+          else
+          {
+            addToTokenQueue(pat.substring(startSubstring, i));
+          }
+        }
+
+        startSubstring = i;
+
+        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\''); i++);
+
+        if (c == '\'' && i < nChars)
+        {
+          addToTokenQueue(pat.substring(startSubstring, i + 1));
+
+          startSubstring = -1;
+        }
+        else
+        {
+          m_processor.error(XPATHErrorResources.ER_EXPECTED_SINGLE_QUOTE,
+                            null);  //"misquoted literal... expected single quote!");
+        }
+        break;
+      case 0x0A :
+      case 0x0D :
+      case ' ' :
+      case '\t' :
+        if (startSubstring != -1)
+        {
+          isNum = false;
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+          isAttrName = false;
+
+          if (-1 != posOfNSSep)
+          {
+            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
+          }
+          else
+          {
+            addToTokenQueue(pat.substring(startSubstring, i));
+          }
+
+          startSubstring = -1;
+        }
+        break;
+      case '@' :
+        isAttrName = true;
+
+      // fall-through on purpose
+      case '-' :
+        if ('-' == c)
+        {
+          if (!(isNum || (startSubstring == -1)))
+          {
+            break;
+          }
+
+          isNum = false;
+        }
+
+      // fall-through on purpose
+      case '(' :
+      case '[' :
+      case ')' :
+      case ']' :
+      case '|' :
+      case '/' :
+      case '*' :
+      case '+' :
+      case '=' :
+      case ',' :
+      case '\\' :  // Unused at the moment
+      case '^' :  // Unused at the moment
+      case '!' :  // Unused at the moment
+      case '$' :
+      case '<' :
+      case '>' :
+        if (startSubstring != -1)
+        {
+          isNum = false;
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+          isAttrName = false;
+
+          if (-1 != posOfNSSep)
+          {
+            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
+          }
+          else
+          {
+            addToTokenQueue(pat.substring(startSubstring, i));
+          }
+
+          startSubstring = -1;
+        }
+        else if (('/' == c) && isStartOfPat)
+        {
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+        }
+        else if ('*' == c)
+        {
+          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+          isAttrName = false;
+        }
+
+        if (0 == nesting)
+        {
+          if ('|' == c)
+          {
+            if (null != targetStrings)
+            {
+              recordTokenString(targetStrings);
+            }
+
+            isStartOfPat = true;
+          }
+        }
+
+        if ((')' == c) || (']' == c))
+        {
+          nesting--;
+        }
+        else if (('(' == c) || ('[' == c))
+        {
+          nesting++;
+        }
+
+        addToTokenQueue(pat.substring(i, i + 1));
+        break;
+      case ':' :
+        if (i>0)
+        {
+          if (posOfNSSep == (i - 1))
+          {
+            if (startSubstring != -1)
+            {
+              if (startSubstring < (i - 1))
+                addToTokenQueue(pat.substring(startSubstring, i - 1));
+            }
+
+            isNum = false;
+            isAttrName = false;
+            startSubstring = -1;
+            posOfNSSep = -1;
+
+            addToTokenQueue(pat.substring(i - 1, i + 1));
+
+            break;
+          }
+          else
+          {
+            posOfNSSep = i;
+          }
+        }
+
+      // fall through on purpose
+      default :
+        if (-1 == startSubstring)
+        {
+          startSubstring = i;
+          isNum = Character.isDigit(c);
+        }
+        else if (isNum)
+        {
+          isNum = Character.isDigit(c);
+        }
+      }
+    }
+
+    if (startSubstring != -1)
+    {
+      isNum = false;
+      isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
+
+      if ((-1 != posOfNSSep) || 
+         ((m_namespaceContext != null) && (m_namespaceContext.handlesNullPrefixes())))
+      {
+        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, nChars);
+      }
+      else
+      {
+        addToTokenQueue(pat.substring(startSubstring, nChars));
+      }
+    }
+
+    if (0 == m_compiler.getTokenQueueSize())
+    {
+      m_processor.error(XPATHErrorResources.ER_EMPTY_EXPRESSION, null);  //"Empty expression!");
+    }
+    else if (null != targetStrings)
+    {
+      recordTokenString(targetStrings);
+    }
+
+    m_processor.m_queueMark = 0;
+  }
+
+  /**
+   * Record the current position on the token queue as long as
+   * this is a top-level element.  Must be called before the
+   * next token is added to the m_tokenQueue.
+   *
+   * @param nesting The nesting count for the pattern element.
+   * @param isStart true if this is the start of a pattern.
+   * @param isAttrName true if we have determined that this is an attribute name.
+   *
+   * @return true if this is the start of a pattern.
+   */
+  private boolean mapPatternElemPos(int nesting, boolean isStart,
+                                    boolean isAttrName)
+  {
+
+    if (0 == nesting)
+    {
+      if(m_patternMapSize >= m_patternMap.length)
+      {
+        int patternMap[] = m_patternMap;
+        int len = m_patternMap.length;
+        m_patternMap = new int[m_patternMapSize + 100];
+        System.arraycopy(patternMap, 0, m_patternMap, 0, len);
+      } 
+      if (!isStart)
+      {
+        m_patternMap[m_patternMapSize - 1] -= TARGETEXTRA;
+      }
+      m_patternMap[m_patternMapSize] =
+        (m_compiler.getTokenQueueSize() - (isAttrName ? 1 : 0)) + TARGETEXTRA;
+
+      m_patternMapSize++;
+
+      isStart = false;
+    }
+
+    return isStart;
+  }
+
+  /**
+   * Given a map pos, return the corresponding token queue pos.
+   *
+   * @param i The index in the m_patternMap.
+   *
+   * @return the token queue position.
+   */
+  private int getTokenQueuePosFromMap(int i)
+  {
+
+    int pos = m_patternMap[i];
+
+    return (pos >= TARGETEXTRA) ? (pos - TARGETEXTRA) : pos;
+  }
+
+  /**
+   * Reset token queue mark and m_token to a
+   * given position.
+   * @param mark The new position.
+   */
+  private final void resetTokenMark(int mark)
+  {
+
+    int qsz = m_compiler.getTokenQueueSize();
+
+    m_processor.m_queueMark = (mark > 0)
+                              ? ((mark <= qsz) ? mark - 1 : mark) : 0;
+
+    if (m_processor.m_queueMark < qsz)
+    {
+      m_processor.m_token =
+        (String) m_compiler.getTokenQueue().elementAt(m_processor.m_queueMark++);
+      m_processor.m_tokenChar = m_processor.m_token.charAt(0);
+    }
+    else
+    {
+      m_processor.m_token = null;
+      m_processor.m_tokenChar = 0;
+    }
+  }
+
+  /**
+   * Given a string, return the corresponding keyword token.
+   *
+   * @param key The keyword.
+   *
+   * @return An opcode value.
+   */
+  final int getKeywordToken(String key)
+  {
+
+    int tok;
+
+    try
+    {
+      Integer itok = (Integer) Keywords.getKeyWord(key);
+
+      tok = (null != itok) ? itok.intValue() : 0;
+    }
+    catch (NullPointerException npe)
+    {
+      tok = 0;
+    }
+    catch (ClassCastException cce)
+    {
+      tok = 0;
+    }
+
+    return tok;
+  }
+
+  /**
+   * Record the current token in the passed vector.
+   *
+   * @param targetStrings Vector of string.
+   */
+  private void recordTokenString(Vector targetStrings)
+  {
+
+    int tokPos = getTokenQueuePosFromMap(m_patternMapSize - 1);
+
+    resetTokenMark(tokPos + 1);
+
+    if (m_processor.lookahead('(', 1))
+    {
+      int tok = getKeywordToken(m_processor.m_token);
+
+      switch (tok)
+      {
+      case OpCodes.NODETYPE_COMMENT :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_COMMENT);
+        break;
+      case OpCodes.NODETYPE_TEXT :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_TEXT);
+        break;
+      case OpCodes.NODETYPE_NODE :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
+        break;
+      case OpCodes.NODETYPE_ROOT :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_ROOT);
+        break;
+      case OpCodes.NODETYPE_ANYELEMENT :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
+        break;
+      case OpCodes.NODETYPE_PI :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
+        break;
+      default :
+        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
+      }
+    }
+    else
+    {
+      if (m_processor.tokenIs('@'))
+      {
+        tokPos++;
+
+        resetTokenMark(tokPos + 1);
+      }
+
+      if (m_processor.lookahead(':', 1))
+      {
+        tokPos += 2;
+      }
+
+      targetStrings.addElement(m_compiler.getTokenQueue().elementAt(tokPos));
+    }
+  }
+
+  /**
+   * Add a token to the token queue.
+   *
+   *
+   * @param s The token.
+   */
+  private final void addToTokenQueue(String s)
+  {
+    m_compiler.getTokenQueue().addElement(s);
+  }
+
+  /**
+   * When a seperator token is found, see if there's a element name or
+   * the like to map.
+   *
+   * @param pat The XPath name string.
+   * @param startSubstring The start of the name string.
+   * @param posOfNSSep The position of the namespace seperator (':').
+   * @param posOfScan The end of the name index.
+   *
+   * @throws javax.xml.transform.TransformerException
+   *
+   * @return -1 always.
+   */
+  private int mapNSTokens(String pat, int startSubstring, int posOfNSSep,
+                          int posOfScan)
+           throws javax.xml.transform.TransformerException
+ {
+
+    String prefix = "";
+    
+    if ((startSubstring >= 0) && (posOfNSSep >= 0))
+    {
+       prefix = pat.substring(startSubstring, posOfNSSep);
+    }
+    String uName;
+
+    if ((null != m_namespaceContext) &&!prefix.equals("*")
+            &&!prefix.equals("xmlns"))
+    {
+      try
+      {
+        if (prefix.length() > 0)
+          uName = ((PrefixResolver) m_namespaceContext).getNamespaceForPrefix(
+            prefix);
+        else
+        {
+
+          // Assume last was wildcard. This is not legal according
+          // to the draft. Set the below to true to make namespace
+          // wildcards work.
+          if (false)
+          {
+            addToTokenQueue(":");
+
+            String s = pat.substring(posOfNSSep + 1, posOfScan);
+
+            if (s.length() > 0)
+              addToTokenQueue(s);
+
+            return -1;
+          }
+          else
+          {
+            uName =
+              ((PrefixResolver) m_namespaceContext).getNamespaceForPrefix(
+                prefix);
+          }
+        }
+      }
+      catch (ClassCastException cce)
+      {
+        uName = m_namespaceContext.getNamespaceForPrefix(prefix);
+      }
+    }
+    else
+    {
+      uName = prefix;
+    }
+
+    if ((null != uName) && (uName.length() > 0))
+    {
+      addToTokenQueue(uName);
+      addToTokenQueue(":");
+
+      String s = pat.substring(posOfNSSep + 1, posOfScan);
+
+      if (s.length() > 0)
+        addToTokenQueue(s);
+    }
+    else
+    {
+        // To older XPath code it doesn't matter if
+        // error() is called or errorForDOM3().
+		m_processor.errorForDOM3(XPATHErrorResources.ER_PREFIX_MUST_RESOLVE,
+						 new String[] {prefix});  //"Prefix must resolve to a namespace: {0}";
+
+/** old code commented out 17-Sep-2004
+// error("Could not locate namespace for prefix: "+prefix);
+//		  m_processor.error(XPATHErrorResources.ER_PREFIX_MUST_RESOLVE,
+//					 new String[] {prefix});  //"Prefix must resolve to a namespace: {0}";
+*/
+
+      /***  Old code commented out 10-Jan-2001
+      addToTokenQueue(prefix);
+      addToTokenQueue(":");
+
+      String s = pat.substring(posOfNSSep + 1, posOfScan);
+
+      if (s.length() > 0)
+        addToTokenQueue(s);
+      ***/
+    }
+
+    return -1;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/compiler/OpCodes.java b/src/main/java/org/apache/xpath/compiler/OpCodes.java
new file mode 100644
index 0000000..04bb958
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/OpCodes.java
@@ -0,0 +1,632 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OpCodes.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+/**
+ * Operations codes for XPath.
+ *
+ * Code for the descriptions of the operations codes:
+ * [UPPER CASE] indicates a literal value,
+ * [lower case] is a description of a value,
+ *      ([length] always indicates the length of the operation,
+ *       including the operations code and the length integer.)
+ * {UPPER CASE} indicates the given production,
+ * {description} is the description of a new production,
+ *      (For instance, {boolean expression} means some expression
+ *       that should be resolved to a boolean.)
+ *  * means that it occurs zero or more times,
+ *  + means that it occurs one or more times,
+ *  ? means that it is optional.
+ *
+ * returns: indicates what the production should return.
+ */
+public class OpCodes
+{
+
+  /**
+   * [ENDOP]
+   * Some operators may like to have a terminator.
+   * @xsl.usage advanced
+   */
+  public static final int ENDOP = -1;
+
+  /**
+   * [EMPTY]
+   * Empty slot to indicate NULL.
+   */
+  public static final int EMPTY = -2;
+
+  /**
+   * [ELEMWILDCARD]
+   * Means ELEMWILDCARD ("*"), used instead
+   * of string index in some places.
+   * @xsl.usage advanced
+   */
+  public static final int ELEMWILDCARD = -3;
+
+  /**
+   * [OP_XPATH]
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XNodeSet
+   *  XNumber
+   *  XString
+   *  XBoolean
+   *  XRTree
+   *  XObject
+   * @xsl.usage advanced
+   */
+  public static final int OP_XPATH = 1;
+
+  /**
+   * [OP_OR]
+   * [length]
+   *  {boolean expression}
+   *  {boolean expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_OR = 2;
+
+  /**
+   * [OP_AND]
+   * [length]
+   *  {boolean expression}
+   *  {boolean expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_AND = 3;
+
+  /**
+   * [OP_NOTEQUALS]
+   * [length]
+   *  {expression}
+   *  {expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_NOTEQUALS = 4;
+
+  /**
+   * [OP_EQUALS]
+   * [length]
+   *  {expression}
+   *  {expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_EQUALS = 5;
+
+  /**
+   * [OP_LTE] (less-than-or-equals)
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_LTE = 6;
+
+  /**
+   * [OP_LT] (less-than)
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_LT = 7;
+
+  /**
+   * [OP_GTE] (greater-than-or-equals)
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_GTE = 8;
+
+  /**
+   * [OP_GT] (greater-than)
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_GT = 9;
+
+  /**
+   * [OP_PLUS]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_PLUS = 10;
+
+  /**
+   * [OP_MINUS]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_MINUS = 11;
+
+  /**
+   * [OP_MULT]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_MULT = 12;
+
+  /**
+   * [OP_DIV]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_DIV = 13;
+
+  /**
+   * [OP_MOD]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_MOD = 14;
+
+  /**
+   * [OP_QUO]
+   * [length]
+   *  {number expression}
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_QUO = 15;
+
+  /**
+   * [OP_NEG]
+   * [length]
+   *  {number expression}
+   *
+   * returns:
+   *  XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_NEG = 16;
+
+  /**
+   * [OP_STRING] (cast operation)
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XString
+   * @xsl.usage advanced
+   */
+  public static final int OP_STRING = 17;
+
+  /**
+   * [OP_BOOL] (cast operation)
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_BOOL = 18;
+
+  /**
+   * [OP_NUMBER] (cast operation)
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int OP_NUMBER = 19;
+
+  /**
+   * [OP_UNION]
+   * [length]
+   *  {PathExpr}+
+   *
+   * returns:
+   *  XNodeSet
+   * @xsl.usage advanced
+   */
+  public static final int OP_UNION = 20;
+
+  /**
+   * [OP_LITERAL]
+   * [3]
+   * [index to token]
+   *
+   * returns:
+   *  XString
+   * @xsl.usage advanced
+   */
+  public static final int OP_LITERAL = 21;
+
+  /** The low opcode for nodesets, needed by getFirstPredicateOpPos and 
+   *  getNextStepPos.          */
+  static final int FIRST_NODESET_OP = 22;
+
+  /**
+   * [OP_VARIABLE]
+   * [4]
+   * [index to namespace token, or EMPTY]
+   * [index to function name token]
+   *
+   * returns:
+   *  XString
+   * @xsl.usage advanced
+   */
+  public static final int OP_VARIABLE = 22;
+
+  /**
+   * [OP_GROUP]
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XNodeSet
+   *  XNumber
+   *  XString
+   *  XBoolean
+   *  XRTree
+   *  XObject
+   * @xsl.usage advanced
+   */
+  public static final int OP_GROUP = 23;
+
+  /**
+   * [OP_EXTFUNCTION] (Extension function.)
+   * [length]
+   * [index to namespace token]
+   * [index to function name token]
+   *  {OP_ARGUMENT}
+   *
+   * returns:
+   *  XNodeSet
+   *  XNumber
+   *  XString
+   *  XBoolean
+   *  XRTree
+   *  XObject
+   * @xsl.usage advanced
+   */
+  public static final int OP_EXTFUNCTION = 24;
+
+  /**
+   * [OP_FUNCTION]
+   * [length]
+   * [FUNC_name]
+   *  {OP_ARGUMENT}
+   * [ENDOP]
+   *
+   * returns:
+   *  XNodeSet
+   *  XNumber
+   *  XString
+   *  XBoolean
+   *  XRTree
+   *  XObject
+   * @xsl.usage advanced
+   */
+  public static final int OP_FUNCTION = 25;
+
+  /** The last opcode for stuff that can be a nodeset.         */
+  static final int LAST_NODESET_OP = 25;
+
+  /**
+   * [OP_ARGUMENT] (Function argument.)
+   * [length]
+   *  {expression}
+   *
+   * returns:
+   *  XNodeSet
+   *  XNumber
+   *  XString
+   *  XBoolean
+   *  XRTree
+   *  XObject
+   * @xsl.usage advanced
+   */
+  public static final int OP_ARGUMENT = 26;
+
+  /**
+   * [OP_NUMBERLIT] (Number literal.)
+   * [3]
+   * [index to token]
+   *
+   * returns:
+   *  XString
+   * @xsl.usage advanced
+   */
+  public static final int OP_NUMBERLIT = 27;
+
+  /**
+   * [OP_LOCATIONPATH]
+   * [length]
+   *   {FROM_stepType}
+   * | {function}
+   * {predicate}
+   * [ENDOP]
+   *
+   * (Note that element and attribute namespaces and
+   * names can be wildcarded '*'.)
+   *
+   * returns:
+   *  XNodeSet
+   * @xsl.usage advanced
+   */
+  public static final int OP_LOCATIONPATH = 28;
+
+  // public static final int LOCATIONPATHEX_MASK = 0x0000FFFF;
+  // public static final int LOCATIONPATHEX_ISSIMPLE = 0x00010000;
+  // public static final int OP_LOCATIONPATH_EX = (28 | 0x00010000);
+
+  /**
+   * [OP_PREDICATE]
+   * [length]
+   *  {expression}
+   * [ENDOP] (For safety)
+   *
+   * returns:
+   *  XBoolean or XNumber
+   * @xsl.usage advanced
+   */
+  public static final int OP_PREDICATE = 29;
+
+  /**
+   * [OP_MATCHPATTERN]
+   * [length]
+   *  {PathExpr}+
+   *
+   * returns:
+   *  XNodeSet
+   * @xsl.usage advanced
+   */
+  public static final int OP_MATCHPATTERN = 30;
+
+  /**
+   * [OP_LOCATIONPATHPATTERN]
+   * [length]
+   *   {FROM_stepType}
+   * | {function}{predicate}
+   * [ENDOP]
+   * returns:
+   *  XNodeSet
+   * @xsl.usage advanced
+   */
+  public static final int OP_LOCATIONPATHPATTERN = 31;
+
+  /**
+   * [NODETYPE_COMMENT]
+   * No size or arguments.
+   * Note: must not overlap function OP number!
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_COMMENT = 1030;
+
+  /**
+   * [NODETYPE_TEXT]
+   * No size or arguments.
+   * Note: must not overlap function OP number!
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_TEXT = 1031;
+
+  /**
+   * [NODETYPE_PI]
+   * [index to token]
+   * Note: must not overlap function OP number!
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_PI = 1032;
+
+  /**
+   * [NODETYPE_NODE]
+   * No size or arguments.
+   * Note: must not overlap function OP number!
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_NODE = 1033;
+
+  /**
+   * [NODENAME]
+   * [index to ns token or EMPTY]
+   * [index to name token]
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODENAME = 34;
+
+  /**
+   * [NODETYPE_ROOT]
+   * No size or arguments.
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_ROOT = 35;
+
+  /**
+   * [NODETYPE_ANY]
+   * No size or arguments.
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_ANYELEMENT = 36;
+
+  /**
+   * [NODETYPE_ANY]
+   * No size or arguments.
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int NODETYPE_FUNCTEST = 1034;
+
+  /**
+   * [FROM_stepType]
+   * [length, including predicates]
+   * [length of just the step, without the predicates]
+   * {node test}
+   * {predicates}?
+   *
+   * returns:
+   *  XBoolean
+   * @xsl.usage advanced
+   */
+  public static final int AXES_START_TYPES = 37;
+
+  /** ancestor axes opcode.         */
+  public static final int FROM_ANCESTORS = 37;
+
+  /** ancestor-or-self axes opcode.         */
+  public static final int FROM_ANCESTORS_OR_SELF = 38;
+
+  /** attribute axes opcode.         */
+  public static final int FROM_ATTRIBUTES = 39;
+
+  /** children axes opcode.         */
+  public static final int FROM_CHILDREN = 40;
+
+  /** descendants axes opcode.         */
+  public static final int FROM_DESCENDANTS = 41;
+
+  /** descendants-of-self axes opcode.         */
+  public static final int FROM_DESCENDANTS_OR_SELF = 42;
+
+  /** following axes opcode.         */
+  public static final int FROM_FOLLOWING = 43;
+
+  /** following-siblings axes opcode.         */
+  public static final int FROM_FOLLOWING_SIBLINGS = 44;
+
+  /** parent axes opcode.         */
+  public static final int FROM_PARENT = 45;
+
+  /** preceding axes opcode.         */
+  public static final int FROM_PRECEDING = 46;
+
+  /** preceding-sibling axes opcode.         */
+  public static final int FROM_PRECEDING_SIBLINGS = 47;
+
+  /** self axes opcode.         */
+  public static final int FROM_SELF = 48;
+
+  /** namespace axes opcode.         */
+  public static final int FROM_NAMESPACE = 49;
+
+  /** '/' axes opcode.         */
+  public static final int FROM_ROOT = 50;
+
+  /**
+   * For match patterns.
+   * @xsl.usage advanced
+   */
+  public static final int MATCH_ATTRIBUTE = 51;
+
+  /**
+   * For match patterns.
+   * @xsl.usage advanced
+   */
+  public static final int MATCH_ANY_ANCESTOR = 52;
+
+  /**
+   * For match patterns.
+   * @xsl.usage advanced
+   */
+  public static final int MATCH_IMMEDIATE_ANCESTOR = 53;
+
+  /** The end of the axes types.    */
+  public static final int AXES_END_TYPES = 53;
+
+  /** The next free ID.  Please keep this up to date.  */
+  private static final int NEXT_FREE_ID = 99;
+}
diff --git a/src/main/java/org/apache/xpath/compiler/OpMap.java b/src/main/java/org/apache/xpath/compiler/OpMap.java
new file mode 100644
index 0000000..349721f
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/OpMap.java
@@ -0,0 +1,455 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: OpMap.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.ObjectVector;
+import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class represents the data structure basics of the XPath
+ * object.
+ */
+public class OpMap
+{
+
+  /**
+   * The current pattern string, for diagnostics purposes
+   */
+  protected String m_currentPattern;
+
+  /**
+   * Return the expression as a string for diagnostics.
+   *
+   * @return The expression string.
+   */
+  public String toString()
+  {
+    return m_currentPattern;
+  }
+
+  /**
+   * Return the expression as a string for diagnostics.
+   *
+   * @return The expression string.
+   */
+  public String getPatternString()
+  {
+    return m_currentPattern;
+  }
+
+  /**
+   * The starting size of the token queue.
+   */
+  static final int MAXTOKENQUEUESIZE = 500;
+
+  /*
+   * Amount to grow token queue when it becomes full
+   */
+  static final int BLOCKTOKENQUEUESIZE = 500;
+  
+  /**
+   *  TokenStack is the queue of used tokens. The current token is the token at the
+   * end of the m_tokenQueue. The idea is that the queue can be marked and a sequence
+   * of tokens can be reused.
+   */
+  ObjectVector m_tokenQueue = new ObjectVector(MAXTOKENQUEUESIZE, BLOCKTOKENQUEUESIZE);
+
+  /**
+   * Get the XPath as a list of tokens.
+   *
+   * @return ObjectVector of tokens.
+   */
+  public ObjectVector getTokenQueue()
+  {
+    return m_tokenQueue;
+  }
+
+  /**
+   * Get the XPath as a list of tokens.
+   *
+   * @param pos index into token queue.
+   *
+   * @return The token, normally a string.
+   */
+  public Object getToken(int pos)
+  {
+    return m_tokenQueue.elementAt(pos);
+  }
+
+  /**
+   * The current size of the token queue.
+   */
+//  public int m_tokenQueueSize = 0;
+
+  /**
+    * Get size of the token queue.
+   *
+   * @return The size of the token queue.
+   */
+  public int getTokenQueueSize()
+  {
+    return m_tokenQueue.size();
+    
+  }
+
+  /**
+   * An operations map is used instead of a proper parse tree.  It contains
+   * operations codes and indexes into the m_tokenQueue.
+   * I use an array instead of a full parse tree in order to cut down
+   * on the number of objects created.
+   */
+  OpMapVector m_opMap = null;
+
+  /**
+    * Get the opcode list that describes the XPath operations.  It contains
+   * operations codes and indexes into the m_tokenQueue.
+   * I use an array instead of a full parse tree in order to cut down
+   * on the number of objects created.
+   *
+   * @return An IntVector that is the opcode list that describes the XPath operations.
+   */
+  public OpMapVector getOpMap()
+  {
+    return m_opMap;
+  }
+
+  // Position indexes
+
+  /**
+   * The length is always the opcode position + 1.
+   * Length is always expressed as the opcode+length bytes,
+   * so it is always 2 or greater.
+   */
+  public static final int MAPINDEX_LENGTH = 1;
+
+  /**
+   * Replace the large arrays
+   * with a small array.
+   */
+  void shrink()
+  {
+
+    int n = m_opMap.elementAt(MAPINDEX_LENGTH);
+    m_opMap.setToSize(n + 4);
+
+    m_opMap.setElementAt(0,n);
+    m_opMap.setElementAt(0,n+1);
+    m_opMap.setElementAt(0,n+2);
+
+
+    n = m_tokenQueue.size();
+    m_tokenQueue.setToSize(n + 4);
+
+    m_tokenQueue.setElementAt(null,n);
+    m_tokenQueue.setElementAt(null,n + 1);
+    m_tokenQueue.setElementAt(null,n + 2);
+  }
+
+  /**
+  * Given an operation position, return the current op.
+   *
+   * @param opPos index into op map.
+   * @return the op that corresponds to the opPos argument.
+   */
+  public int getOp(int opPos)
+  {
+    return m_opMap.elementAt(opPos);
+  }
+
+  /**
+  * Set the op at index to the given int.
+   *
+   * @param opPos index into op map.
+   * @param value Value to set
+   */
+  public void setOp(int opPos, int value)
+  {
+     m_opMap.setElementAt(value,opPos);
+  }
+  
+  /**
+   * Given an operation position, return the end position, i.e. the
+   * beginning of the next operation.
+   *
+   * @param opPos An op position of an operation for which there is a size 
+   *              entry following.
+   * @return position of next operation in m_opMap.
+   */
+  public int getNextOpPos(int opPos)
+  {
+    return opPos + m_opMap.elementAt(opPos + 1);
+  }
+
+  /**
+   * Given a location step position, return the end position, i.e. the
+   * beginning of the next step.
+   *
+   * @param opPos the position of a location step.
+   * @return the position of the next location step.
+   */
+  public int getNextStepPos(int opPos)
+  {
+
+    int stepType = getOp(opPos);
+
+    if ((stepType >= OpCodes.AXES_START_TYPES)
+            && (stepType <= OpCodes.AXES_END_TYPES))
+    {
+      return getNextOpPos(opPos);
+    }
+    else if ((stepType >= OpCodes.FIRST_NODESET_OP)
+             && (stepType <= OpCodes.LAST_NODESET_OP))
+    {
+      int newOpPos = getNextOpPos(opPos);
+
+      while (OpCodes.OP_PREDICATE == getOp(newOpPos))
+      {
+        newOpPos = getNextOpPos(newOpPos);
+      }
+
+      stepType = getOp(newOpPos);
+
+      if (!((stepType >= OpCodes.AXES_START_TYPES)
+            && (stepType <= OpCodes.AXES_END_TYPES)))
+      {
+        return OpCodes.ENDOP;
+      }
+
+      return newOpPos;
+    }
+    else
+    {
+      throw new RuntimeException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_UNKNOWN_STEP, new Object[]{String.valueOf(stepType)})); 
+      //"Programmer's assertion in getNextStepPos: unknown stepType: " + stepType);
+    }
+  }
+
+  /**
+   * Given an operation position, return the end position, i.e. the
+   * beginning of the next operation.
+   *
+   * @param opMap The operations map.
+   * @param opPos index to operation, for which there is a size entry following.
+   * @return position of next operation in m_opMap.
+   */
+  public static int getNextOpPos(int[] opMap, int opPos)
+  {
+    return opPos + opMap[opPos + 1];
+  }
+
+  /**
+   * Given an FROM_stepType position, return the position of the
+   * first predicate, if there is one, or else this will point
+   * to the end of the FROM_stepType.
+   * Example:
+   *  int posOfPredicate = xpath.getNextOpPos(stepPos);
+   *  boolean hasPredicates =
+   *            OpCodes.OP_PREDICATE == xpath.getOp(posOfPredicate);
+   *
+   * @param opPos position of FROM_stepType op. 
+   * @return position of predicate in FROM_stepType structure.
+   */
+  public int getFirstPredicateOpPos(int opPos)
+     throws javax.xml.transform.TransformerException
+  {
+
+    int stepType = m_opMap.elementAt(opPos);
+
+    if ((stepType >= OpCodes.AXES_START_TYPES)
+            && (stepType <= OpCodes.AXES_END_TYPES))
+    {
+      return opPos + m_opMap.elementAt(opPos + 2);
+    }
+    else if ((stepType >= OpCodes.FIRST_NODESET_OP)
+             && (stepType <= OpCodes.LAST_NODESET_OP))
+    {
+      return opPos + m_opMap.elementAt(opPos + 1);
+    }
+    else if(-2 == stepType)
+    {
+      return -2;
+    }
+    else
+    {
+      error(org.apache.xpath.res.XPATHErrorResources.ER_UNKNOWN_OPCODE,
+            new Object[]{ String.valueOf(stepType) });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
+      return -1;
+    }
+  }
+  
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  public void error(String msg, Object[] args) throws javax.xml.transform.TransformerException
+  {
+
+    java.lang.String fmsg = org.apache.xalan.res.XSLMessages.createXPATHMessage(msg, args);
+    
+
+    throw new javax.xml.transform.TransformerException(fmsg);
+  }
+
+
+  /**
+   * Go to the first child of a given operation.
+   *
+   * @param opPos position of operation.
+   *
+   * @return The position of the first child of the operation.
+   */
+  public static int getFirstChildPos(int opPos)
+  {
+    return opPos + 2;
+  }
+
+  /**
+   * Get the length of an operation.
+   *
+   * @param opPos The position of the operation in the op map.
+   *
+   * @return The size of the operation.
+   */
+  public int getArgLength(int opPos)
+  {
+    return m_opMap.elementAt(opPos + MAPINDEX_LENGTH);
+  }
+
+  /**
+   * Given a location step, get the length of that step.
+   *
+   * @param opPos Position of location step in op map.
+   *
+   * @return The length of the step.
+   */
+  public int getArgLengthOfStep(int opPos)
+  {
+    return m_opMap.elementAt(opPos + MAPINDEX_LENGTH + 1) - 3;
+  }
+
+  /**
+   * Get the first child position of a given location step.
+   *
+   * @param opPos Position of location step in the location map.
+   *
+   * @return The first child position of the step.
+   */
+  public static int getFirstChildPosOfStep(int opPos)
+  {
+    return opPos + 3;
+  }
+
+  /**
+   * Get the test type of the step, i.e. NODETYPE_XXX value.
+   * 
+   * @param opPosOfStep The position of the FROM_XXX step.
+   *
+   * @return NODETYPE_XXX value.
+   */
+  public int getStepTestType(int opPosOfStep)
+  {
+    return m_opMap.elementAt(opPosOfStep + 3);  // skip past op, len, len without predicates
+  }
+
+  /**
+   * Get the namespace of the step.
+   * 
+   * @param opPosOfStep The position of the FROM_XXX step.
+   *
+   * @return The step's namespace, NodeTest.WILD, or null for null namespace.
+   */
+  public String getStepNS(int opPosOfStep)
+  {
+
+    int argLenOfStep = getArgLengthOfStep(opPosOfStep);
+
+    // System.out.println("getStepNS.argLenOfStep: "+argLenOfStep);
+    if (argLenOfStep == 3)
+    {
+      int index = m_opMap.elementAt(opPosOfStep + 4);
+
+      if (index >= 0)
+        return (String) m_tokenQueue.elementAt(index);
+      else if (OpCodes.ELEMWILDCARD == index)
+        return NodeTest.WILD;
+      else
+        return null;
+    }
+    else
+      return null;
+  }
+
+  /**
+   * Get the local name of the step.
+   * @param opPosOfStep The position of the FROM_XXX step.
+   *
+   * @return OpCodes.EMPTY, OpCodes.ELEMWILDCARD, or the local name.
+   */
+  public String getStepLocalName(int opPosOfStep)
+  {
+
+    int argLenOfStep = getArgLengthOfStep(opPosOfStep);
+
+    // System.out.println("getStepLocalName.argLenOfStep: "+argLenOfStep);
+    int index;
+
+    switch (argLenOfStep)
+    {
+    case 0 :
+      index = OpCodes.EMPTY;
+      break;
+    case 1 :
+      index = OpCodes.ELEMWILDCARD;
+      break;
+    case 2 :
+      index = m_opMap.elementAt(opPosOfStep + 4);
+      break;
+    case 3 :
+      index = m_opMap.elementAt(opPosOfStep + 5);
+      break;
+    default :
+      index = OpCodes.EMPTY;
+      break;  // Should assert error
+    }
+
+    // int index = (argLenOfStep == 3) ? m_opMap[opPosOfStep+5] 
+    //                                  : ((argLenOfStep == 1) ? -3 : -2);
+    if (index >= 0)
+      return (String) m_tokenQueue.elementAt(index).toString();
+    else if (OpCodes.ELEMWILDCARD == index)
+      return NodeTest.WILD;
+    else
+      return null;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xpath/compiler/OpMapVector.java b/src/main/java/org/apache/xpath/compiler/OpMapVector.java
new file mode 100644
index 0000000..a2c53d2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/OpMapVector.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xpath.compiler;
+
+/**
+ * 
+ * Like IntVector, but used only for the OpMap array.  Length of array
+ * is kept in the m_lengthPos position of the array.  Only the required methods 
+ * are in included here.
+ * @xsl.usage internal
+ */
+public class OpMapVector {
+    
+ /** Size of blocks to allocate          */
+  protected int m_blocksize;
+
+  /** Array of ints          */
+  protected int m_map[]; // IntStack is trying to see this directly
+
+  /** Position where size of array is kept          */
+  protected int m_lengthPos = 0;
+
+  /** Size of array          */
+  protected int m_mapSize;
+  
+    /**
+   * Construct a OpMapVector, using the given block size.
+   *
+   * @param blocksize Size of block to allocate
+   */
+  public OpMapVector(int blocksize, int increaseSize, int lengthPos)
+  {
+
+    m_blocksize = increaseSize;
+    m_mapSize = blocksize;
+    m_lengthPos = lengthPos;
+    m_map = new int[blocksize];
+  }
+  
+  /**
+   * Get the nth element.
+   *
+   * @param i index of object to get
+   *
+   * @return object at given index
+   */
+  public final int elementAt(int i)
+  {
+    return m_map[i];
+  }  
+   
+    /**
+   * Sets the component at the specified index of this vector to be the
+   * specified object. The previous component at that position is discarded.
+   *
+   * The index must be a value greater than or equal to 0 and less
+   * than the current size of the vector.
+   *
+   * @param value object to set
+   * @param index Index of where to set the object
+   */
+  public final void setElementAt(int value, int index)
+  {
+    if (index >= m_mapSize)
+    {
+      int oldSize = m_mapSize;
+      
+      m_mapSize += m_blocksize;
+
+      int newMap[] = new int[m_mapSize];
+
+      System.arraycopy(m_map, 0, newMap, 0, oldSize);
+
+      m_map = newMap;
+    }
+
+    m_map[index] = value;
+  }
+  
+  
+  /*
+   * Reset the array to the supplied size.  No checking is done.
+   * 
+   * @param size The size to trim to.
+   */
+  public final void setToSize(int size) {
+    
+    int newMap[] = new int[size];
+
+    System.arraycopy(m_map, 0, newMap, 0, m_map[m_lengthPos]);
+
+    m_mapSize = size;
+    m_map = newMap;
+    
+  }  
+
+}
diff --git a/src/main/java/org/apache/xpath/compiler/PsuedoNames.java b/src/main/java/org/apache/xpath/compiler/PsuedoNames.java
new file mode 100644
index 0000000..d585c81
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/PsuedoNames.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: PsuedoNames.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+/**
+ * This is used to represent names of nodes that may not be named, like a 
+ * comment node.
+ */
+public class PsuedoNames
+{
+
+  /**
+   * Psuedo name for a wild card pattern ('*').
+   */
+  public static final String PSEUDONAME_ANY = "*";
+
+  /**
+   * Psuedo name for the root node.
+   */
+  public static final String PSEUDONAME_ROOT = "/";
+
+  /**
+   * Psuedo name for a text node.
+   */
+  public static final String PSEUDONAME_TEXT = "#text";
+
+  /**
+   * Psuedo name for a comment node.
+   */
+  public static final String PSEUDONAME_COMMENT = "#comment";
+
+  /**
+   * Psuedo name for a processing instruction node.
+   */
+  public static final String PSEUDONAME_PI = "#pi";
+
+  /**
+   * Psuedo name for an unknown type value.
+   */
+  public static final String PSEUDONAME_OTHER = "*";
+}
diff --git a/src/main/java/org/apache/xpath/compiler/XPathDumper.java b/src/main/java/org/apache/xpath/compiler/XPathDumper.java
new file mode 100644
index 0000000..c53e0a5
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/XPathDumper.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathDumper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+
+/**
+ * Class for XPath diagnostic functions.
+ */
+public class XPathDumper
+{
+
+  // deleted for the time being.
+}
diff --git a/src/main/java/org/apache/xpath/compiler/XPathParser.java b/src/main/java/org/apache/xpath/compiler/XPathParser.java
new file mode 100644
index 0000000..58067e1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/XPathParser.java
@@ -0,0 +1,2401 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPathParser.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.compiler;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.XPathProcessorException;
+import org.apache.xpath.domapi.XPathStylesheetDOM3Exception;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Tokenizes and parses XPath expressions. This should really be named
+ * XPathParserImpl, and may be renamed in the future.
+ * @xsl.usage general
+ */
+public class XPathParser
+{
+	// %REVIEW% Is there a better way of doing this?
+	// Upside is minimum object churn. Downside is that we don't have a useful
+	// backtrace in the exception itself -- but we don't expect to need one.
+	static public final String CONTINUE_AFTER_FATAL_ERROR="CONTINUE_AFTER_FATAL_ERROR";
+
+  /**
+   * The XPath to be processed.
+   */
+  private OpMap m_ops;
+
+  /**
+   * The next token in the pattern.
+   */
+  transient String m_token;
+
+  /**
+   * The first char in m_token, the theory being that this
+   * is an optimization because we won't have to do charAt(0) as
+   * often.
+   */
+  transient char m_tokenChar = 0;
+
+  /**
+   * The position in the token queue is tracked by m_queueMark.
+   */
+  int m_queueMark = 0;
+
+  /**
+   * Results from checking FilterExpr syntax
+   */
+  protected final static int FILTER_MATCH_FAILED     = 0;
+  protected final static int FILTER_MATCH_PRIMARY    = 1;
+  protected final static int FILTER_MATCH_PREDICATES = 2;
+
+  /**
+   * The parser constructor.
+   */
+  public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocator sourceLocator)
+  {
+    m_errorListener = errorListener;
+    m_sourceLocator = sourceLocator;
+  }
+
+  /**
+   * The prefix resolver to map prefixes to namespaces in the OpMap.
+   */
+  PrefixResolver m_namespaceContext;
+
+  /**
+   * Given an string, init an XPath object for selections,
+   * in order that a parse doesn't
+   * have to be done each time the expression is evaluated.
+   * 
+   * @param compiler The compiler object.
+   * @param expression A string conforming to the XPath grammar.
+   * @param namespaceContext An object that is able to resolve prefixes in
+   * the XPath to namespaces.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void initXPath(
+          Compiler compiler, String expression, PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    m_ops = compiler;
+    m_namespaceContext = namespaceContext;
+    m_functionTable = compiler.getFunctionTable();
+
+    Lexer lexer = new Lexer(compiler, namespaceContext, this);
+
+    lexer.tokenize(expression);
+
+    m_ops.setOp(0,OpCodes.OP_XPATH);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH,2);
+    
+    
+	// Patch for Christine's gripe. She wants her errorHandler to return from
+	// a fatal error and continue trying to parse, rather than throwing an exception.
+	// Without the patch, that put us into an endless loop.
+	//
+	// %REVIEW% Is there a better way of doing this?
+	// %REVIEW% Are there any other cases which need the safety net?
+	// 	(and if so do we care right now, or should we rewrite the XPath
+	//	grammar engine and can fix it at that time?)
+	try {
+
+      nextToken();
+      Expr();
+
+      if (null != m_token)
+      {
+        String extraTokens = "";
+
+        while (null != m_token)
+        {
+          extraTokens += "'" + m_token + "'";
+
+          nextToken();
+
+          if (null != m_token)
+            extraTokens += ", ";
+        }
+
+        error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
+              new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
+      }
+
+    } 
+    catch (org.apache.xpath.XPathProcessorException e)
+    {
+	  if(CONTINUE_AFTER_FATAL_ERROR.equals(e.getMessage()))
+	  {
+		// What I _want_ to do is null out this XPath.
+		// I doubt this has the desired effect, but I'm not sure what else to do.
+		// %REVIEW%!!!
+		initXPath(compiler, "/..",  namespaceContext);
+	  }
+	  else
+		throw e;
+    }
+
+    compiler.shrink();
+  }
+
+  /**
+   * Given an string, init an XPath object for pattern matches,
+   * in order that a parse doesn't
+   * have to be done each time the expression is evaluated.
+   * @param compiler The XPath object to be initialized.
+   * @param expression A String representing the XPath.
+   * @param namespaceContext An object that is able to resolve prefixes in
+   * the XPath to namespaces.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public void initMatchPattern(
+          Compiler compiler, String expression, PrefixResolver namespaceContext)
+            throws javax.xml.transform.TransformerException
+  {
+
+    m_ops = compiler;
+    m_namespaceContext = namespaceContext;
+    m_functionTable = compiler.getFunctionTable();
+
+    Lexer lexer = new Lexer(compiler, namespaceContext, this);
+
+    lexer.tokenize(expression);
+
+    m_ops.setOp(0, OpCodes.OP_MATCHPATTERN);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, 2);
+
+    nextToken();
+    Pattern();
+
+    if (null != m_token)
+    {
+      String extraTokens = "";
+
+      while (null != m_token)
+      {
+        extraTokens += "'" + m_token + "'";
+
+        nextToken();
+
+        if (null != m_token)
+          extraTokens += ", ";
+      }
+
+      error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
+            new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
+    }
+
+    // Terminate for safety.
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH)+1);
+
+    m_ops.shrink();
+  }
+
+  /** The error listener where syntax errors are to be sent.
+   */
+  private ErrorListener m_errorListener;
+  
+  /** The source location of the XPath. */
+  javax.xml.transform.SourceLocator m_sourceLocator;
+  
+  /** The table contains build-in functions and customized functions */
+  private FunctionTable m_functionTable;
+
+  /**
+   * Allow an application to register an error event handler, where syntax 
+   * errors will be sent.  If the error listener is not set, syntax errors 
+   * will be sent to System.err.
+   * 
+   * @param handler Reference to error listener where syntax errors will be 
+   *                sent.
+   */
+  public void setErrorHandler(ErrorListener handler)
+  {
+    m_errorListener = handler;
+  }
+
+  /**
+   * Return the current error listener.
+   *
+   * @return The error listener, which should not normally be null, but may be.
+   */
+  public ErrorListener getErrorListener()
+  {
+    return m_errorListener;
+  }
+
+  /**
+   * Check whether m_token matches the target string. 
+   *
+   * @param s A string reference or null.
+   *
+   * @return If m_token is null, returns false (or true if s is also null), or 
+   * return true if the current token matches the string, else false.
+   */
+  final boolean tokenIs(String s)
+  {
+    return (m_token != null) ? (m_token.equals(s)) : (s == null);
+  }
+
+  /**
+   * Check whether m_tokenChar==c. 
+   *
+   * @param c A character to be tested.
+   *
+   * @return If m_token is null, returns false, or return true if c matches 
+   *         the current token.
+   */
+  final boolean tokenIs(char c)
+  {
+    return (m_token != null) ? (m_tokenChar == c) : false;
+  }
+
+  /**
+   * Look ahead of the current token in order to
+   * make a branching decision.
+   *
+   * @param c the character to be tested for.
+   * @param n number of tokens to look ahead.  Must be
+   * greater than 1.
+   *
+   * @return true if the next token matches the character argument.
+   */
+  final boolean lookahead(char c, int n)
+  {
+
+    int pos = (m_queueMark + n);
+    boolean b;
+
+    if ((pos <= m_ops.getTokenQueueSize()) && (pos > 0)
+            && (m_ops.getTokenQueueSize() != 0))
+    {
+      String tok = ((String) m_ops.m_tokenQueue.elementAt(pos - 1));
+
+      b = (tok.length() == 1) ? (tok.charAt(0) == c) : false;
+    }
+    else
+    {
+      b = false;
+    }
+
+    return b;
+  }
+
+  /**
+   * Look behind the first character of the current token in order to
+   * make a branching decision.
+   * 
+   * @param c the character to compare it to.
+   * @param n number of tokens to look behind.  Must be
+   * greater than 1.  Note that the look behind terminates
+   * at either the beginning of the string or on a '|'
+   * character.  Because of this, this method should only
+   * be used for pattern matching.
+   *
+   * @return true if the token behind the current token matches the character 
+   *         argument.
+   */
+  private final boolean lookbehind(char c, int n)
+  {
+
+    boolean isToken;
+    int lookBehindPos = m_queueMark - (n + 1);
+
+    if (lookBehindPos >= 0)
+    {
+      String lookbehind = (String) m_ops.m_tokenQueue.elementAt(lookBehindPos);
+
+      if (lookbehind.length() == 1)
+      {
+        char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);
+
+        isToken = (c0 == '|') ? false : (c0 == c);
+      }
+      else
+      {
+        isToken = false;
+      }
+    }
+    else
+    {
+      isToken = false;
+    }
+
+    return isToken;
+  }
+
+  /**
+   * look behind the current token in order to
+   * see if there is a useable token.
+   * 
+   * @param n number of tokens to look behind.  Must be
+   * greater than 1.  Note that the look behind terminates
+   * at either the beginning of the string or on a '|'
+   * character.  Because of this, this method should only
+   * be used for pattern matching.
+   * 
+   * @return true if look behind has a token, false otherwise.
+   */
+  private final boolean lookbehindHasToken(int n)
+  {
+
+    boolean hasToken;
+
+    if ((m_queueMark - n) > 0)
+    {
+      String lookbehind = (String) m_ops.m_tokenQueue.elementAt(m_queueMark - (n - 1));
+      char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);
+
+      hasToken = (c0 == '|') ? false : true;
+    }
+    else
+    {
+      hasToken = false;
+    }
+
+    return hasToken;
+  }
+
+  /**
+   * Look ahead of the current token in order to
+   * make a branching decision.
+   * 
+   * @param s the string to compare it to.
+   * @param n number of tokens to lookahead.  Must be
+   * greater than 1.
+   *
+   * @return true if the token behind the current token matches the string 
+   *         argument.
+   */
+  private final boolean lookahead(String s, int n)
+  {
+
+    boolean isToken;
+
+    if ((m_queueMark + n) <= m_ops.getTokenQueueSize())
+    {
+      String lookahead = (String) m_ops.m_tokenQueue.elementAt(m_queueMark + (n - 1));
+
+      isToken = (lookahead != null) ? lookahead.equals(s) : (s == null);
+    }
+    else
+    {
+      isToken = (null == s);
+    }
+
+    return isToken;
+  }
+
+  /**
+   * Retrieve the next token from the command and
+   * store it in m_token string.
+   */
+  private final void nextToken()
+  {
+
+    if (m_queueMark < m_ops.getTokenQueueSize())
+    {
+      m_token = (String) m_ops.m_tokenQueue.elementAt(m_queueMark++);
+      m_tokenChar = m_token.charAt(0);
+    }
+    else
+    {
+      m_token = null;
+      m_tokenChar = 0;
+    }
+  }
+
+  /**
+   * Retrieve a token relative to the current token.
+   * 
+   * @param i Position relative to current token.
+   *
+   * @return The string at the given index, or null if the index is out 
+   *         of range.
+   */
+  private final String getTokenRelative(int i)
+  {
+
+    String tok;
+    int relative = m_queueMark + i;
+
+    if ((relative > 0) && (relative < m_ops.getTokenQueueSize()))
+    {
+      tok = (String) m_ops.m_tokenQueue.elementAt(relative);
+    }
+    else
+    {
+      tok = null;
+    }
+
+    return tok;
+  }
+
+  /**
+   * Retrieve the previous token from the command and
+   * store it in m_token string.
+   */
+  private final void prevToken()
+  {
+
+    if (m_queueMark > 0)
+    {
+      m_queueMark--;
+
+      m_token = (String) m_ops.m_tokenQueue.elementAt(m_queueMark);
+      m_tokenChar = m_token.charAt(0);
+    }
+    else
+    {
+      m_token = null;
+      m_tokenChar = 0;
+    }
+  }
+
+  /**
+   * Consume an expected token, throwing an exception if it
+   * isn't there.
+   *
+   * @param expected The string to be expected.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private final void consumeExpected(String expected)
+          throws javax.xml.transform.TransformerException
+  {
+
+    if (tokenIs(expected))
+    {
+      nextToken();
+    }
+    else
+    {
+      error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND, new Object[]{ expected,
+                                                                     m_token });  //"Expected "+expected+", but found: "+m_token);
+
+	  // Patch for Christina's gripe. She wants her errorHandler to return from
+	  // this error and continue trying to parse, rather than throwing an exception.
+	  // Without the patch, that put us into an endless loop.
+		throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR);
+	}
+  }
+
+  /**
+   * Consume an expected token, throwing an exception if it
+   * isn't there.
+   *
+   * @param expected the character to be expected.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  private final void consumeExpected(char expected)
+          throws javax.xml.transform.TransformerException
+  {
+
+    if (tokenIs(expected))
+    {
+      nextToken();
+    }
+    else
+    {
+      error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND,
+            new Object[]{ String.valueOf(expected),
+                          m_token });  //"Expected "+expected+", but found: "+m_token);
+
+	  // Patch for Christina's gripe. She wants her errorHandler to return from
+	  // this error and continue trying to parse, rather than throwing an exception.
+	  // Without the patch, that put us into an endless loop.
+		throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR);
+    }
+  }
+
+  /**
+   * Warn the user of a problem.
+   *
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  void warn(String msg, Object[] args) throws TransformerException
+  {
+
+    String fmsg = XSLMessages.createXPATHWarning(msg, args);
+    ErrorListener ehandler = this.getErrorListener();
+
+    if (null != ehandler)
+    {
+      // TO DO: Need to get stylesheet Locator from here.
+      ehandler.warning(new TransformerException(fmsg, m_sourceLocator));
+    }
+    else
+    {
+      // Should never happen.
+      System.err.println(fmsg);
+    }
+  }
+
+  /**
+   * Notify the user of an assertion error, and probably throw an
+   * exception.
+   *
+   * @param b  If false, a runtime exception will be thrown.
+   * @param msg The assertion message, which should be informative.
+   * 
+   * @throws RuntimeException if the b argument is false.
+   */
+  private void assertion(boolean b, String msg)
+  {
+
+    if (!b)
+    {
+      String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ msg });
+
+      throw new RuntimeException(fMsg);
+    }
+  }
+
+  /**
+   * Notify the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  void error(String msg, Object[] args) throws TransformerException
+  {
+
+    String fmsg = XSLMessages.createXPATHMessage(msg, args);
+    ErrorListener ehandler = this.getErrorListener();
+
+    TransformerException te = new TransformerException(fmsg, m_sourceLocator);
+    if (null != ehandler)
+    {
+      // TO DO: Need to get stylesheet Locator from here.
+      ehandler.fatalError(te);
+    }
+    else
+    {
+      // System.err.println(fmsg);
+      throw te;
+    }
+  }
+
+  /**
+   * This method is added to support DOM 3 XPath API.
+   * <p>
+   * This method is exactly like error(String, Object[]); except that
+   * the underlying TransformerException is 
+   * XpathStylesheetDOM3Exception (which extends TransformerException).
+   * <p>
+   * So older XPath code in Xalan is not affected by this. To older XPath code
+   * the behavior of whether error() or errorForDOM3() is called because it is
+   * always catching TransformerException objects and is oblivious to
+   * the new subclass of XPathStylesheetDOM3Exception. Older XPath code 
+   * runs as before.
+   * <p>
+   * However, newer DOM3 XPath code upon catching a TransformerException can
+   * can check if the exception is an instance of XPathStylesheetDOM3Exception
+   * and take appropriate action.
+   * 
+   * @param msg An error msgkey that corresponds to one of the constants found 
+   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
+   *            a key for a format string.
+   * @param args An array of arguments represented in the format string, which 
+   *             may be null.
+   *
+   * @throws TransformerException if the current ErrorListoner determines to 
+   *                              throw an exception.
+   */
+  void errorForDOM3(String msg, Object[] args) throws TransformerException
+  {
+
+	String fmsg = XSLMessages.createXPATHMessage(msg, args);
+	ErrorListener ehandler = this.getErrorListener();
+
+	TransformerException te = new XPathStylesheetDOM3Exception(fmsg, m_sourceLocator);
+	if (null != ehandler)
+	{
+	  // TO DO: Need to get stylesheet Locator from here.
+	  ehandler.fatalError(te);
+	}
+	else
+	{
+	  // System.err.println(fmsg);
+	  throw te;
+	}
+  }
+  /**
+   * Dump the remaining token queue.
+   * Thanks to Craig for this.
+   *
+   * @return A dump of the remaining token queue, which may be appended to 
+   *         an error message.
+   */
+  protected String dumpRemainingTokenQueue()
+  {
+
+    int q = m_queueMark;
+    String returnMsg;
+
+    if (q < m_ops.getTokenQueueSize())
+    {
+      String msg = "\n Remaining tokens: (";
+
+      while (q < m_ops.getTokenQueueSize())
+      {
+        String t = (String) m_ops.m_tokenQueue.elementAt(q++);
+
+        msg += (" '" + t + "'");
+      }
+
+      returnMsg = msg + ")";
+    }
+    else
+    {
+      returnMsg = "";
+    }
+
+    return returnMsg;
+  }
+
+  /**
+   * Given a string, return the corresponding function token.
+   *
+   * @param key A local name of a function.
+   *
+   * @return   The function ID, which may correspond to one of the FUNC_XXX 
+   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
+   *    be a value installed by an external module.
+   */
+  final int getFunctionToken(String key)
+  {
+
+    int tok;
+    
+    Object id;
+
+    try
+    {
+      // These are nodetests, xpathparser treats them as functions when parsing
+      // a FilterExpr. 
+      id = Keywords.lookupNodeTest(key);
+      if (null == id) id = m_functionTable.getFunctionID(key);
+      tok = ((Integer) id).intValue();
+    }
+    catch (NullPointerException npe)
+    {
+      tok = -1;
+    }
+    catch (ClassCastException cce)
+    {
+      tok = -1;
+    }
+
+    return tok;
+  }
+
+  /**
+   * Insert room for operation.  This will NOT set
+   * the length value of the operation, but will update
+   * the length value for the total expression.
+   *
+   * @param pos The position where the op is to be inserted.
+   * @param length The length of the operation space in the op map.
+   * @param op The op code to the inserted.
+   */
+  void insertOp(int pos, int length, int op)
+  {
+
+    int totalLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    for (int i = totalLen - 1; i >= pos; i--)
+    {
+      m_ops.setOp(i + length, m_ops.getOp(i));
+    }
+
+    m_ops.setOp(pos,op);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH,totalLen + length);
+  }
+
+  /**
+   * Insert room for operation.  This WILL set
+   * the length value of the operation, and will update
+   * the length value for the total expression.
+   *
+   * @param length The length of the operation.
+   * @param op The op code to the inserted.
+   */
+  void appendOp(int length, int op)
+  {
+
+    int totalLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    m_ops.setOp(totalLen, op);
+    m_ops.setOp(totalLen + OpMap.MAPINDEX_LENGTH, length);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, totalLen + length);
+  }
+
+  // ============= EXPRESSIONS FUNCTIONS =================
+
+  /**
+   *
+   *
+   * Expr  ::=  OrExpr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Expr() throws javax.xml.transform.TransformerException
+  {
+    OrExpr();
+  }
+
+  /**
+   *
+   *
+   * OrExpr  ::=  AndExpr
+   * | OrExpr 'or' AndExpr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void OrExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    AndExpr();
+
+    if ((null != m_token) && tokenIs("or"))
+    {
+      nextToken();
+      insertOp(opPos, 2, OpCodes.OP_OR);
+      OrExpr();
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+    }
+  }
+
+  /**
+   *
+   *
+   * AndExpr  ::=  EqualityExpr
+   * | AndExpr 'and' EqualityExpr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void AndExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    EqualityExpr(-1);
+
+    if ((null != m_token) && tokenIs("and"))
+    {
+      nextToken();
+      insertOp(opPos, 2, OpCodes.OP_AND);
+      AndExpr();
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+    }
+  }
+
+  /**
+   *
+   * @returns an Object which is either a String, a Number, a Boolean, or a vector
+   * of nodes.
+   *
+   * EqualityExpr  ::=  RelationalExpr
+   * | EqualityExpr '=' RelationalExpr
+   *
+   *
+   * @param addPos Position where expression is to be added, or -1 for append.
+   *
+   * @return the position at the end of the equality expression.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if (-1 == addPos)
+      addPos = opPos;
+
+    RelationalExpr(-1);
+
+    if (null != m_token)
+    {
+      if (tokenIs('!') && lookahead('=', 1))
+      {
+        nextToken();
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_NOTEQUALS);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = EqualityExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs('='))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_EQUALS);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = EqualityExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+    }
+
+    return addPos;
+  }
+
+  /**
+   * .
+   * @returns an Object which is either a String, a Number, a Boolean, or a vector
+   * of nodes.
+   *
+   * RelationalExpr  ::=  AdditiveExpr
+   * | RelationalExpr '<' AdditiveExpr
+   * | RelationalExpr '>' AdditiveExpr
+   * | RelationalExpr '<=' AdditiveExpr
+   * | RelationalExpr '>=' AdditiveExpr
+   *
+   *
+   * @param addPos Position where expression is to be added, or -1 for append.
+   *
+   * @return the position at the end of the relational expression.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if (-1 == addPos)
+      addPos = opPos;
+
+    AdditiveExpr(-1);
+
+    if (null != m_token)
+    {
+      if (tokenIs('<'))
+      {
+        nextToken();
+
+        if (tokenIs('='))
+        {
+          nextToken();
+          insertOp(addPos, 2, OpCodes.OP_LTE);
+        }
+        else
+        {
+          insertOp(addPos, 2, OpCodes.OP_LT);
+        }
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = RelationalExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, 
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs('>'))
+      {
+        nextToken();
+
+        if (tokenIs('='))
+        {
+          nextToken();
+          insertOp(addPos, 2, OpCodes.OP_GTE);
+        }
+        else
+        {
+          insertOp(addPos, 2, OpCodes.OP_GT);
+        }
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = RelationalExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+    }
+
+    return addPos;
+  }
+
+  /**
+   * This has to handle construction of the operations so that they are evaluated
+   * in pre-fix order.  So, for 9+7-6, instead of |+|9|-|7|6|, this needs to be
+   * evaluated as |-|+|9|7|6|.
+   *
+   * AdditiveExpr  ::=  MultiplicativeExpr
+   * | AdditiveExpr '+' MultiplicativeExpr
+   * | AdditiveExpr '-' MultiplicativeExpr
+   *
+   *
+   * @param addPos Position where expression is to be added, or -1 for append.
+   *
+   * @return the position at the end of the equality expression.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if (-1 == addPos)
+      addPos = opPos;
+
+    MultiplicativeExpr(-1);
+
+    if (null != m_token)
+    {
+      if (tokenIs('+'))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_PLUS);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = AdditiveExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs('-'))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_MINUS);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = AdditiveExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, 
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+    }
+
+    return addPos;
+  }
+
+  /**
+   * This has to handle construction of the operations so that they are evaluated
+   * in pre-fix order.  So, for 9+7-6, instead of |+|9|-|7|6|, this needs to be
+   * evaluated as |-|+|9|7|6|.
+   *
+   * MultiplicativeExpr  ::=  UnaryExpr
+   * | MultiplicativeExpr MultiplyOperator UnaryExpr
+   * | MultiplicativeExpr 'div' UnaryExpr
+   * | MultiplicativeExpr 'mod' UnaryExpr
+   * | MultiplicativeExpr 'quo' UnaryExpr
+   *
+   * @param addPos Position where expression is to be added, or -1 for append.
+   *
+   * @return the position at the end of the equality expression.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if (-1 == addPos)
+      addPos = opPos;
+
+    UnaryExpr();
+
+    if (null != m_token)
+    {
+      if (tokenIs('*'))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_MULT);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = MultiplicativeExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs("div"))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_DIV);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = MultiplicativeExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs("mod"))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_MOD);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = MultiplicativeExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+      else if (tokenIs("quo"))
+      {
+        nextToken();
+        insertOp(addPos, 2, OpCodes.OP_QUO);
+
+        int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+        addPos = MultiplicativeExpr(addPos);
+        m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
+        addPos += 2;
+      }
+    }
+
+    return addPos;
+  }
+
+  /**
+   *
+   * UnaryExpr  ::=  UnionExpr
+   * | '-' UnaryExpr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void UnaryExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    boolean isNeg = false;
+
+    if (m_tokenChar == '-')
+    {
+      nextToken();
+      appendOp(2, OpCodes.OP_NEG);
+
+      isNeg = true;
+    }
+
+    UnionExpr();
+
+    if (isNeg)
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   *
+   * StringExpr  ::=  Expr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void StringExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    appendOp(2, OpCodes.OP_STRING);
+    Expr();
+
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   *
+   *
+   * StringExpr  ::=  Expr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void BooleanExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    appendOp(2, OpCodes.OP_BOOL);
+    Expr();
+
+    int opLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos;
+
+    if (opLen == 2)
+    {
+      error(XPATHErrorResources.ER_BOOLEAN_ARG_NO_LONGER_OPTIONAL, null);  //"boolean(...) argument is no longer optional with 19990709 XPath draft.");
+    }
+
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, opLen);
+  }
+
+  /**
+   *
+   *
+   * NumberExpr  ::=  Expr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void NumberExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    appendOp(2, OpCodes.OP_NUMBER);
+    Expr();
+
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   * The context of the right hand side expressions is the context of the
+   * left hand side expression. The results of the right hand side expressions
+   * are node sets. The result of the left hand side UnionExpr is the union
+   * of the results of the right hand side expressions.
+   *
+   *
+   * UnionExpr    ::=    PathExpr
+   * | UnionExpr '|' PathExpr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void UnionExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    boolean continueOrLoop = true;
+    boolean foundUnion = false;
+
+    do
+    {
+      PathExpr();
+
+      if (tokenIs('|'))
+      {
+        if (false == foundUnion)
+        {
+          foundUnion = true;
+
+          insertOp(opPos, 2, OpCodes.OP_UNION);
+        }
+
+        nextToken();
+      }
+      else
+      {
+        break;
+      }
+
+      // this.m_testForDocOrder = true;
+    }
+    while (continueOrLoop);
+
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   * PathExpr  ::=  LocationPath
+   * | FilterExpr
+   * | FilterExpr '/' RelativeLocationPath
+   * | FilterExpr '//' RelativeLocationPath
+   *
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void PathExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    int filterExprMatch = FilterExpr();
+
+    if (filterExprMatch != FILTER_MATCH_FAILED)
+    {
+      // If FilterExpr had Predicates, a OP_LOCATIONPATH opcode would already
+      // have been inserted.
+      boolean locationPathStarted = (filterExprMatch==FILTER_MATCH_PREDICATES);
+
+      if (tokenIs('/'))
+      {
+        nextToken();
+
+        if (!locationPathStarted)
+        {
+          // int locationPathOpPos = opPos;
+          insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
+
+          locationPathStarted = true;
+        }
+
+        if (!RelativeLocationPath())
+        {
+          // "Relative location path expected following '/' or '//'"
+          error(XPATHErrorResources.ER_EXPECTED_REL_LOC_PATH, null);
+        }
+
+      }
+
+      // Terminate for safety.
+      if (locationPathStarted)
+      {
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+        m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+        m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+      }
+    }
+    else
+    {
+      LocationPath();
+    }
+  }
+
+  /**
+   *
+   *
+   * FilterExpr  ::=  PrimaryExpr
+   * | FilterExpr Predicate
+   *
+   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
+   * the error condition is severe enough to halt processing.
+   *
+   * @return  FILTER_MATCH_PREDICATES, if this method successfully matched a
+   *          FilterExpr with one or more Predicates;
+   *          FILTER_MATCH_PRIMARY, if this method successfully matched a
+   *          FilterExpr that was just a PrimaryExpr; or
+   *          FILTER_MATCH_FAILED, if this method did not match a FilterExpr
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int FilterExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    int filterMatch;
+
+    if (PrimaryExpr())
+    {
+      if (tokenIs('['))
+      {
+
+        // int locationPathOpPos = opPos;
+        insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
+
+        while (tokenIs('['))
+        {
+          Predicate();
+        }
+
+        filterMatch = FILTER_MATCH_PREDICATES;
+      }
+      else
+      {
+        filterMatch = FILTER_MATCH_PRIMARY;
+      }
+    }
+    else
+    {
+      filterMatch = FILTER_MATCH_FAILED;
+    }
+
+    return filterMatch;
+
+    /*
+     * if(tokenIs('['))
+     * {
+     *   Predicate();
+     *   m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+     * }
+     */
+  }
+
+  /**
+   *
+   * PrimaryExpr  ::=  VariableReference
+   * | '(' Expr ')'
+   * | Literal
+   * | Number
+   * | FunctionCall
+   *
+   * @return true if this method successfully matched a PrimaryExpr
+   *
+   * @throws javax.xml.transform.TransformerException
+   *
+   */
+  protected boolean PrimaryExpr() throws javax.xml.transform.TransformerException
+  {
+
+    boolean matchFound;
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if ((m_tokenChar == '\'') || (m_tokenChar == '"'))
+    {
+      appendOp(2, OpCodes.OP_LITERAL);
+      Literal();
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, 
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      matchFound = true;
+    }
+    else if (m_tokenChar == '$')
+    {
+      nextToken();  // consume '$'
+      appendOp(2, OpCodes.OP_VARIABLE);
+      QName();
+      
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      matchFound = true;
+    }
+    else if (m_tokenChar == '(')
+    {
+      nextToken();
+      appendOp(2, OpCodes.OP_GROUP);
+      Expr();
+      consumeExpected(')');
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      matchFound = true;
+    }
+    else if ((null != m_token) && ((('.' == m_tokenChar) && (m_token.length() > 1) && Character.isDigit(
+            m_token.charAt(1))) || Character.isDigit(m_tokenChar)))
+    {
+      appendOp(2, OpCodes.OP_NUMBERLIT);
+      Number();
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      matchFound = true;
+    }
+    else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3)))
+    {
+      matchFound = FunctionCall();
+    }
+    else
+    {
+      matchFound = false;
+    }
+
+    return matchFound;
+  }
+
+  /**
+   *
+   * Argument    ::=    Expr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Argument() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    appendOp(2, OpCodes.OP_ARGUMENT);
+    Expr();
+
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   *
+   * FunctionCall    ::=    FunctionName '(' ( Argument ( ',' Argument)*)? ')'
+   *
+   * @return true if, and only if, a FunctionCall was matched
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected boolean FunctionCall() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    if (lookahead(':', 1))
+    {
+      appendOp(4, OpCodes.OP_EXTFUNCTION);
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1, m_queueMark - 1);
+
+      nextToken();
+      consumeExpected(':');
+
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 2, m_queueMark - 1);
+
+      nextToken();
+    }
+    else
+    {
+      int funcTok = getFunctionToken(m_token);
+
+      if (-1 == funcTok)
+      {
+        error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
+              new Object[]{ m_token });  //"Could not find function: "+m_token+"()");
+      }
+
+      switch (funcTok)
+      {
+      case OpCodes.NODETYPE_PI :
+      case OpCodes.NODETYPE_COMMENT :
+      case OpCodes.NODETYPE_TEXT :
+      case OpCodes.NODETYPE_NODE :
+        // Node type tests look like function calls, but they're not
+        return false;
+      default :
+        appendOp(3, OpCodes.OP_FUNCTION);
+
+        m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1, funcTok);
+      }
+
+      nextToken();
+    }
+
+    consumeExpected('(');
+
+    while (!tokenIs(')') && m_token != null)
+    {
+      if (tokenIs(','))
+      {
+        error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null);  //"Found ',' but no preceding argument!");
+      }
+
+      Argument();
+
+      if (!tokenIs(')'))
+      {
+        consumeExpected(',');
+
+        if (tokenIs(')'))
+        {
+          error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG,
+                null);  //"Found ',' but no following argument!");
+        }
+      }
+    }
+
+    consumeExpected(')');
+
+    // Terminate for safety.
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH,m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, 
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+    return true;
+  }
+
+  // ============= GRAMMAR FUNCTIONS =================
+
+  /**
+   *
+   * LocationPath ::= RelativeLocationPath
+   * | AbsoluteLocationPath
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void LocationPath() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    // int locationPathOpPos = opPos;
+    appendOp(2, OpCodes.OP_LOCATIONPATH);
+
+    boolean seenSlash = tokenIs('/');
+
+    if (seenSlash)
+    {
+      appendOp(4, OpCodes.FROM_ROOT);
+
+      // Tell how long the step is without the predicate
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2, 4);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_ROOT);
+
+      nextToken();
+    } else if (m_token == null) {
+      error(XPATHErrorResources.ER_EXPECTED_LOC_PATH_AT_END_EXPR, null);
+    }
+
+    if (m_token != null)
+    {
+      if (!RelativeLocationPath() && !seenSlash)
+      {
+        // Neither a '/' nor a RelativeLocationPath - i.e., matched nothing
+        // "Location path expected, but found "+m_token+" was encountered."
+        error(XPATHErrorResources.ER_EXPECTED_LOC_PATH, 
+              new Object [] {m_token});
+      }
+    }
+
+    // Terminate for safety.
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH,m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   *
+   * RelativeLocationPath ::= Step
+   * | RelativeLocationPath '/' Step
+   * | AbbreviatedRelativeLocationPath
+   *
+   * @returns true if, and only if, a RelativeLocationPath was matched
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected boolean RelativeLocationPath()
+               throws javax.xml.transform.TransformerException
+  {
+    if (!Step())
+    {
+      return false;
+    }
+
+    while (tokenIs('/'))
+    {
+      nextToken();
+
+      if (!Step())
+      {
+        // RelativeLocationPath can't end with a trailing '/'
+        // "Location step expected following '/' or '//'"
+        error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   *
+   * Step    ::=    Basis Predicate
+   * | AbbreviatedStep
+   *
+   * @returns false if step was empty (or only a '/'); true, otherwise
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected boolean Step() throws javax.xml.transform.TransformerException
+  {
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    boolean doubleSlash = tokenIs('/');
+
+    // At most a single '/' before each Step is consumed by caller; if the
+    // first thing is a '/', that means we had '//' and the Step must not
+    // be empty.
+    if (doubleSlash)
+    {
+      nextToken();
+
+      appendOp(2, OpCodes.FROM_DESCENDANTS_OR_SELF);
+
+      // Have to fix up for patterns such as '//@foo' or '//attribute::foo',
+      // which translate to 'descendant-or-self::node()/attribute::foo'.
+      // notice I leave the '/' on the queue, so the next will be processed
+      // by a regular step pattern.
+
+      // Make room for telling how long the step is without the predicate
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH,m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.NODETYPE_NODE);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH,m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      // Tell how long the step is without the predicate
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1,
+          m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      // Tell how long the step is with the predicate
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+          m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+      opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    }
+
+    if (tokenIs("."))
+    {
+      nextToken();
+
+      if (tokenIs('['))
+      {
+        error(XPATHErrorResources.ER_PREDICATE_ILLEGAL_SYNTAX, null);  //"'..[predicate]' or '.[predicate]' is illegal syntax.  Use 'self::node()[predicate]' instead.");
+      }
+
+      appendOp(4, OpCodes.FROM_SELF);
+
+      // Tell how long the step is without the predicate
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2,4);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_NODE);
+    }
+    else if (tokenIs(".."))
+    {
+      nextToken();
+      appendOp(4, OpCodes.FROM_PARENT);
+
+      // Tell how long the step is without the predicate
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2,4);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_NODE);
+    }
+
+    // There is probably a better way to test for this 
+    // transition... but it gets real hairy if you try 
+    // to do it in basis().
+    else if (tokenIs('*') || tokenIs('@') || tokenIs('_')
+             || (m_token!= null && Character.isLetter(m_token.charAt(0))))
+    {
+      Basis();
+
+      while (tokenIs('['))
+      {
+        Predicate();
+      }
+
+      // Tell how long the entire step is.
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+        m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos); 
+    }
+    else
+    {
+      // No Step matched - that's an error if previous thing was a '//'
+      if (doubleSlash)
+      {
+        // "Location step expected following '/' or '//'"
+        error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
+      }
+
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   *
+   * Basis    ::=    AxisName '::' NodeTest
+   * | AbbreviatedBasis
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Basis() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    int axesType;
+
+    // The next blocks guarantee that a FROM_XXX will be added.
+    if (lookahead("::", 1))
+    {
+      axesType = AxisName();
+
+      nextToken();
+      nextToken();
+    }
+    else if (tokenIs('@'))
+    {
+      axesType = OpCodes.FROM_ATTRIBUTES;
+
+      appendOp(2, axesType);
+      nextToken();
+    }
+    else
+    {
+      axesType = OpCodes.FROM_CHILDREN;
+
+      appendOp(2, axesType);
+    }
+
+    // Make room for telling how long the step is without the predicate
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+    NodeTest(axesType);
+
+    // Tell how long the step is without the predicate
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+   }
+
+  /**
+   *
+   * Basis    ::=    AxisName '::' NodeTest
+   * | AbbreviatedBasis
+   *
+   * @return FROM_XXX axes type, found in {@link org.apache.xpath.compiler.Keywords}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected int AxisName() throws javax.xml.transform.TransformerException
+  {
+
+    Object val = Keywords.getAxisName(m_token);
+
+    if (null == val)
+    {
+      error(XPATHErrorResources.ER_ILLEGAL_AXIS_NAME,
+            new Object[]{ m_token });  //"illegal axis name: "+m_token);
+    }
+
+    int axesType = ((Integer) val).intValue();
+
+    appendOp(2, axesType);
+
+    return axesType;
+  }
+
+  /**
+   *
+   * NodeTest    ::=    WildcardName
+   * | NodeType '(' ')'
+   * | 'processing-instruction' '(' Literal ')'
+   *
+   * @param axesType FROM_XXX axes type, found in {@link org.apache.xpath.compiler.Keywords}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void NodeTest(int axesType) throws javax.xml.transform.TransformerException
+  {
+
+    if (lookahead('(', 1))
+    {
+      Object nodeTestOp = Keywords.getNodeType(m_token);
+
+      if (null == nodeTestOp)
+      {
+        error(XPATHErrorResources.ER_UNKNOWN_NODETYPE,
+              new Object[]{ m_token });  //"Unknown nodetype: "+m_token);
+      }
+      else
+      {
+        nextToken();
+
+        int nt = ((Integer) nodeTestOp).intValue();
+
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), nt);
+        m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+        consumeExpected('(');
+
+        if (OpCodes.NODETYPE_PI == nt)
+        {
+          if (!tokenIs(')'))
+          {
+            Literal();
+          }
+        }
+
+        consumeExpected(')');
+      }
+    }
+    else
+    {
+
+      // Assume name of attribute or element.
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.NODENAME);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      if (lookahead(':', 1))
+      {
+        if (tokenIs('*'))
+        {
+          m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD);
+        }
+        else
+        {
+          m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+
+          // Minimalist check for an NCName - just check first character
+          // to distinguish from other possible tokens
+          if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+          {
+            // "Node test that matches either NCName:* or QName was expected."
+            error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
+          }
+        }
+
+        nextToken();
+        consumeExpected(':');
+      }
+      else
+      {
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.EMPTY);
+      }
+
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      if (tokenIs('*'))
+      {
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD);
+      }
+      else
+      {
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+
+        // Minimalist check for an NCName - just check first character
+        // to distinguish from other possible tokens
+        if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+        {
+          // "Node test that matches either NCName:* or QName was expected."
+          error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
+        }
+      }
+
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      nextToken();
+    }
+  }
+
+  /**
+   *
+   * Predicate ::= '[' PredicateExpr ']'
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Predicate() throws javax.xml.transform.TransformerException
+  {
+
+    if (tokenIs('['))
+    {
+      nextToken();
+      PredicateExpr();
+      consumeExpected(']');
+    }
+  }
+
+  /**
+   *
+   * PredicateExpr ::= Expr
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void PredicateExpr() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    appendOp(2, OpCodes.OP_PREDICATE);
+    Expr();
+
+    // Terminate for safety.
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   * QName ::=  (Prefix ':')? LocalPart
+   * Prefix ::=  NCName
+   * LocalPart ::=  NCName
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void QName() throws javax.xml.transform.TransformerException
+  {
+    // Namespace
+    if(lookahead(':', 1))
+    {
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      nextToken();
+      consumeExpected(':');
+    }
+    else
+    {
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.EMPTY);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+    }
+    
+    // Local name
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+    nextToken();
+  }
+
+  /**
+   * NCName ::=  (Letter | '_') (NCNameChar)
+   * NCNameChar ::=  Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
+   */
+  protected void NCName()
+  {
+
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+    nextToken();
+  }
+
+  /**
+   * The value of the Literal is the sequence of characters inside
+   * the " or ' characters>.
+   *
+   * Literal  ::=  '"' [^"]* '"'
+   * | "'" [^']* "'"
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Literal() throws javax.xml.transform.TransformerException
+  {
+
+    int last = m_token.length() - 1;
+    char c0 = m_tokenChar;
+    char cX = m_token.charAt(last);
+
+    if (((c0 == '\"') && (cX == '\"')) || ((c0 == '\'') && (cX == '\'')))
+    {
+
+      // Mutate the token to remove the quotes and have the XString object
+      // already made.
+      int tokenQueuePos = m_queueMark - 1;
+
+      m_ops.m_tokenQueue.setElementAt(null,tokenQueuePos);
+
+      Object obj = new XString(m_token.substring(1, last));
+
+      m_ops.m_tokenQueue.setElementAt(obj,tokenQueuePos);
+
+      // lit = m_token.substring(1, last);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), tokenQueuePos);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      nextToken();
+    }
+    else
+    {
+      error(XPATHErrorResources.ER_PATTERN_LITERAL_NEEDS_BE_QUOTED,
+            new Object[]{ m_token });  //"Pattern literal ("+m_token+") needs to be quoted!");
+    }
+  }
+
+  /**
+   *
+   * Number ::= [0-9]+('.'[0-9]+)? | '.'[0-9]+
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Number() throws javax.xml.transform.TransformerException
+  {
+
+    if (null != m_token)
+    {
+
+      // Mutate the token to remove the quotes and have the XNumber object
+      // already made.
+      double num;
+
+      try
+      {
+      	// XPath 1.0 does not support number in exp notation
+      	if ((m_token.indexOf('e') > -1)||(m_token.indexOf('E') > -1))
+      		throw new NumberFormatException();
+        num = Double.valueOf(m_token).doubleValue();
+      }
+      catch (NumberFormatException nfe)
+      {
+        num = 0.0;  // to shut up compiler.
+
+        error(XPATHErrorResources.ER_COULDNOT_BE_FORMATTED_TO_NUMBER,
+              new Object[]{ m_token });  //m_token+" could not be formatted to a number!");
+      }
+
+      m_ops.m_tokenQueue.setElementAt(new XNumber(num),m_queueMark - 1);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
+      m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+      nextToken();
+    }
+  }
+
+  // ============= PATTERN FUNCTIONS =================
+
+  /**
+   *
+   * Pattern  ::=  LocationPathPattern
+   * | Pattern '|' LocationPathPattern
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void Pattern() throws javax.xml.transform.TransformerException
+  {
+
+    while (true)
+    {
+      LocationPathPattern();
+
+      if (tokenIs('|'))
+      {
+        nextToken();
+      }
+      else
+      {
+        break;
+      }
+    }
+  }
+
+  /**
+   *
+   *
+   * LocationPathPattern  ::=  '/' RelativePathPattern?
+   * | IdKeyPattern (('/' | '//') RelativePathPattern)?
+   * | '//'? RelativePathPattern
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void LocationPathPattern() throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+
+    final int RELATIVE_PATH_NOT_PERMITTED = 0;
+    final int RELATIVE_PATH_PERMITTED     = 1;
+    final int RELATIVE_PATH_REQUIRED      = 2;
+
+    int relativePathStatus = RELATIVE_PATH_NOT_PERMITTED;
+
+    appendOp(2, OpCodes.OP_LOCATIONPATHPATTERN);
+
+    if (lookahead('(', 1)
+            && (tokenIs(Keywords.FUNC_ID_STRING)
+                || tokenIs(Keywords.FUNC_KEY_STRING)))
+    {
+      IdKeyPattern();
+
+      if (tokenIs('/'))
+      {
+        nextToken();
+
+        if (tokenIs('/'))
+        {
+          appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
+
+          nextToken();
+        }
+        else
+        {
+          appendOp(4, OpCodes.MATCH_IMMEDIATE_ANCESTOR);
+        }
+
+        // Tell how long the step is without the predicate
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2, 4);
+        m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_FUNCTEST);
+
+        relativePathStatus = RELATIVE_PATH_REQUIRED;
+      }
+    }
+    else if (tokenIs('/'))
+    {
+      if (lookahead('/', 1))
+      {
+        appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
+        
+        // Added this to fix bug reported by Myriam for match="//x/a"
+        // patterns.  If you don't do this, the 'x' step will think it's part
+        // of a '//' pattern, and so will cause 'a' to be matched when it has
+        // any ancestor that is 'x'.
+        nextToken();
+
+        relativePathStatus = RELATIVE_PATH_REQUIRED;
+      }
+      else
+      {
+        appendOp(4, OpCodes.FROM_ROOT);
+
+        relativePathStatus = RELATIVE_PATH_PERMITTED;
+      }
+
+
+      // Tell how long the step is without the predicate
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2, 4);
+      m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_ROOT);
+
+      nextToken();
+    }
+    else
+    {
+      relativePathStatus = RELATIVE_PATH_REQUIRED;
+    }
+
+    if (relativePathStatus != RELATIVE_PATH_NOT_PERMITTED)
+    {
+      if (!tokenIs('|') && (null != m_token))
+      {
+        RelativePathPattern();
+      }
+      else if (relativePathStatus == RELATIVE_PATH_REQUIRED)
+      {
+        // "A relative path pattern was expected."
+        error(XPATHErrorResources.ER_EXPECTED_REL_PATH_PATTERN, null);
+      }
+    }
+
+    // Terminate for safety.
+    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+  }
+
+  /**
+   *
+   * IdKeyPattern  ::=  'id' '(' Literal ')'
+   * | 'key' '(' Literal ',' Literal ')'
+   * (Also handle doc())
+   *
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void IdKeyPattern() throws javax.xml.transform.TransformerException
+  {
+    FunctionCall();
+  }
+
+  /**
+   *
+   * RelativePathPattern  ::=  StepPattern
+   * | RelativePathPattern '/' StepPattern
+   * | RelativePathPattern '//' StepPattern
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void RelativePathPattern()
+              throws javax.xml.transform.TransformerException
+  {
+
+    // Caller will have consumed any '/' or '//' preceding the
+    // RelativePathPattern, so let StepPattern know it can't begin with a '/'
+    boolean trailingSlashConsumed = StepPattern(false);
+
+    while (tokenIs('/'))
+    {
+      nextToken();
+
+      // StepPattern() may consume first slash of pair in "a//b" while
+      // processing StepPattern "a".  On next iteration, let StepPattern know
+      // that happened, so it doesn't match ill-formed patterns like "a///b".
+      trailingSlashConsumed = StepPattern(!trailingSlashConsumed);
+    }
+  }
+
+  /**
+   *
+   * StepPattern  ::=  AbbreviatedNodeTestStep
+   *
+   * @param isLeadingSlashPermitted a boolean indicating whether a slash can
+   *        appear at the start of this step
+   *
+   * @return boolean indicating whether a slash following the step was consumed
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected boolean StepPattern(boolean isLeadingSlashPermitted)
+            throws javax.xml.transform.TransformerException
+  {
+    return AbbreviatedNodeTestStep(isLeadingSlashPermitted);
+  }
+
+  /**
+   *
+   * AbbreviatedNodeTestStep    ::=    '@'? NodeTest Predicate
+   *
+   * @param isLeadingSlashPermitted a boolean indicating whether a slash can
+   *        appear at the start of this step
+   *
+   * @return boolean indicating whether a slash following the step was consumed
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted)
+            throws javax.xml.transform.TransformerException
+  {
+
+    int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    int axesType;
+
+    // The next blocks guarantee that a MATCH_XXX will be added.
+    int matchTypePos = -1;
+
+    if (tokenIs('@'))
+    {
+      axesType = OpCodes.MATCH_ATTRIBUTE;
+
+      appendOp(2, axesType);
+      nextToken();
+    }
+    else if (this.lookahead("::", 1))
+    {
+      if (tokenIs("attribute"))
+      {
+        axesType = OpCodes.MATCH_ATTRIBUTE;
+
+        appendOp(2, axesType);
+      }
+      else if (tokenIs("child"))
+      {
+        matchTypePos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+        axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
+
+        appendOp(2, axesType);
+      }
+      else
+      {
+        axesType = -1;
+
+        this.error(XPATHErrorResources.ER_AXES_NOT_ALLOWED,
+                   new Object[]{ this.m_token });
+      }
+
+      nextToken();
+      nextToken();
+    }
+    else if (tokenIs('/'))
+    {
+      if (!isLeadingSlashPermitted)
+      {
+        // "A step was expected in the pattern, but '/' was encountered."
+        error(XPATHErrorResources.ER_EXPECTED_STEP_PATTERN, null);
+      }
+      axesType = OpCodes.MATCH_ANY_ANCESTOR;
+
+      appendOp(2, axesType);
+      nextToken();
+    }
+    else
+    {
+      matchTypePos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+      axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
+
+      appendOp(2, axesType);
+    }
+
+    // Make room for telling how long the step is without the predicate
+    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
+
+    NodeTest(axesType);
+
+    // Tell how long the step is without the predicate
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+    while (tokenIs('['))
+    {
+      Predicate();
+    }
+
+    boolean trailingSlashConsumed;
+
+    // For "a//b", where "a" is current step, we need to mark operation of
+    // current step as "MATCH_ANY_ANCESTOR".  Then we'll consume the first
+    // slash and subsequent step will be treated as a MATCH_IMMEDIATE_ANCESTOR
+    // (unless it too is followed by '//'.)
+    //
+    // %REVIEW%  Following is what happens today, but I'm not sure that's
+    // %REVIEW%  correct behaviour.  Perhaps no valid case could be constructed
+    // %REVIEW%  where it would matter?
+    //
+    // If current step is on the attribute axis (e.g., "@x//b"), we won't
+    // change the current step, and let following step be marked as
+    // MATCH_ANY_ANCESTOR on next call instead.
+    if ((matchTypePos > -1) && tokenIs('/') && lookahead('/', 1))
+    {
+      m_ops.setOp(matchTypePos, OpCodes.MATCH_ANY_ANCESTOR);
+
+      nextToken();
+
+      trailingSlashConsumed = true;
+    }
+    else
+    {
+      trailingSlashConsumed = false;
+    }
+
+    // Tell how long the entire step is.
+    m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+
+    return trailingSlashConsumed;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/compiler/package.html b/src/main/java/org/apache/xpath/compiler/package.html
new file mode 100644
index 0000000..6f45248
--- /dev/null
+++ b/src/main/java/org/apache/xpath/compiler/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<html>
+  <title>XPath parsing and compilation support Package.</title>
+  <body>
+    <p>Implements an XPath parser which produces an OpMap, and a so-called Compiler
+    which produces an expression tree for fast evaluation.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/domapi/XPathStylesheetDOM3Exception.java b/src/main/java/org/apache/xpath/domapi/XPathStylesheetDOM3Exception.java
new file mode 100644
index 0000000..b63eb85
--- /dev/null
+++ b/src/main/java/org/apache/xpath/domapi/XPathStylesheetDOM3Exception.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.apache.xpath.domapi;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+/**
+ *
+ * A new exception to add support for DOM Level 3 XPath API.
+ * This class is needed to throw a org.w3c.dom.DOMException with proper error code in
+ * createExpression method of XPathEvaluatorImpl (a DOM Level 3 class).
+ * 
+ * This class extends TransformerException because the error message includes information
+ * about where the XPath problem is in the stylesheet as well as the XPath expression itself.
+ * 
+ * @xsl.usage internal
+ */
+final public class XPathStylesheetDOM3Exception extends TransformerException {
+	public XPathStylesheetDOM3Exception(String msg, SourceLocator arg1)
+	{
+		super(msg, arg1);
+	}
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncBoolean.java b/src/main/java/org/apache/xpath/functions/FuncBoolean.java
new file mode 100644
index 0000000..36eb203
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncBoolean.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncBoolean.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Boolean() function.
+ * @xsl.usage advanced
+ */
+public class FuncBoolean extends FunctionOneArg
+{
+    static final long serialVersionUID = 4328660760070034592L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return m_arg0.execute(xctxt).bool() ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+  
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncCeiling.java b/src/main/java/org/apache/xpath/functions/FuncCeiling.java
new file mode 100644
index 0000000..f496d25
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncCeiling.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncCeiling.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Ceiling() function.
+ * @xsl.usage advanced
+ */
+public class FuncCeiling extends FunctionOneArg
+{
+    static final long serialVersionUID = -1275988936390464739L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(Math.ceil(m_arg0.execute(xctxt).num()));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncConcat.java b/src/main/java/org/apache/xpath/functions/FuncConcat.java
new file mode 100644
index 0000000..570f585
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncConcat.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncConcat.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the Concat() function.
+ * @xsl.usage advanced
+ */
+public class FuncConcat extends FunctionMultiArgs
+{
+    static final long serialVersionUID = 1737228885202314413L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    StringBuffer sb = new StringBuffer();
+
+    // Compiler says we must have at least two arguments.
+    sb.append(m_arg0.execute(xctxt).str());
+    sb.append(m_arg1.execute(xctxt).str());
+
+    if (null != m_arg2)
+      sb.append(m_arg2.execute(xctxt).str());
+
+    if (null != m_args)
+    {
+      for (int i = 0; i < m_args.length; i++)
+      {
+        sb.append(m_args[i].execute(xctxt).str());
+      }
+    }
+
+    return new XString(sb.toString());
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum < 2)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("gtone", null));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncContains.java b/src/main/java/org/apache/xpath/functions/FuncContains.java
new file mode 100644
index 0000000..0c6849f
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncContains.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncContains.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Contains() function.
+ * @xsl.usage advanced
+ */
+public class FuncContains extends Function2Args
+{
+    static final long serialVersionUID = 5084753781887919723L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String s1 = m_arg0.execute(xctxt).str();
+    String s2 = m_arg1.execute(xctxt).str();
+
+    // Add this check for JDK consistency for empty strings.
+    if (s1.length() == 0 && s2.length() == 0)
+      return XBoolean.S_TRUE;
+
+    int index = s1.indexOf(s2);
+
+    return (index > -1) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncCount.java b/src/main/java/org/apache/xpath/functions/FuncCount.java
new file mode 100644
index 0000000..71e7ba8
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncCount.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncCount.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Count() function.
+ * @xsl.usage advanced
+ */
+public class FuncCount extends FunctionOneArg
+{
+    static final long serialVersionUID = -7116225100474153751L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+//    DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
+
+//    // We should probably make a function on the iterator for this, 
+//    // as a given implementation could optimize.
+//    int i = 0;
+//
+//    while (DTM.NULL != nl.nextNode())
+//    {
+//      i++;
+//    }
+//    nl.detach();
+	DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
+	int i = nl.getLength();	
+	nl.detach();
+
+    return new XNumber((double) i);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncCurrent.java b/src/main/java/org/apache/xpath/functions/FuncCurrent.java
new file mode 100644
index 0000000..764cc0d
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncCurrent.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncCurrent.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.LocPathIterator;
+import org.apache.xpath.axes.PredicatedNodeTest;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.axes.SubContextList;
+import org.apache.xpath.patterns.StepPattern;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.res.XSLTErrorResources;
+
+
+/**
+ * Execute the current() function.
+ * @xsl.usage advanced
+ */
+public class FuncCurrent extends Function
+{
+    static final long serialVersionUID = 5715316804877715008L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+   
+    SubContextList subContextList = xctxt.getCurrentNodeList();
+    int currentNode = DTM.NULL;
+
+    if (null != subContextList) {
+        if (subContextList instanceof PredicatedNodeTest) {
+            LocPathIterator iter = ((PredicatedNodeTest)subContextList)
+                                                          .getLocPathIterator();
+            currentNode = iter.getCurrentContextNode();
+         } else if(subContextList instanceof StepPattern) {
+           throw new RuntimeException(XSLMessages.createMessage(
+              XSLTErrorResources.ER_PROCESSOR_ERROR,null));
+         }
+    } else {
+        // not predicate => ContextNode == CurrentNode
+        currentNode = xctxt.getContextNode();
+    }
+    return new XNodeSet(currentNode, xctxt.getDTMManager());
+  }
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncDoclocation.java b/src/main/java/org/apache/xpath/functions/FuncDoclocation.java
new file mode 100644
index 0000000..50d0b15
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncDoclocation.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncDoclocation.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the proprietary document-location() function, which returns
+ * a node set of documents.
+ * @xsl.usage advanced
+ */
+public class FuncDoclocation extends FunctionDef1Arg
+{
+    static final long serialVersionUID = 7469213946343568769L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int whereNode = getArg0AsNode(xctxt);
+    String fileLocation = null;
+
+    if (DTM.NULL != whereNode)
+    {
+      DTM dtm = xctxt.getDTM(whereNode);
+      
+      // %REVIEW%
+      if (DTM.DOCUMENT_FRAGMENT_NODE ==  dtm.getNodeType(whereNode))
+      {
+        whereNode = dtm.getFirstChild(whereNode);
+      }
+
+      if (DTM.NULL != whereNode)
+      {        
+        fileLocation = dtm.getDocumentBaseURI();
+//        int owner = dtm.getDocument();
+//        fileLocation = xctxt.getSourceTreeManager().findURIFromDoc(owner);
+      }
+    }
+
+    return new XString((null != fileLocation) ? fileLocation : "");
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncExtElementAvailable.java b/src/main/java/org/apache/xpath/functions/FuncExtElementAvailable.java
new file mode 100644
index 0000000..5feea0d
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncExtElementAvailable.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncExtElementAvailable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.ExtensionsProvider;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the ExtElementAvailable() function.
+ * @xsl.usage advanced
+ */
+public class FuncExtElementAvailable extends FunctionOneArg
+{
+    static final long serialVersionUID = -472533699257968546L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String prefix;
+    String namespace;
+    String methName;
+
+    String fullName = m_arg0.execute(xctxt).str();
+    int indexOfNSSep = fullName.indexOf(':');
+
+    if (indexOfNSSep < 0)
+    {
+      prefix = "";
+      namespace = Constants.S_XSLNAMESPACEURL;
+      methName = fullName;
+    }
+    else
+    {
+      prefix = fullName.substring(0, indexOfNSSep);
+      namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
+      if (null == namespace)
+        return XBoolean.S_FALSE;
+      methName= fullName.substring(indexOfNSSep + 1);
+    }
+
+    if (namespace.equals(Constants.S_XSLNAMESPACEURL)
+    ||  namespace.equals(Constants.S_BUILTIN_EXTENSIONS_URL))
+    {
+      try
+      {
+        TransformerImpl transformer = (TransformerImpl) xctxt.getOwnerObject();
+        return transformer.getStylesheet().getAvailableElements().containsKey(
+                                                            new QName(namespace, methName))
+               ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+      }
+      catch (Exception e)
+      {
+        return XBoolean.S_FALSE;
+      }
+    }
+    else
+    {
+      //dml
+      ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
+      return extProvider.elementAvailable(namespace, methName)
+             ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncExtFunction.java b/src/main/java/org/apache/xpath/functions/FuncExtFunction.java
new file mode 100644
index 0000000..9293ccc
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncExtFunction.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncExtFunction.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import java.util.Vector;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.ExtensionsProvider;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XNull;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.res.XPATHMessages;
+
+/**
+ * An object of this class represents an extension call expression.  When
+ * the expression executes, it calls ExtensionsTable#extFunction, and then
+ * converts the result to the appropriate XObject.
+ * @xsl.usage advanced
+ */
+public class FuncExtFunction extends Function
+{
+    static final long serialVersionUID = 5196115554693708718L;
+
+  /**
+   * The namespace for the extension function, which should not normally
+   *  be null or empty.
+   *  @serial    
+   */
+  String m_namespace;
+
+  /**
+   * The local name of the extension.
+   *  @serial   
+   */
+  String m_extensionName;
+
+  /**
+   * Unique method key, which is passed to ExtensionsTable#extFunction in
+   *  order to allow caching of the method.
+   *  @serial 
+   */
+  Object m_methodKey;
+
+  /**
+   * Array of static expressions which represent the parameters to the
+   *  function.
+   *  @serial   
+   */
+  Vector m_argVec = new Vector();
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list
+   * should be searched backwards for the first qualified name that
+   * corresponds to the variable reference qname.  The position of the
+   * QName in the vector from the start of the vector will be its position
+   * in the stack frame (but variables above the globalsTop value will need
+   * to be offset to the current stack frame).
+   * NEEDSDOC @param globalsSize
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+
+    if (null != m_argVec)
+    {
+      int nArgs = m_argVec.size();
+
+      for (int i = 0; i < nArgs; i++)
+      {
+        Expression arg = (Expression) m_argVec.elementAt(i);
+
+        arg.fixupVariables(vars, globalsSize);
+      }
+    }
+  }
+  
+  /**
+   * Return the namespace of the extension function.
+   *
+   * @return The namespace of the extension function.
+   */
+  public String getNamespace()
+  {
+    return m_namespace;
+  }
+  
+  /**
+   * Return the name of the extension function.
+   *
+   * @return The name of the extension function.
+   */
+  public String getFunctionName()
+  {
+    return m_extensionName;
+  }
+  
+  /**
+   * Return the method key of the extension function.
+   *
+   * @return The method key of the extension function.
+   */
+  public Object getMethodKey()
+  {
+    return m_methodKey;
+  }
+
+  /** 
+   * Return the nth argument passed to the extension function.
+   * 
+   * @param n The argument number index.
+   * @return The Expression object at the given index.
+   */    
+  public Expression getArg(int n) {
+    if (n >= 0 && n < m_argVec.size())
+      return (Expression) m_argVec.elementAt(n);
+    else
+      return null;
+  }
+
+  /**
+   * Return the number of arguments that were passed
+   * into this extension function.
+   *
+   * @return The number of arguments.
+   */    
+  public int getArgCount() {
+    return m_argVec.size();
+  }
+
+  /**
+   * Create a new FuncExtFunction based on the qualified name of the extension,
+   * and a unique method key.
+   *
+   * @param namespace The namespace for the extension function, which should
+   *                  not normally be null or empty.
+   * @param extensionName The local name of the extension.
+   * @param methodKey Unique method key, which is passed to
+   *                  ExtensionsTable#extFunction in order to allow caching
+   *                  of the method.
+   */
+  public FuncExtFunction(java.lang.String namespace,
+                         java.lang.String extensionName, Object methodKey)
+  {
+    //try{throw new Exception("FuncExtFunction() " + namespace + " " + extensionName);} catch (Exception e){e.printStackTrace();}
+    m_namespace = namespace;
+    m_extensionName = extensionName;
+    m_methodKey = methodKey;
+  }
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    if (xctxt.isSecureProcessing())
+      throw new javax.xml.transform.TransformerException(
+        XPATHMessages.createXPATHMessage(
+          XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,
+          new Object[] {toString()}));
+      
+    XObject result;
+    Vector argVec = new Vector();
+    int nArgs = m_argVec.size();
+
+    for (int i = 0; i < nArgs; i++)
+    {
+      Expression arg = (Expression) m_argVec.elementAt(i);
+      
+      XObject xobj = arg.execute(xctxt);
+      /*
+       * Should cache the arguments for func:function
+       */
+      xobj.allowDetachToRelease(false); 
+      argVec.addElement(xobj);
+    }
+    //dml
+    ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
+    Object val = extProvider.extFunction(this, argVec);
+
+    if (null != val)
+    {
+      result = XObject.create(val, xctxt);
+    }
+    else
+    {
+      result = new XNull();
+    }
+
+    return result;
+  }
+
+  /**
+   * Set an argument expression for a function.  This method is called by the
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If the argNum parameter is beyond what
+   * is specified for this function.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+    m_argVec.addElement(arg);
+    arg.exprSetParent(this);
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException{}
+
+
+  class ArgExtOwner implements ExpressionOwner
+  {
+  
+    Expression m_exp;
+  	
+  	ArgExtOwner(Expression exp)
+  	{
+  		m_exp = exp;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_exp;
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(FuncExtFunction.this);
+    	m_exp = exp;
+    }
+  }
+  
+  
+  /**
+   * Call the visitors for the function arguments.
+   */
+  public void callArgVisitors(XPathVisitor visitor)
+  {
+      for (int i = 0; i < m_argVec.size(); i++)
+      {
+         Expression exp = (Expression)m_argVec.elementAt(i);
+         exp.callVisitors(new ArgExtOwner(exp), visitor);
+      }
+    
+  }
+
+  /**
+   * Set the parent node.
+   * For an extension function, we also need to set the parent
+   * node for all argument expressions.
+   * 
+   * @param n The parent node
+   */
+  public void exprSetParent(ExpressionNode n) 
+  {
+	
+    super.exprSetParent(n);
+      
+    int nArgs = m_argVec.size();
+
+    for (int i = 0; i < nArgs; i++)
+    {
+      Expression arg = (Expression) m_argVec.elementAt(i);
+
+      arg.exprSetParent(n);
+    }		
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.  This class supports an arbitrary
+   * number of arguments, so this method must never be called.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+    String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ "Programmer's assertion:  the method FunctionMultiArgs.reportWrongNumberArgs() should never be called." });
+
+    throw new RuntimeException(fMsg);
+  }
+  
+  /**
+   * Return the name of the extesion function in string format
+   */
+  public String toString()
+  {
+    if (m_namespace != null && m_namespace.length() > 0)
+      return "{" + m_namespace + "}" + m_extensionName;
+    else
+      return m_extensionName;
+  }  
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncExtFunctionAvailable.java b/src/main/java/org/apache/xpath/functions/FuncExtFunctionAvailable.java
new file mode 100644
index 0000000..8e4e5d7
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncExtFunctionAvailable.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncExtFunctionAvailable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xpath.ExtensionsProvider;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.FunctionTable;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the ExtFunctionAvailable() function.
+ * @xsl.usage advanced
+ */
+public class FuncExtFunctionAvailable extends FunctionOneArg
+{
+    static final long serialVersionUID = 5118814314918592241L;
+    
+    transient private FunctionTable m_functionTable = null;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String prefix;
+    String namespace;
+    String methName;
+
+    String fullName = m_arg0.execute(xctxt).str();
+    int indexOfNSSep = fullName.indexOf(':');
+
+    if (indexOfNSSep < 0)
+    {
+      prefix = "";
+      namespace = Constants.S_XSLNAMESPACEURL;
+      methName = fullName;
+    }
+    else
+    {
+      prefix = fullName.substring(0, indexOfNSSep);
+      namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
+      if (null == namespace)
+        return XBoolean.S_FALSE;
+        methName = fullName.substring(indexOfNSSep + 1);
+    }
+
+    if (namespace.equals(Constants.S_XSLNAMESPACEURL))
+    {
+      try
+      {
+        if (null == m_functionTable) m_functionTable = new FunctionTable();
+        return m_functionTable.functionAvailable(methName) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+      }
+      catch (Exception e)
+      {
+        return XBoolean.S_FALSE;
+      }
+    }
+    else
+    {
+      //dml
+      ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
+      return extProvider.functionAvailable(namespace, methName)
+             ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+    }
+  }
+  
+  /**
+   * The function table is an instance field. In order to access this instance 
+   * field during evaluation, this method is called at compilation time to
+   * insert function table information for later usage. It should only be used
+   * during compiling of XPath expressions.
+   * @param aTable an instance of the function table
+   */
+  public void setFunctionTable(FunctionTable aTable){
+          m_functionTable = aTable;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncFalse.java b/src/main/java/org/apache/xpath/functions/FuncFalse.java
new file mode 100644
index 0000000..5bb671b
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncFalse.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncFalse.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the False() function.
+ * @xsl.usage advanced
+ */
+public class FuncFalse extends Function
+{
+    static final long serialVersionUID = 6150918062759769887L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return XBoolean.S_FALSE;
+  }
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncFloor.java b/src/main/java/org/apache/xpath/functions/FuncFloor.java
new file mode 100644
index 0000000..3dda98d
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncFloor.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncFloor.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Floor() function.
+ * @xsl.usage advanced
+ */
+public class FuncFloor extends FunctionOneArg
+{
+    static final long serialVersionUID = 2326752233236309265L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(java.lang.Math.floor(m_arg0.execute(xctxt).num()));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncGenerateId.java b/src/main/java/org/apache/xpath/functions/FuncGenerateId.java
new file mode 100644
index 0000000..a79dcca
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncGenerateId.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncGenerateId.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the GenerateId() function.
+ * @xsl.usage advanced
+ */
+public class FuncGenerateId extends FunctionDef1Arg
+{
+    static final long serialVersionUID = 973544842091724273L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int which = getArg0AsNode(xctxt);
+
+    if (DTM.NULL != which)
+    {
+      // Note that this is a different value than in previous releases
+      // of Xalan. It's sensitive to the exact encoding of the node
+      // handle anyway, so fighting to maintain backward compatability
+      // really didn't make sense; it may change again as we continue
+      // to experiment with balancing document and node numbers within
+      // that value.
+      return new XString("N" + Integer.toHexString(which).toUpperCase());
+    }
+    else
+      return XString.EMPTYSTRING;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncId.java b/src/main/java/org/apache/xpath/functions/FuncId.java
new file mode 100644
index 0000000..b06d66f
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncId.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncId.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import java.util.StringTokenizer;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.StringVector;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Execute the Id() function.
+ * @xsl.usage advanced
+ */
+public class FuncId extends FunctionOneArg
+{
+    static final long serialVersionUID = 8930573966143567310L;
+
+  /**
+   * Fill in a list with nodes that match a space delimited list if ID 
+   * ID references.
+   *
+   * @param xctxt The runtime XPath context.
+   * @param docContext The document where the nodes are being looked for.
+   * @param refval A space delimited list of ID references.
+   * @param usedrefs List of references for which nodes were found.
+   * @param nodeSet Node set where the nodes will be added to.
+   * @param mayBeMore true if there is another set of nodes to be looked for.
+   *
+   * @return The usedrefs value.
+   */
+  private StringVector getNodesByID(XPathContext xctxt, int docContext,
+                                    String refval, StringVector usedrefs,
+                                    NodeSetDTM nodeSet, boolean mayBeMore)
+  {
+
+    if (null != refval)
+    {
+      String ref = null;
+//      DOMHelper dh = xctxt.getDOMHelper();
+      StringTokenizer tokenizer = new StringTokenizer(refval);
+      boolean hasMore = tokenizer.hasMoreTokens();
+      DTM dtm = xctxt.getDTM(docContext);
+
+      while (hasMore)
+      {
+        ref = tokenizer.nextToken();
+        hasMore = tokenizer.hasMoreTokens();
+
+        if ((null != usedrefs) && usedrefs.contains(ref))
+        {
+          ref = null;
+
+          continue;
+        }
+
+        int node = dtm.getElementById(ref);
+
+        if (DTM.NULL != node)
+          nodeSet.addNodeInDocOrder(node, xctxt);
+
+        if ((null != ref) && (hasMore || mayBeMore))
+        {
+          if (null == usedrefs)
+            usedrefs = new StringVector();
+
+          usedrefs.addElement(ref);
+        }
+      }
+    }
+
+    return usedrefs;
+  }
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+    int docContext = dtm.getDocument();
+
+    if (DTM.NULL == docContext)
+      error(xctxt, XPATHErrorResources.ER_CONTEXT_HAS_NO_OWNERDOC, null);
+
+    XObject arg = m_arg0.execute(xctxt);
+    int argType = arg.getType();
+    XNodeSet nodes = new XNodeSet(xctxt.getDTMManager());
+    NodeSetDTM nodeSet = nodes.mutableNodeset();
+
+    if (XObject.CLASS_NODESET == argType)
+    {
+      DTMIterator ni = arg.iter();
+      StringVector usedrefs = null;
+      int pos = ni.nextNode();
+
+      while (DTM.NULL != pos)
+      {
+        DTM ndtm = ni.getDTM(pos);
+        String refval = ndtm.getStringValue(pos).toString();
+
+        pos = ni.nextNode();
+        usedrefs = getNodesByID(xctxt, docContext, refval, usedrefs, nodeSet,
+                                DTM.NULL != pos);
+      }
+      // ni.detach();
+    }
+    else if (XObject.CLASS_NULL == argType)
+    {
+      return nodes;
+    }
+    else
+    {
+      String refval = arg.str();
+
+      getNodesByID(xctxt, docContext, refval, null, nodeSet, false);
+    }
+
+    return nodes;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncLang.java b/src/main/java/org/apache/xpath/functions/FuncLang.java
new file mode 100644
index 0000000..61b8d25
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncLang.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncLang.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Lang() function.
+ * @xsl.usage advanced
+ */
+public class FuncLang extends FunctionOneArg
+{
+    static final long serialVersionUID = -7868705139354872185L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String lang = m_arg0.execute(xctxt).str();
+    int parent = xctxt.getCurrentNode();
+    boolean isLang = false;
+    DTM dtm = xctxt.getDTM(parent);
+
+    while (DTM.NULL != parent)
+    {
+      if (DTM.ELEMENT_NODE == dtm.getNodeType(parent))
+      {
+        int langAttr = dtm.getAttributeNode(parent, "http://www.w3.org/XML/1998/namespace", "lang");
+
+        if (DTM.NULL != langAttr)
+        {
+          String langVal = dtm.getNodeValue(langAttr);
+          // %OPT%
+          if (langVal.toLowerCase().startsWith(lang.toLowerCase()))
+          {
+            int valLen = lang.length();
+
+            if ((langVal.length() == valLen)
+                    || (langVal.charAt(valLen) == '-'))
+            {
+              isLang = true;
+            }
+          }
+
+          break;
+        }
+      }
+
+      parent = dtm.getParent(parent);
+    }
+
+    return isLang ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncLast.java b/src/main/java/org/apache/xpath/functions/FuncLast.java
new file mode 100644
index 0000000..93f1afd
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncLast.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncLast.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.SubContextList;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+
+/**
+ * Execute the Last() function.
+ * @xsl.usage advanced
+ */
+public class FuncLast extends Function
+{
+    static final long serialVersionUID = 9205812403085432943L;
+  
+  private boolean m_isTopLevel;
+  
+  /**
+   * Figure out if we're executing a toplevel expression.
+   * If so, we can't be inside of a predicate. 
+   */
+  public void postCompileStep(Compiler compiler)
+  {
+    m_isTopLevel = compiler.getLocationPathDepth() == -1;
+  }
+
+  /**
+   * Get the position in the current context node list.
+   *
+   * @param xctxt non-null reference to XPath runtime context.
+   *
+   * @return The number of nodes in the list.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public int getCountOfContextNodeList(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // assert(null != m_contextNodeList, "m_contextNodeList must be non-null");
+    // If we're in a predicate, then this will return non-null.
+    SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
+
+    // System.out.println("iter: "+iter);
+    if (null != iter)
+      return iter.getLastPos(xctxt);
+
+    DTMIterator cnl = xctxt.getContextNodeList();
+    int count;
+    if(null != cnl)
+    {
+      count = cnl.getLength();
+      // System.out.println("count: "+count); 
+    }
+    else
+      count = 0;   
+    return count;
+  }
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    XNumber xnum = new XNumber((double) getCountOfContextNodeList(xctxt));
+    // System.out.println("last: "+xnum.num());
+    return xnum;
+  }
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncLocalPart.java b/src/main/java/org/apache/xpath/functions/FuncLocalPart.java
new file mode 100644
index 0000000..f73a1d8
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncLocalPart.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncLocalPart.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the LocalPart() function.
+ * @xsl.usage advanced
+ */
+public class FuncLocalPart extends FunctionDef1Arg
+{
+    static final long serialVersionUID = 7591798770325814746L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int context = getArg0AsNode(xctxt);
+    if(DTM.NULL == context)
+      return XString.EMPTYSTRING;
+    DTM dtm = xctxt.getDTM(context);
+    String s = (context != DTM.NULL) ? dtm.getLocalName(context) : "";
+    if(s.startsWith("#") || s.equals("xmlns"))
+      return XString.EMPTYSTRING;
+
+    return new XString(s);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncNamespace.java b/src/main/java/org/apache/xpath/functions/FuncNamespace.java
new file mode 100644
index 0000000..6c040e6
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncNamespace.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncNamespace.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the Namespace() function.
+ * @xsl.usage advanced
+ */
+public class FuncNamespace extends FunctionDef1Arg
+{
+    static final long serialVersionUID = -4695674566722321237L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int context = getArg0AsNode(xctxt);
+    
+    String s;
+    if(context != DTM.NULL)
+    {
+      DTM dtm = xctxt.getDTM(context);
+      int t = dtm.getNodeType(context);
+      if(t == DTM.ELEMENT_NODE)
+      {
+        s = dtm.getNamespaceURI(context);
+      }
+      else if(t == DTM.ATTRIBUTE_NODE)
+      {
+
+        // This function always returns an empty string for namespace nodes.
+        // We check for those here.  Fix inspired by Davanum Srinivas.
+
+        s = dtm.getNodeName(context);
+        if(s.startsWith("xmlns:") || s.equals("xmlns"))
+          return XString.EMPTYSTRING;
+
+        s = dtm.getNamespaceURI(context);
+      }
+      else
+        return XString.EMPTYSTRING;
+    }
+    else 
+      return XString.EMPTYSTRING;
+    
+    return ((null == s) ? XString.EMPTYSTRING : new XString(s));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncNormalizeSpace.java b/src/main/java/org/apache/xpath/functions/FuncNormalizeSpace.java
new file mode 100644
index 0000000..5c00d20
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncNormalizeSpace.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncNormalizeSpace.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.xml.sax.ContentHandler;
+
+/**
+ * Execute the normalize-space() function.
+ * @xsl.usage advanced
+ */
+public class FuncNormalizeSpace extends FunctionDef1Arg
+{
+    static final long serialVersionUID = -3377956872032190880L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    XMLString s1 = getArg0AsString(xctxt);
+
+    return (XString)s1.fixWhiteSpace(true, true, false);
+  }
+  
+  /**
+   * Execute an expression in the XPath runtime context, and return the 
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception 
+   *         occurs.
+   */
+  public void executeCharsToContentHandler(XPathContext xctxt, 
+                                              ContentHandler handler)
+    throws javax.xml.transform.TransformerException,
+           org.xml.sax.SAXException
+  {
+    if(Arg0IsNodesetExpr())
+    {
+      int node = getArg0AsNode(xctxt);
+      if(DTM.NULL != node)
+      {
+        DTM dtm = xctxt.getDTM(node);
+        dtm.dispatchCharactersEvents(node, handler, true);
+      }
+    }
+    else
+    {
+      XObject obj = execute(xctxt);
+      obj.dispatchCharactersEvents(handler);
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncNot.java b/src/main/java/org/apache/xpath/functions/FuncNot.java
new file mode 100644
index 0000000..b69a450
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncNot.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncNot.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Not() function.
+ * @xsl.usage advanced
+ */
+public class FuncNot extends FunctionOneArg
+{
+    static final long serialVersionUID = 7299699961076329790L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return m_arg0.execute(xctxt).bool() ? XBoolean.S_FALSE : XBoolean.S_TRUE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncNumber.java b/src/main/java/org/apache/xpath/functions/FuncNumber.java
new file mode 100644
index 0000000..401447c
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncNumber.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncNumber.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Number() function.
+ * @xsl.usage advanced
+ */
+public class FuncNumber extends FunctionDef1Arg
+{
+    static final long serialVersionUID = 7266745342264153076L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(getArg0AsNumber(xctxt));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncPosition.java b/src/main/java/org/apache/xpath/functions/FuncPosition.java
new file mode 100644
index 0000000..c6b9a05
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncPosition.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncPosition.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.SubContextList;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Position() function.
+ * @xsl.usage advanced
+ */
+public class FuncPosition extends Function
+{
+    static final long serialVersionUID = -9092846348197271582L;
+  private boolean m_isTopLevel;
+  
+  /**
+   * Figure out if we're executing a toplevel expression.
+   * If so, we can't be inside of a predicate. 
+   */
+  public void postCompileStep(Compiler compiler)
+  {
+    m_isTopLevel = compiler.getLocationPathDepth() == -1;
+  }
+
+  /**
+   * Get the position in the current context node list.
+   *
+   * @param xctxt Runtime XPath context.
+   *
+   * @return The current position of the itteration in the context node list, 
+   *         or -1 if there is no active context node list.
+   */
+  public int getPositionInContextNodeList(XPathContext xctxt)
+  {
+
+    // System.out.println("FuncPosition- entry");
+    // If we're in a predicate, then this will return non-null.
+    SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
+
+    if (null != iter)
+    {
+      int prox = iter.getProximityPosition(xctxt);
+ 
+      // System.out.println("FuncPosition- prox: "+prox);
+      return prox;
+    }
+
+    DTMIterator cnl = xctxt.getContextNodeList();
+
+    if (null != cnl)
+    {
+      int n = cnl.getCurrentNode();
+      if(n == DTM.NULL)
+      {
+        if(cnl.getCurrentPos() == 0)
+          return 0;
+          
+        // Then I think we're in a sort.  See sort21.xsl. So the iterator has 
+        // already been spent, and is not on the node we're processing. 
+        // It's highly possible that this is an issue for other context-list 
+        // functions.  Shouldn't be a problem for last(), and it shouldn't be 
+        // a problem for current().
+        try 
+        { 
+          cnl = cnl.cloneWithReset(); 
+        }
+        catch(CloneNotSupportedException cnse)
+        {
+          throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
+        }
+        int currentNode = xctxt.getContextNode();
+        // System.out.println("currentNode: "+currentNode);
+        while(DTM.NULL != (n = cnl.nextNode()))
+        {
+          if(n == currentNode)
+            break;
+        }
+      }
+      // System.out.println("n: "+n);
+      // System.out.println("FuncPosition- cnl.getCurrentPos(): "+cnl.getCurrentPos());
+      return cnl.getCurrentPos();
+    }
+
+    // System.out.println("FuncPosition - out of guesses: -1");
+    return -1;
+  }
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    double pos = (double) getPositionInContextNodeList(xctxt);
+    
+    return new XNumber(pos);
+  }
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncQname.java b/src/main/java/org/apache/xpath/functions/FuncQname.java
new file mode 100644
index 0000000..db51cab
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncQname.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncQname.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the Qname() function.
+ * @xsl.usage advanced
+ */
+public class FuncQname extends FunctionDef1Arg
+{
+    static final long serialVersionUID = -1532307875532617380L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    int context = getArg0AsNode(xctxt);
+    XObject val;
+
+    if (DTM.NULL != context)
+    {
+      DTM dtm = xctxt.getDTM(context);
+      String qname = dtm.getNodeNameX(context);
+      val = (null == qname) ? XString.EMPTYSTRING : new XString(qname);
+    }
+    else
+    {
+      val = XString.EMPTYSTRING;
+    }
+
+    return val;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncRound.java b/src/main/java/org/apache/xpath/functions/FuncRound.java
new file mode 100644
index 0000000..78943c5
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncRound.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncRound.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the round() function.
+ * @xsl.usage advanced
+ */
+public class FuncRound extends FunctionOneArg
+{
+    static final long serialVersionUID = -7970583902573826611L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+          final XObject obj = m_arg0.execute(xctxt);
+          final double val= obj.num();
+          if (val >= -0.5 && val < 0) return new XNumber(-0.0);
+          if (val == 0.0) return new XNumber(val);
+          return new XNumber(java.lang.Math.floor(val
+                                            + 0.5));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncStartsWith.java b/src/main/java/org/apache/xpath/functions/FuncStartsWith.java
new file mode 100644
index 0000000..5a090a2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncStartsWith.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncStartsWith.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the StartsWith() function.
+ * @xsl.usage advanced
+ */
+public class FuncStartsWith extends Function2Args
+{
+    static final long serialVersionUID = 2194585774699567928L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return m_arg0.execute(xctxt).xstr().startsWith(m_arg1.execute(xctxt).xstr())
+           ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncString.java b/src/main/java/org/apache/xpath/functions/FuncString.java
new file mode 100644
index 0000000..4107b22
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncString.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncString.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the String() function.
+ * @xsl.usage advanced
+ */
+public class FuncString extends FunctionDef1Arg
+{
+    static final long serialVersionUID = -2206677149497712883L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return (XString)getArg0AsString(xctxt);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncStringLength.java b/src/main/java/org/apache/xpath/functions/FuncStringLength.java
new file mode 100644
index 0000000..bc8bce6
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncStringLength.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncStringLength.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the StringLength() function.
+ * @xsl.usage advanced
+ */
+public class FuncStringLength extends FunctionDef1Arg
+{
+    static final long serialVersionUID = -159616417996519839L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(getArg0AsString(xctxt).length());
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncSubstring.java b/src/main/java/org/apache/xpath/functions/FuncSubstring.java
new file mode 100644
index 0000000..b2254e2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncSubstring.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncSubstring.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Execute the Substring() function.
+ * @xsl.usage advanced
+ */
+public class FuncSubstring extends Function3Args
+{
+    static final long serialVersionUID = -5996676095024715502L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    XMLString s1 = m_arg0.execute(xctxt).xstr();
+    double start = m_arg1.execute(xctxt).num();
+    int lenOfS1 = s1.length();
+    XMLString substr;
+
+    if (lenOfS1 <= 0)
+      return XString.EMPTYSTRING;
+    else
+    {
+      int startIndex;
+
+      if (Double.isNaN(start))
+      {
+
+        // Double.MIN_VALUE doesn't work with math below 
+        // so just use a big number and hope I never get caught.
+        start = -1000000;
+        startIndex = 0;
+      }
+      else
+      {
+        start = Math.round(start);
+        startIndex = (start > 0) ? (int) start - 1 : 0;
+      }
+
+      if (null != m_arg2)
+      {
+        double len = m_arg2.num(xctxt);
+        int end = (int) (Math.round(len) + start) - 1;
+
+        // Normalize end index.
+        if (end < 0)
+          end = 0;
+        else if (end > lenOfS1)
+          end = lenOfS1;
+
+        if (startIndex > lenOfS1)
+          startIndex = lenOfS1;
+
+        substr = s1.substring(startIndex, end);
+      }
+      else
+      {
+        if (startIndex > lenOfS1)
+          startIndex = lenOfS1;
+        substr = s1.substring(startIndex);
+      }
+    }
+
+    return (XString)substr; // cast semi-safe
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct. 
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum < 2)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3");
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncSubstringAfter.java b/src/main/java/org/apache/xpath/functions/FuncSubstringAfter.java
new file mode 100644
index 0000000..9685977
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncSubstringAfter.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncSubstringAfter.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the SubstringAfter() function.
+ * @xsl.usage advanced
+ */
+public class FuncSubstringAfter extends Function2Args
+{
+    static final long serialVersionUID = -8119731889862512194L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    XMLString s1 = m_arg0.execute(xctxt).xstr();
+    XMLString s2 = m_arg1.execute(xctxt).xstr();
+    int index = s1.indexOf(s2);
+
+    return (-1 == index)
+           ? XString.EMPTYSTRING
+           : (XString)s1.substring(index + s2.length());
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncSubstringBefore.java b/src/main/java/org/apache/xpath/functions/FuncSubstringBefore.java
new file mode 100644
index 0000000..4dcd2f1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncSubstringBefore.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncSubstringBefore.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the SubstringBefore() function.
+ * @xsl.usage advanced
+ */
+public class FuncSubstringBefore extends Function2Args
+{
+    static final long serialVersionUID = 4110547161672431775L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String s1 = m_arg0.execute(xctxt).str();
+    String s2 = m_arg1.execute(xctxt).str();
+    int index = s1.indexOf(s2);
+
+    return (-1 == index)
+           ? XString.EMPTYSTRING : new XString(s1.substring(0, index));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncSum.java b/src/main/java/org/apache/xpath/functions/FuncSum.java
new file mode 100644
index 0000000..1abbe65
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncSum.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncSum.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the Sum() function.
+ * @xsl.usage advanced
+ */
+public class FuncSum extends FunctionOneArg
+{
+    static final long serialVersionUID = -2719049259574677519L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    DTMIterator nodes = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
+    double sum = 0.0;
+    int pos;
+
+    while (DTM.NULL != (pos = nodes.nextNode()))
+    {
+      DTM dtm = nodes.getDTM(pos);
+      XMLString s = dtm.getStringValue(pos);
+
+      if (null != s)
+        sum += s.toDouble();
+    }
+    nodes.detach();
+
+    return new XNumber(sum);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncSystemProperty.java b/src/main/java/org/apache/xpath/functions/FuncSystemProperty.java
new file mode 100644
index 0000000..154e686
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncSystemProperty.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncSystemProperty.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Execute the SystemProperty() function.
+ * @xsl.usage advanced
+ */
+public class FuncSystemProperty extends FunctionOneArg
+{
+    static final long serialVersionUID = 3694874980992204867L;
+  /**
+   * The path/filename of the property file: XSLTInfo.properties
+   * Maintenance note: see also
+   * org.apache.xalan.processor.TransformerFactoryImpl.XSLT_PROPERTIES
+   */
+  static final String XSLT_PROPERTIES = 
+            "org/apache/xalan/res/XSLTInfo.properties";
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String fullName = m_arg0.execute(xctxt).str();
+    int indexOfNSSep = fullName.indexOf(':');
+    String result;
+    String propName = "";
+
+    // List of properties where the name of the
+    // property argument is to be looked for.
+    Properties xsltInfo = new Properties();
+
+    loadPropertyFile(XSLT_PROPERTIES, xsltInfo);
+
+    if (indexOfNSSep > 0)
+    {
+      String prefix = (indexOfNSSep >= 0)
+                      ? fullName.substring(0, indexOfNSSep) : "";
+      String namespace;
+
+      namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
+      propName = (indexOfNSSep < 0)
+                 ? fullName : fullName.substring(indexOfNSSep + 1);
+
+      if (namespace.startsWith("http://www.w3.org/XSL/Transform")
+              || namespace.equals("http://www.w3.org/1999/XSL/Transform"))
+      {
+        result = xsltInfo.getProperty(propName);
+
+        if (null == result)
+        {
+          warn(xctxt, XPATHErrorResources.WG_PROPERTY_NOT_SUPPORTED,
+               new Object[]{ fullName });  //"XSL Property not supported: "+fullName);
+
+          return XString.EMPTYSTRING;
+        }
+      }
+      else
+      {
+        warn(xctxt, XPATHErrorResources.WG_DONT_DO_ANYTHING_WITH_NS,
+             new Object[]{ namespace,
+                           fullName });  //"Don't currently do anything with namespace "+namespace+" in property: "+fullName);
+
+        try
+        {
+          result = System.getProperty(propName);
+
+          if (null == result)
+          {
+
+            // result = System.getenv(propName);
+            return XString.EMPTYSTRING;
+          }
+        }
+        catch (SecurityException se)
+        {
+          warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
+               new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
+
+          return XString.EMPTYSTRING;
+        }
+      }
+    }
+    else
+    {
+      try
+      {
+        result = System.getProperty(fullName);
+
+        if (null == result)
+        {
+
+          // result = System.getenv(fullName);
+          return XString.EMPTYSTRING;
+        }
+      }
+      catch (SecurityException se)
+      {
+        warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
+             new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
+
+        return XString.EMPTYSTRING;
+      }
+    }
+
+    if (propName.equals("version") && result.length() > 0)
+    {
+      try
+      {
+        // Needs to return the version number of the spec we conform to.
+        return new XString("1.0");
+      }
+      catch (Exception ex)
+      {
+        return new XString(result);
+      }
+    }
+    else
+      return new XString(result);
+  }
+
+  /**
+   * Retrieve a propery bundle from a specified file
+   * 
+   * @param file The string name of the property file.  The name 
+   * should already be fully qualified as path/filename
+   * @param target The target property bag the file will be placed into.
+   */
+  public void loadPropertyFile(String file, Properties target)
+  {
+    try
+    {
+      // Use SecuritySupport class to provide priveleged access to property file
+      SecuritySupport ss = SecuritySupport.getInstance();
+
+      InputStream is = ss.getResourceAsStream(ObjectFactory.findClassLoader(),
+                                              file);
+
+      // get a buffered version
+      BufferedInputStream bis = new BufferedInputStream(is);
+
+      target.load(bis);  // and load up the property bag from this
+      bis.close();  // close out after reading
+    }
+    catch (Exception ex)
+    {
+      // ex.printStackTrace();
+      throw new org.apache.xml.utils.WrappedRuntimeException(ex);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncTranslate.java b/src/main/java/org/apache/xpath/functions/FuncTranslate.java
new file mode 100644
index 0000000..4eb1fc8
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncTranslate.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncTranslate.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * Execute the Translate() function.
+ * @xsl.usage advanced
+ */
+public class FuncTranslate extends Function3Args
+{
+    static final long serialVersionUID = -1672834340026116482L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String theFirstString = m_arg0.execute(xctxt).str();
+    String theSecondString = m_arg1.execute(xctxt).str();
+    String theThirdString = m_arg2.execute(xctxt).str();
+    int theFirstStringLength = theFirstString.length();
+    int theThirdStringLength = theThirdString.length();
+
+    // A vector to contain the new characters.  We'll use it to construct
+    // the result string.
+    StringBuffer sbuffer = new StringBuffer();
+
+    for (int i = 0; i < theFirstStringLength; i++)
+    {
+      char theCurrentChar = theFirstString.charAt(i);
+      int theIndex = theSecondString.indexOf(theCurrentChar);
+
+      if (theIndex < 0)
+      {
+
+        // Didn't find the character in the second string, so it
+        // is not translated.
+        sbuffer.append(theCurrentChar);
+      }
+      else if (theIndex < theThirdStringLength)
+      {
+
+        // OK, there's a corresponding character in the
+        // third string, so do the translation...
+        sbuffer.append(theThirdString.charAt(theIndex));
+      }
+      else
+      {
+
+        // There's no corresponding character in the
+        // third string, since it's shorter than the
+        // second string.  In this case, the character
+        // is removed from the output string, so don't
+        // do anything.
+      }
+    }
+
+    return new XString(sbuffer.toString());
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncTrue.java b/src/main/java/org/apache/xpath/functions/FuncTrue.java
new file mode 100644
index 0000000..b8c7479
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncTrue.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncTrue.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Execute the True() function.
+ * @xsl.usage advanced
+ */
+public class FuncTrue extends Function
+{
+    static final long serialVersionUID = 5663314547346339447L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+    return XBoolean.S_TRUE;
+  }
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FuncUnparsedEntityURI.java b/src/main/java/org/apache/xpath/functions/FuncUnparsedEntityURI.java
new file mode 100644
index 0000000..4517e0d
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FuncUnparsedEntityURI.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FuncUnparsedEntityURI.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * @xsl.usage advanced
+ */
+public class FuncUnparsedEntityURI extends FunctionOneArg
+{
+    static final long serialVersionUID = 845309759097448178L;
+
+  /**
+   * Execute the function.  The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    String name = m_arg0.execute(xctxt).str();
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+    int doc = dtm.getDocument();
+    
+    String uri = dtm.getUnparsedEntityURI(name);
+
+    return new XString(uri);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/Function.java b/src/main/java/org/apache/xpath/functions/Function.java
new file mode 100644
index 0000000..6e923a4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/Function.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Function.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This is a superclass of all XPath functions.  This allows two
+ * ways for the class to be called. One method is that the
+ * super class processes the arguments and hands the results to
+ * the derived class, the other method is that the derived
+ * class may process it's own arguments, which is faster since
+ * the arguments don't have to be added to an array, but causes
+ * a larger code footprint.
+ * @xsl.usage advanced
+ */
+public abstract class Function extends Expression
+{
+    static final long serialVersionUID = 6927661240854599768L;
+
+  /**
+   * Set an argument expression for a function.  This method is called by the 
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If the argNum parameter is beyond what 
+   * is specified for this function.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+			// throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("zero", null));
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   * This method is meant to be overloaded by derived classes, to check for 
+   * the number of arguments for a specific function type.  This method is 
+   * called by the compiler for static number of arguments checking.
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum != 0)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.  This method is meant to be overloaded
+   * by derived classes so that the message will be as specific as possible.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("zero", null));
+  }
+
+  /**
+   * Execute an XPath function object.  The function must return
+   * a valid object.
+   * @param xctxt The execution current context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    // Programmer's assert.  (And, no, I don't want the method to be abstract).
+    System.out.println("Error! Function.execute should not be called!");
+
+    return null;
+  }
+  
+  /**
+   * Call the visitors for the function arguments.
+   */
+  public void callArgVisitors(XPathVisitor visitor)
+  {
+  }
+
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	if(visitor.visitFunction(owner, this))
+  	{
+  		callArgVisitors(visitor);
+  	}
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	return true;
+  }
+
+  /**
+   * This function is currently only being used by Position()
+   * and Last(). See respective functions for more detail.
+   */
+  public void postCompileStep(Compiler compiler)
+  {
+    // no default action
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/Function2Args.java b/src/main/java/org/apache/xpath/functions/Function2Args.java
new file mode 100644
index 0000000..7c36c4a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/Function2Args.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Function2Args.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * Base class for functions that accept two arguments.
+ * @xsl.usage advanced
+ */
+public class Function2Args extends FunctionOneArg
+{
+    static final long serialVersionUID = 5574294996842710641L;
+
+  /** The second argument passed to the function (at index 1).
+   *  @serial  */
+  Expression m_arg1;
+
+  /**
+   * Return the second argument passed to the function (at index 1).
+   *
+   * @return An expression that represents the second argument passed to the 
+   *         function.
+   */
+  public Expression getArg1()
+  {
+    return m_arg1;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    if(null != m_arg1)
+      m_arg1.fixupVariables(vars, globalsSize);
+  }
+
+
+  /**
+   * Set an argument expression for a function.  This method is called by the 
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If the argNum parameter is greater than 1.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+
+    // System.out.println("argNum: "+argNum);
+    if (argNum == 0)
+      super.setArg(arg, argNum);
+    else if (1 == argNum)
+    {
+      m_arg1 = arg;
+      arg.exprSetParent(this);
+    }
+    else
+		  reportWrongNumberArgs();
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct. 
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum != 2)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("two", null));
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    return super.canTraverseOutsideSubtree() 
+    ? true : m_arg1.canTraverseOutsideSubtree();
+   }
+   
+  class Arg1Owner implements ExpressionOwner
+  {
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_arg1;
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(Function2Args.this);
+    	m_arg1 = exp;
+    }
+  }
+
+   
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callArgVisitors(XPathVisitor visitor)
+  {
+  	super.callArgVisitors(visitor);
+  	if(null != m_arg1)
+  		m_arg1.callVisitors(new Arg1Owner(), visitor);
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(null != m_arg1)
+  	{
+  		if(null == ((Function2Args)expr).m_arg1)
+  			return false;
+  			
+  		if(!m_arg1.deepEquals(((Function2Args)expr).m_arg1))
+  			return false;
+  	}
+  	else if(null != ((Function2Args)expr).m_arg1)
+  		return false;
+  		
+  	return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/Function3Args.java b/src/main/java/org/apache/xpath/functions/Function3Args.java
new file mode 100644
index 0000000..bb49216
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/Function3Args.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Function3Args.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * Base class for functions that accept three arguments.
+ * @xsl.usage advanced
+ */
+public class Function3Args extends Function2Args
+{
+    static final long serialVersionUID = 7915240747161506646L;
+
+  /** The third argument passed to the function (at index 2).
+   *  @serial  */
+  Expression m_arg2;
+
+  /**
+   * Return the third argument passed to the function (at index 2).
+   *
+   * @return An expression that represents the third argument passed to the 
+   *         function.
+   */
+  public Expression getArg2()
+  {
+    return m_arg2;
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    if(null != m_arg2)
+      m_arg2.fixupVariables(vars, globalsSize);
+  }
+
+  /**
+   * Set an argument expression for a function.  This method is called by the 
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If the argNum parameter is greater than 2.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+
+    if (argNum < 2)
+      super.setArg(arg, argNum);
+    else if (2 == argNum)
+    {
+      m_arg2 = arg;
+      arg.exprSetParent(this);
+    }
+    else
+		  reportWrongNumberArgs();
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct. 
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum != 3)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("three", null));
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    return super.canTraverseOutsideSubtree() 
+    ? true : m_arg2.canTraverseOutsideSubtree();
+   }
+   
+  class Arg2Owner implements ExpressionOwner
+  {
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_arg2;
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(Function3Args.this);
+    	m_arg2 = exp;
+    }
+  }
+
+   
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callArgVisitors(XPathVisitor visitor)
+  {
+  	super.callArgVisitors(visitor);
+  	if(null != m_arg2)
+  		m_arg2.callVisitors(new Arg2Owner(), visitor);
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(null != m_arg2)
+  	{
+  		if(null == ((Function3Args)expr).m_arg2)
+  			return false;
+
+  		if(!m_arg2.deepEquals(((Function3Args)expr).m_arg2))
+  			return false;
+  	}
+  	else if (null != ((Function3Args)expr).m_arg2)
+  		return false;
+  		
+  	return true;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/FunctionDef1Arg.java b/src/main/java/org/apache/xpath/functions/FunctionDef1Arg.java
new file mode 100644
index 0000000..40e36cf
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FunctionDef1Arg.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FunctionDef1Arg.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Base class for functions that accept one argument that can be defaulted if
+ * not specified.
+ * @xsl.usage advanced
+ */
+public class FunctionDef1Arg extends FunctionOneArg
+{
+    static final long serialVersionUID = 2325189412814149264L;
+
+  /**
+   * Execute the first argument expression that is expected to return a
+   * nodeset.  If the argument is null, then return the current context node.
+   *
+   * @param xctxt Runtime XPath context.
+   *
+   * @return The first node of the executed nodeset, or the current context
+   *         node if the first argument is null.
+   *
+   * @throws javax.xml.transform.TransformerException if an error occurs while
+   *                                   executing the argument expression.
+   */
+  protected int getArg0AsNode(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return (null == m_arg0)
+           ? xctxt.getCurrentNode() : m_arg0.asNode(xctxt);
+  }
+  
+  /**
+   * Tell if the expression is a nodeset expression.
+   * @return true if the expression can be represented as a nodeset.
+   */
+  public boolean Arg0IsNodesetExpr()
+  {
+    return (null == m_arg0) ? true : m_arg0.isNodesetExpr();
+  }
+
+  /**
+   * Execute the first argument expression that is expected to return a
+   * string.  If the argument is null, then get the string value from the
+   * current context node.
+   *
+   * @param xctxt Runtime XPath context.
+   *
+   * @return The string value of the first argument, or the string value of the
+   *         current context node if the first argument is null.
+   *
+   * @throws javax.xml.transform.TransformerException if an error occurs while
+   *                                   executing the argument expression.
+   */
+  protected XMLString getArg0AsString(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    if(null == m_arg0)
+    {
+      int currentNode = xctxt.getCurrentNode();
+      if(DTM.NULL == currentNode)
+        return XString.EMPTYSTRING;
+      else
+      {
+        DTM dtm = xctxt.getDTM(currentNode);
+        return dtm.getStringValue(currentNode);
+      }
+      
+    }
+    else
+      return m_arg0.execute(xctxt).xstr();   
+  }
+
+  /**
+   * Execute the first argument expression that is expected to return a
+   * number.  If the argument is null, then get the number value from the
+   * current context node.
+   *
+   * @param xctxt Runtime XPath context.
+   *
+   * @return The number value of the first argument, or the number value of the
+   *         current context node if the first argument is null.
+   *
+   * @throws javax.xml.transform.TransformerException if an error occurs while
+   *                                   executing the argument expression.
+   */
+  protected double getArg0AsNumber(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    if(null == m_arg0)
+    {
+      int currentNode = xctxt.getCurrentNode();
+      if(DTM.NULL == currentNode)
+        return 0;
+      else
+      {
+        DTM dtm = xctxt.getDTM(currentNode);
+        XMLString str = dtm.getStringValue(currentNode);
+        return str.toDouble();
+      }
+      
+    }
+    else
+      return m_arg0.execute(xctxt).num();
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException if the number of arguments is not 0 or 1.
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum > 1)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ZERO_OR_ONE, null)); //"0 or 1");
+  }
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+    return (null == m_arg0) ? false : super.canTraverseOutsideSubtree();
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FunctionMultiArgs.java b/src/main/java/org/apache/xpath/functions/FunctionMultiArgs.java
new file mode 100644
index 0000000..559e66f
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FunctionMultiArgs.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FunctionMultiArgs.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Base class for functions that accept an undetermined number of multiple
+ * arguments.
+ * @xsl.usage advanced
+ */
+public class FunctionMultiArgs extends Function3Args
+{
+    static final long serialVersionUID = 7117257746138417181L;
+
+  /** Argument expressions that are at index 3 or greater.
+   *  @serial */
+  Expression[] m_args;
+  
+  /**
+   * Return an expression array containing arguments at index 3 or greater.
+   *
+   * @return An array that contains the arguments at index 3 or greater.
+   */
+  public Expression[] getArgs()
+  {
+    return m_args;
+  }
+
+  /**
+   * Set an argument expression for a function.  This method is called by the
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If a derived class determines that the
+   * number of arguments is incorrect.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+
+    if (argNum < 3)
+      super.setArg(arg, argNum);
+    else
+    {
+      if (null == m_args)
+      {
+        m_args = new Expression[1];
+        m_args[0] = arg;
+      }
+      else
+      {
+
+        // Slow but space conservative.
+        Expression[] args = new Expression[m_args.length + 1];
+
+        System.arraycopy(m_args, 0, args, 0, m_args.length);
+
+        args[m_args.length] = arg;
+        m_args = args;
+      }
+      arg.exprSetParent(this);
+    }
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    if(null != m_args)
+    {
+      for (int i = 0; i < m_args.length; i++) 
+      {
+        m_args[i].fixupVariables(vars, globalsSize);
+      }
+    }
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException{}
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.  This class supports an arbitrary
+   * number of arguments, so this method must never be called.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+    String fMsg = XSLMessages.createXPATHMessage(
+        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
+        new Object[]{ "Programmer's assertion:  the method FunctionMultiArgs.reportWrongNumberArgs() should never be called." });
+
+    throw new RuntimeException(fMsg);
+  }
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+
+    if (super.canTraverseOutsideSubtree())
+      return true;
+    else
+    {
+      int n = m_args.length;
+
+      for (int i = 0; i < n; i++)
+      {
+        if (m_args[i].canTraverseOutsideSubtree())
+          return true;
+      }
+
+      return false;
+    }
+  }
+  
+  class ArgMultiOwner implements ExpressionOwner
+  {
+  	int m_argIndex;
+  	
+  	ArgMultiOwner(int index)
+  	{
+  		m_argIndex = index;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_args[m_argIndex];
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(FunctionMultiArgs.this);
+    	m_args[m_argIndex] = exp;
+    }
+  }
+
+   
+    /**
+     * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+     */
+    public void callArgVisitors(XPathVisitor visitor)
+    {
+      super.callArgVisitors(visitor);
+      if (null != m_args)
+      {
+        int n = m_args.length;
+        for (int i = 0; i < n; i++)
+        {
+          m_args[i].callVisitors(new ArgMultiOwner(i), visitor);
+        }
+      }
+    }
+    
+    /**
+     * @see Expression#deepEquals(Expression)
+     */
+    public boolean deepEquals(Expression expr)
+    {
+      if (!super.deepEquals(expr))
+            return false;
+
+      FunctionMultiArgs fma = (FunctionMultiArgs) expr;
+      if (null != m_args)
+      {
+        int n = m_args.length;
+        if ((null == fma) || (fma.m_args.length != n))
+              return false;
+
+        for (int i = 0; i < n; i++)
+        {
+          if (!m_args[i].deepEquals(fma.m_args[i]))
+                return false;
+        }
+
+      }
+      else if (null != fma.m_args)
+      {
+          return false;
+      }
+
+      return true;
+    }
+}
diff --git a/src/main/java/org/apache/xpath/functions/FunctionOneArg.java b/src/main/java/org/apache/xpath/functions/FunctionOneArg.java
new file mode 100644
index 0000000..40ea4ff
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/FunctionOneArg.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FunctionOneArg.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * Base class for functions that accept one argument.
+ * @xsl.usage advanced
+ */
+public class FunctionOneArg extends Function implements ExpressionOwner
+{
+    static final long serialVersionUID = -5180174180765609758L;
+
+  /** The first argument passed to the function (at index 0).
+   *  @serial  */
+  Expression m_arg0;
+
+  /**
+   * Return the first argument passed to the function (at index 0).
+   *
+   * @return An expression that represents the first argument passed to the 
+   *         function.
+   */
+  public Expression getArg0()
+  {
+    return m_arg0;
+  }
+  
+  /**
+   * Set an argument expression for a function.  This method is called by the 
+   * XPath compiler.
+   *
+   * @param arg non-null expression that represents the argument.
+   * @param argNum The argument number index.
+   *
+   * @throws WrongNumberArgsException If the argNum parameter is greater than 0.
+   */
+  public void setArg(Expression arg, int argNum)
+          throws WrongNumberArgsException
+  {
+
+    if (0 == argNum)
+    {
+      m_arg0 = arg;
+      arg.exprSetParent(this);
+    }
+    else
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct. 
+   *
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+    if (argNum != 1)
+      reportWrongNumberArgs();
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("one", null));
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+    return m_arg0.canTraverseOutsideSubtree();
+   }
+   
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    if(null != m_arg0)
+      m_arg0.fixupVariables(vars, globalsSize);
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callArgVisitors(XPathVisitor visitor)
+  {
+  	if(null != m_arg0)
+  		m_arg0.callVisitors(this, visitor);
+  }
+
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_arg0;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_arg0 = exp;
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	if(null != m_arg0)
+  	{
+  		if(null == ((FunctionOneArg)expr).m_arg0)
+  			return false;
+  			
+  		if(!m_arg0.deepEquals(((FunctionOneArg)expr).m_arg0))
+  			return false;
+  	}
+  	else if(null != ((FunctionOneArg)expr).m_arg0)
+  		return false;
+
+  	return true;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/functions/ObjectFactory.java b/src/main/java/org/apache/xpath/functions/ObjectFactory.java
new file mode 100755
index 0000000..96ac601
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/ObjectFactory.java
@@ -0,0 +1,661 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ObjectFactory.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+
+package org.apache.xpath.functions;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id: ObjectFactory.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services/";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                FileInputStream fis = null;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        fis = ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                    }
+	        } catch (Exception x) {
+	            fXalanProperties = null;
+	            fLastModified = -1;
+                    // assert(x instanceof FileNotFoundException
+	            //        || x instanceof SecurityException)
+	            // In both cases, ignore and continue w/ next location
+	        }
+                finally {
+                    // try to close the input stream if one was opened.
+                    if (fis != null) {
+                        try {
+                            fis.close();
+                        }
+                        // Ignore the exception.
+                        catch (IOException exc) {}
+                    }
+                }	            
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            FileInputStream fis = null;
+            try {
+                fis = ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+            finally {
+                // try to close the input stream if one was opened.
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    }
+                    // Ignore the exception.
+                    catch (IOException exc) {}
+                }
+            }               
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {   
+        //throw security exception if the calling thread is not allowed to access the
+        //class. Restrict the access to the package classes as specified in java.security policy.
+        SecurityManager security = System.getSecurityManager();
+        try{
+                if (security != null){
+                    final int lastDot = className.lastIndexOf(".");
+                    String packageName = className;
+                    if (lastDot != -1) packageName = className.substring(0, lastDot);
+                    security.checkPackageAccess(packageName);
+                 }   
+        }catch(SecurityException e){
+            throw e;
+        }
+        
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+        finally {
+            try {
+                // try to close the reader.
+                rd.close();
+            }
+            // Ignore the exception.
+            catch (IOException exc) {}
+        }          
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+                static final long serialVersionUID = -5782303800588797207L;
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/main/java/org/apache/xpath/functions/SecuritySupport.java b/src/main/java/org/apache/xpath/functions/SecuritySupport.java
new file mode 100644
index 0000000..556a159
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/SecuritySupport.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+
+package org.apache.xpath.functions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/main/java/org/apache/xpath/functions/SecuritySupport12.java b/src/main/java/org/apache/xpath/functions/SecuritySupport12.java
new file mode 100644
index 0000000..e7edf5a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/SecuritySupport12.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: SecuritySupport12.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+
+package org.apache.xpath.functions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/main/java/org/apache/xpath/functions/WrongNumberArgsException.java b/src/main/java/org/apache/xpath/functions/WrongNumberArgsException.java
new file mode 100644
index 0000000..6f11938
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/WrongNumberArgsException.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: WrongNumberArgsException.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.functions;
+
+/**
+ * An exception that is thrown if the wrong number of arguments to an exception 
+ * are specified by the stylesheet.
+ * @xsl.usage advanced
+ */
+public class WrongNumberArgsException extends Exception
+{
+    static final long serialVersionUID = -4551577097576242432L;
+
+  /**
+   * Constructor WrongNumberArgsException
+   *
+   * @param argsExpected Error message that tells the number of arguments that 
+   * were expected.
+   */
+  public WrongNumberArgsException(String argsExpected)
+  {
+
+    super(argsExpected);
+  }
+}
diff --git a/src/main/java/org/apache/xpath/functions/package.html b/src/main/java/org/apache/xpath/functions/package.html
new file mode 100644
index 0000000..362770a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/functions/package.html
@@ -0,0 +1,29 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath functions Package.</title>
+  <body>
+    <p>Implements XPath functions -- each function is derived from Function, 
+    FunctionOneArg, Function2Args, etc, with number-of-arguments checking being 
+    applied mainly at compile time -- this package only implements XPath functions, 
+    XSLT functions are found in the "templates" package.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/jaxp/JAXPExtensionsProvider.java b/src/main/java/org/apache/xpath/jaxp/JAXPExtensionsProvider.java
new file mode 100644
index 0000000..fced9c7
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/JAXPExtensionsProvider.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// $Id: JAXPExtensionsProvider.java 468655 2006-10-28 07:12:06Z minchau $
+
+package org.apache.xpath.jaxp;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+
+import org.apache.xpath.ExtensionsProvider;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xalan.res.XSLMessages;
+
+import org.apache.xpath.functions.FuncExtFunction;
+import java.util.Vector;
+import java.util.ArrayList;
+import javax.xml.namespace.QName;
+
+/**
+ * 
+ * @author Ramesh Mandava ( ramesh.mandava@sun.com )
+ */
+public class JAXPExtensionsProvider implements ExtensionsProvider {
+    	
+    private final XPathFunctionResolver resolver;
+    private boolean extensionInvocationDisabled = false;
+	
+    public JAXPExtensionsProvider(XPathFunctionResolver resolver) {
+        this.resolver = resolver;
+        this.extensionInvocationDisabled = false;
+    }
+
+    public JAXPExtensionsProvider(XPathFunctionResolver resolver, 
+        boolean featureSecureProcessing ) {
+        this.resolver = resolver;
+        this.extensionInvocationDisabled = featureSecureProcessing;
+    }
+
+    /**
+     * Is the extension function available?
+     */
+
+    public boolean functionAvailable(String ns, String funcName)
+          throws javax.xml.transform.TransformerException {
+      try {
+        if ( funcName == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                new Object[] {"Function Name"} );
+            throw new NullPointerException ( fmsg ); 
+        }
+        //Find the XPathFunction corresponding to namespace and funcName
+        javax.xml.namespace.QName myQName = new QName( ns, funcName );
+        javax.xml.xpath.XPathFunction xpathFunction = 
+            resolver.resolveFunction ( myQName, 0 );
+        if (  xpathFunction == null ) {
+            return false;
+        }
+        return true;
+      } catch ( Exception e ) {
+        return false;
+      }
+       
+
+    }
+        
+
+    /**
+     * Is the extension element available?
+     */
+    public boolean elementAvailable(String ns, String elemName)
+          throws javax.xml.transform.TransformerException {
+        return false;
+    }
+
+    /**
+     * Execute the extension function.
+     */
+    public Object extFunction(String ns, String funcName, Vector argVec,
+        Object methodKey) throws javax.xml.transform.TransformerException {
+        try {
+
+            if ( funcName == null ) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"Function Name"} );
+                throw new NullPointerException ( fmsg ); 
+            }
+            //Find the XPathFunction corresponding to namespace and funcName
+            javax.xml.namespace.QName myQName = new QName( ns, funcName );
+
+            // JAXP 1.3 spec says When XMLConstants.FEATURE_SECURE_PROCESSING 
+            // feature is set then invocation of extension functions need to
+            // throw XPathFunctionException
+            if ( extensionInvocationDisabled ) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,
+                    new Object[] { myQName.toString() } );
+                throw new XPathFunctionException ( fmsg );
+            }
+
+            // Assuming user is passing all the needed parameters ( including
+            // default values )
+            int arity = argVec.size();
+
+            javax.xml.xpath.XPathFunction xpathFunction = 
+                resolver.resolveFunction ( myQName, arity );
+
+            // not using methodKey
+            ArrayList argList = new ArrayList( arity);
+            for ( int i=0; i<arity; i++ ) {
+                Object argument = argVec.elementAt( i );
+                // XNodeSet object() returns NodeVector and not NodeList
+                // Explicitly getting NodeList by using nodelist()
+                if ( argument instanceof XNodeSet ) {
+                    argList.add ( i, ((XNodeSet)argument).nodelist() );
+                } else if ( argument instanceof XObject ) {
+                    Object passedArgument = ((XObject)argument).object();
+                    argList.add ( i, passedArgument );
+                } else {
+                    argList.add ( i, argument );
+                }
+            }
+
+            return ( xpathFunction.evaluate ( argList ));
+        } catch ( XPathFunctionException xfe ) {
+            // If we get XPathFunctionException then we want to terminate
+            // further execution by throwing WrappedRuntimeException 
+            throw new org.apache.xml.utils.WrappedRuntimeException ( xfe );
+        } catch ( Exception e ) {
+            throw new javax.xml.transform.TransformerException ( e );
+        }
+    
+    }
+
+    /**
+     * Execute the extension function.
+     */
+    public Object extFunction(FuncExtFunction extFunction,
+                              Vector argVec)
+        throws javax.xml.transform.TransformerException {
+        try {
+            String namespace = extFunction.getNamespace();
+            String functionName = extFunction.getFunctionName();
+            int arity = extFunction.getArgCount();
+            javax.xml.namespace.QName myQName = 
+                new javax.xml.namespace.QName( namespace, functionName );
+
+            // JAXP 1.3 spec says  When XMLConstants.FEATURE_SECURE_PROCESSING
+            // feature is set then invocation of extension functions need to
+            // throw XPathFunctionException
+            if ( extensionInvocationDisabled ) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,                    new Object[] { myQName.toString() } );
+                throw new XPathFunctionException ( fmsg );
+            }
+
+            XPathFunction xpathFunction = 
+                resolver.resolveFunction( myQName, arity );
+
+            ArrayList argList = new ArrayList( arity);
+            for ( int i=0; i<arity; i++ ) {
+                Object argument = argVec.elementAt( i );
+                // XNodeSet object() returns NodeVector and not NodeList
+                // Explicitly getting NodeList by using nodelist()
+                if ( argument instanceof XNodeSet ) {
+                    argList.add ( i, ((XNodeSet)argument).nodelist() );
+                } else if ( argument instanceof XObject ) {
+                    Object passedArgument = ((XObject)argument).object();
+                    argList.add ( i, passedArgument );
+                } else {
+                    argList.add ( i, argument );
+                }
+            }
+       
+            return ( xpathFunction.evaluate ( argList ));
+
+        } catch ( XPathFunctionException xfe ) {
+            // If we get XPathFunctionException then we want to terminate 
+            // further execution by throwing WrappedRuntimeException
+            throw new org.apache.xml.utils.WrappedRuntimeException ( xfe );
+        } catch ( Exception e ) {
+            throw new javax.xml.transform.TransformerException ( e );
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/xpath/jaxp/JAXPPrefixResolver.java b/src/main/java/org/apache/xpath/jaxp/JAXPPrefixResolver.java
new file mode 100644
index 0000000..9208dc1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/JAXPPrefixResolver.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// $Id: JAXPPrefixResolver.java 468655 2006-10-28 07:12:06Z minchau $
+
+package org.apache.xpath.jaxp;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NamedNodeMap;
+import org.apache.xml.utils.PrefixResolver;
+
+import javax.xml.namespace.NamespaceContext;
+
+/**
+ * <meta name="usage" content="general"/>
+ * This class implements a Default PrefixResolver which
+ * can be used to perform prefix-to-namespace lookup
+ * for the XPath object.
+ * This class delegates the resolution to the passed NamespaceContext
+ */
+public class JAXPPrefixResolver implements PrefixResolver
+{
+
+    private NamespaceContext namespaceContext;
+    
+
+    public JAXPPrefixResolver ( NamespaceContext nsContext ) {
+        this.namespaceContext = nsContext;
+    } 
+
+
+    public String getNamespaceForPrefix( String prefix ) {
+        return namespaceContext.getNamespaceURI( prefix );
+    }
+
+    /**
+     * Return the base identifier.
+     *
+     * @return null
+     */
+    public String getBaseIdentifier() {
+        return null;
+    }
+
+    /**
+     * @see PrefixResolver#handlesNullPrefixes() 
+     */
+    public boolean handlesNullPrefixes() {
+        return false;
+    }
+
+
+    /**
+     * The URI for the XML namespace.
+     * (Duplicate of that found in org.apache.xpath.XPathContext). 
+     */
+     
+    public static final String S_XMLNAMESPACEURI =
+        "http://www.w3.org/XML/1998/namespace";
+
+
+    /**
+     * Given a prefix and a Context Node, get the corresponding namespace.
+     * Warning: This will not work correctly if namespaceContext
+     * is an attribute node.
+     * @param prefix Prefix to resolve.
+     * @param namespaceContext Node from which to start searching for a
+     * xmlns attribute that binds a prefix to a namespace.
+     * @return Namespace that prefix resolves to, or null if prefix
+     * is not bound.
+     */
+    public String getNamespaceForPrefix(String prefix,
+                                      org.w3c.dom.Node namespaceContext) {
+        Node parent = namespaceContext;
+        String namespace = null;
+
+        if (prefix.equals("xml")) {
+            namespace = S_XMLNAMESPACEURI;
+        } else {
+            int type;
+
+            while ((null != parent) && (null == namespace)
+                && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
+                    || (type == Node.ENTITY_REFERENCE_NODE))) {
+
+                if (type == Node.ELEMENT_NODE) {
+                    NamedNodeMap nnm = parent.getAttributes();
+
+                    for (int i = 0; i < nnm.getLength(); i++) {
+                        Node attr = nnm.item(i);
+                        String aname = attr.getNodeName();
+                        boolean isPrefix = aname.startsWith("xmlns:");
+
+                        if (isPrefix || aname.equals("xmlns")) {
+                            int index = aname.indexOf(':');
+                            String p =isPrefix ?aname.substring(index + 1) :"";
+
+                            if (p.equals(prefix)) {
+                                namespace = attr.getNodeValue();
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                parent = parent.getParentNode();
+            }
+        }
+        return namespace;
+    }
+
+}
+
diff --git a/src/main/java/org/apache/xpath/jaxp/JAXPVariableStack.java b/src/main/java/org/apache/xpath/jaxp/JAXPVariableStack.java
new file mode 100644
index 0000000..ec076ea
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/JAXPVariableStack.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// $Id: JAXPVariableStack.java 524815 2007-04-02 15:52:15Z zongaro $
+
+package org.apache.xpath.jaxp;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathVariableResolver;
+
+import org.apache.xml.utils.QName;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xalan.res.XSLMessages;
+
+
+/**
+ * Overrides {@link VariableStack} and delegates the call to
+ * {@link javax.xml.xpath.XPathVariableResolver}.
+ * 
+ * @author Ramesh Mandava ( ramesh.mandava@sun.com )
+ */
+public class JAXPVariableStack extends VariableStack {
+    	
+    private final XPathVariableResolver resolver;
+	
+    public JAXPVariableStack(XPathVariableResolver resolver) {
+        super(2);
+        this.resolver = resolver;
+    }
+	
+    public XObject getVariableOrParam(XPathContext xctxt, QName qname)
+        throws TransformerException,IllegalArgumentException {
+        if ( qname == null ) {
+            //JAXP 1.3 spec says that if variable name is null then 
+            // we need to through IllegalArgumentException
+            String fmsg = XSLMessages.createXPATHMessage( 
+                XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                new Object[] {"Variable qname"} );
+            throw new IllegalArgumentException( fmsg );
+        }
+	javax.xml.namespace.QName name =
+	    new javax.xml.namespace.QName(
+                qname.getNamespace(),
+                qname.getLocalPart());
+        Object varValue = resolver.resolveVariable( name );		
+        if ( varValue == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                XPATHErrorResources.ER_RESOLVE_VARIABLE_RETURNS_NULL,
+                new Object[] { name.toString()} );
+            throw new TransformerException( fmsg );
+        } 
+        return XObject.create( varValue, xctxt );
+    }
+
+}
diff --git a/src/main/java/org/apache/xpath/jaxp/XPathExpressionImpl.java b/src/main/java/org/apache/xpath/jaxp/XPathExpressionImpl.java
new file mode 100644
index 0000000..ba6c1b4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/XPathExpressionImpl.java
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// $Id: XPathExpressionImpl.java 524813 2007-04-02 15:52:07Z zongaro $
+
+package org.apache.xpath.jaxp;
+
+import org.apache.xpath.*;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xalan.res.XSLMessages;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.traversal.NodeIterator;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+
+import org.xml.sax.InputSource;
+
+/**
+ * The XPathExpression interface encapsulates a (compiled) XPath expression.
+ *
+ * @version $Revision: 524813 $
+ * @author  Ramesh Mandava
+ */
+public class XPathExpressionImpl  implements javax.xml.xpath.XPathExpression{
+
+    private XPathFunctionResolver functionResolver;
+    private XPathVariableResolver variableResolver;
+    private JAXPPrefixResolver prefixResolver;
+    private org.apache.xpath.XPath xpath;
+
+    // By default Extension Functions are allowed in XPath Expressions. If
+    // Secure Processing Feature is set on XPathFactory then the invocation of
+    // extensions function need to throw XPathFunctionException
+    private boolean featureSecureProcessing = false;
+
+    /** Protected constructor to prevent direct instantiation; use compile()
+     * from the context.
+     */
+    protected XPathExpressionImpl() { };
+
+    protected XPathExpressionImpl(org.apache.xpath.XPath xpath, 
+            JAXPPrefixResolver prefixResolver, 
+            XPathFunctionResolver functionResolver,
+            XPathVariableResolver variableResolver ) { 
+        this.xpath = xpath;
+        this.prefixResolver = prefixResolver;
+        this.functionResolver = functionResolver;
+        this.variableResolver = variableResolver;
+        this.featureSecureProcessing = false;
+    };
+
+    protected XPathExpressionImpl(org.apache.xpath.XPath xpath,
+            JAXPPrefixResolver prefixResolver,
+            XPathFunctionResolver functionResolver,
+            XPathVariableResolver variableResolver,
+            boolean featureSecureProcessing ) { 
+        this.xpath = xpath;
+        this.prefixResolver = prefixResolver;
+        this.functionResolver = functionResolver;
+        this.variableResolver = variableResolver;
+        this.featureSecureProcessing = featureSecureProcessing;
+    };
+
+    public void setXPath (org.apache.xpath.XPath xpath ) {
+        this.xpath = xpath;
+    }  
+
+    public Object eval(Object item, QName returnType)
+            throws javax.xml.transform.TransformerException {
+        XObject resultObject = eval ( item );
+        return getResultAsType( resultObject, returnType );
+    }
+    
+    private XObject eval ( Object contextItem )
+            throws javax.xml.transform.TransformerException {
+        org.apache.xpath.XPathContext xpathSupport = null;
+
+        // Create an XPathContext that doesn't support pushing and popping of
+        // variable resolution scopes.  Sufficient for simple XPath 1.0
+        // expressions.
+        if ( functionResolver != null ) {
+            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
+                    functionResolver, featureSecureProcessing );
+            xpathSupport = new org.apache.xpath.XPathContext(jep, false);
+        } else {
+            xpathSupport = new org.apache.xpath.XPathContext(false);
+        }
+
+        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
+        XObject xobj = null;
+          
+        Node contextNode = (Node)contextItem;
+        // We always need to have a ContextNode with Xalan XPath implementation
+        // To allow simple expression evaluation like 1+1 we are setting 
+        // dummy Document as Context Node
+        if ( contextNode == null ) {
+              contextNode = getDummyDocument();
+        } 
+
+        xobj = xpath.execute(xpathSupport, contextNode, prefixResolver );
+        return xobj;
+    }
+
+
+    /**
+     * <p>Evaluate the compiled XPath expression in the specified context and
+     *  return the result as the specified type.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     * for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If <code>returnType</code> is not one of the types defined 
+     * in {@link XPathConstants},
+     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * <p>If a <code>null</code> value is provided for
+     * <code>item</code>, an empty document will be used for the
+     * context.
+     * If <code>returnType</code> is <code>null</code>, then a 
+     * <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param item The starting context (node or node list, for example).
+     * @param returnType The desired return type.
+     *
+     * @return The <code>Object</code> that is the result of evaluating the
+     * expression and converting the result to
+     *   <code>returnType</code>.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If <code>returnType</code> is not one
+     * of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If  <code>returnType</code> is
+     * <code>null</code>.
+     */
+    public Object evaluate(Object item, QName returnType)
+        throws XPathExpressionException {
+        //Validating parameters to enforce constraints defined by JAXP spec
+        if ( returnType == null ) {
+           //Throwing NullPointerException as defined in spec
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"returnType"} );
+            throw new NullPointerException( fmsg );
+        }
+        // Checking if requested returnType is supported. returnType need to be
+        // defined in XPathConstants 
+        if ( !isSupported ( returnType ) ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                    new Object[] { returnType.toString() } );
+            throw new IllegalArgumentException ( fmsg );
+        }
+        try { 
+            return eval( item, returnType);
+        } catch ( java.lang.NullPointerException npe ) {
+            // If VariableResolver returns null Or if we get 
+            // NullPointerException at this stage for some other reason
+            // then we have to reurn XPathException
+            throw new XPathExpressionException ( npe );
+        } catch ( javax.xml.transform.TransformerException te ) {
+            Throwable nestedException = te.getException();
+            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+                throw (javax.xml.xpath.XPathFunctionException)nestedException;
+            } else {
+                // For any other exceptions we need to throw
+                // XPathExpressionException ( as per spec )
+                throw new XPathExpressionException( te);
+            }
+        }
+
+    }
+    
+    /**
+     * <p>Evaluate the compiled XPath expression in the specified context and
+     * return the result as a <code>String</code>.</p>
+     *
+     * <p>This method calls {@link #evaluate(Object item, QName returnType)}
+     * with a <code>returnType</code> of
+     * {@link XPathConstants#STRING}.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     *  for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If a <code>null</code> value is provided for
+     * <code>item</code>, an empty document will be used for the
+     * context.
+     *
+     * @param item The starting context (node or node list, for example).
+     *
+     * @return The <code>String</code> that is the result of evaluating the
+     * expression and converting the result to a
+     *   <code>String</code>.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     */
+    public String evaluate(Object item) 
+        throws XPathExpressionException {
+        return (String)this.evaluate( item, XPathConstants.STRING );
+    }
+
+
+
+    static DocumentBuilderFactory dbf = null;
+    static DocumentBuilder db = null;
+    static Document d = null;
+
+    /**
+     * <p>Evaluate the compiled XPath expression in the context of the 
+     * specified <code>InputSource</code> and return the result as the
+     *  specified type.</p>
+     *
+     * <p>This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluate(Object item, QName returnType)} on the resulting 
+     * document object.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     *  for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If <code>returnType</code> is not one of the types defined in 
+     * {@link XPathConstants},
+     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     *<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
+     * then a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param source The <code>InputSource</code> of the document to evaluate
+     * over.
+     * @param returnType The desired return type.
+     *
+     * @return The <code>Object</code> that is the result of evaluating the
+     * expression and converting the result to
+     *   <code>returnType</code>.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If <code>returnType</code> is not one
+     * of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If  <code>source</code> or 
+     * <code>returnType</code> is <code>null</code>.
+     */
+    public Object evaluate(InputSource source, QName returnType)
+        throws XPathExpressionException {
+        if ( ( source == null ) || ( returnType == null ) ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
+                    null );
+            throw new NullPointerException ( fmsg );
+        }
+        // Checking if requested returnType is supported. returnType need to be
+        // defined in XPathConstants 
+        if ( !isSupported ( returnType ) ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                    new Object[] { returnType.toString() } );
+            throw new IllegalArgumentException ( fmsg );
+        }
+        try {
+            if ( dbf == null ) {
+                dbf = DocumentBuilderFactory.newInstance();
+                dbf.setNamespaceAware( true );
+                dbf.setValidating( false );
+            }
+            db = dbf.newDocumentBuilder();
+            Document document = db.parse( source );
+            return eval(  document, returnType );
+        } catch ( Exception e ) {
+            throw new XPathExpressionException ( e );
+        }
+    }
+
+    /**
+     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
+     * <code>String</code>.</p>
+     *
+     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
+     * {@link XPathConstants#STRING}.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     * for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param source The <code>InputSource</code> of the document to evaluate over.
+     *
+     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
+     *   <code>String</code>.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws NullPointerException If  <code>source</code> is <code>null</code>.
+     */
+    public String evaluate(InputSource source)
+        throws XPathExpressionException {
+        return (String)this.evaluate( source, XPathConstants.STRING );
+    }
+
+    private boolean isSupported( QName returnType ) {
+        // XPathConstants.STRING
+        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
+             ( returnType.equals( XPathConstants.NUMBER ) ) ||
+             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
+             ( returnType.equals( XPathConstants.NODE ) ) ||
+             ( returnType.equals( XPathConstants.NODESET ) )  ) {
+    
+            return true;
+        }
+        return false;
+     }
+
+     private Object getResultAsType( XObject resultObject, QName returnType )
+        throws javax.xml.transform.TransformerException {
+        // XPathConstants.STRING
+        if ( returnType.equals( XPathConstants.STRING ) ) {
+            return resultObject.str();
+        }
+        // XPathConstants.NUMBER
+        if ( returnType.equals( XPathConstants.NUMBER ) ) {
+            return new Double ( resultObject.num());
+        }
+        // XPathConstants.BOOLEAN
+        if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
+            return new Boolean( resultObject.bool());
+        }
+        // XPathConstants.NODESET ---ORdered, UNOrdered???
+        if ( returnType.equals( XPathConstants.NODESET ) ) {
+            return resultObject.nodelist();
+        }
+        // XPathConstants.NODE
+        if ( returnType.equals( XPathConstants.NODE ) ) {
+            NodeIterator ni = resultObject.nodeset();
+            //Return the first node, or null
+            return ni.nextNode();
+        }
+        // If isSupported check is already done then the execution path 
+        // shouldn't come here. Being defensive
+        String fmsg = XSLMessages.createXPATHMessage( 
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString()});
+        throw new IllegalArgumentException ( fmsg );
+    }
+
+
+    private static Document getDummyDocument( ) {
+        try {
+            if ( dbf == null ) {
+                dbf = DocumentBuilderFactory.newInstance();
+                dbf.setNamespaceAware( true );
+                dbf.setValidating( false );
+            }
+            db = dbf.newDocumentBuilder();
+
+            DOMImplementation dim = db.getDOMImplementation();
+            d = dim.createDocument("http://java.sun.com/jaxp/xpath",
+                "dummyroot", null);
+            return d;
+        } catch ( Exception e ) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+
+
+}
diff --git a/src/main/java/org/apache/xpath/jaxp/XPathFactoryImpl.java b/src/main/java/org/apache/xpath/jaxp/XPathFactoryImpl.java
new file mode 100644
index 0000000..669673e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/XPathFactoryImpl.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// $Id: XPathFactoryImpl.java 468655 2006-10-28 07:12:06Z minchau $
+
+package org.apache.xpath.jaxp;
+
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xalan.res.XSLMessages;
+
+import javax.xml.XMLConstants;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+
+/**
+ * The XPathFactory builds XPaths.
+ *
+ * @version $Revision: 468655 $
+ * @author  Ramesh Mandava
+ */
+public  class XPathFactoryImpl extends XPathFactory {
+	
+	/**
+	 * <p>Name of class as a constant to use for debugging.</p>
+	 */
+	private static final String CLASS_NAME = "XPathFactoryImpl";
+	
+	/**
+	 *<p>XPathFunctionResolver for this XPathFactory and created XPaths.</p>
+	 */
+	private XPathFunctionResolver xPathFunctionResolver = null;
+	
+	/**
+	 * <p>XPathVariableResolver for this XPathFactory and created XPaths</p>
+	 */
+	private XPathVariableResolver xPathVariableResolver = null;
+
+	/**
+	 * <p>State of secure processing feature.</p>
+	 */
+	private boolean featureSecureProcessing = false;
+		
+	/**
+	 * <p>Is specified object model supported by this 
+         * <code>XPathFactory</code>?</p>
+	 * 
+	 * @param objectModel Specifies the object model which the returned
+         * <code>XPathFactory</code> will understand.
+	 *  
+	 * @return <code>true</code> if <code>XPathFactory</code> supports 
+         * <code>objectModel</code>, else <code>false</code>.
+	 * 
+	 * @throws NullPointerException If <code>objectModel</code> is <code>null</code>.
+	 * @throws IllegalArgumentException If <code>objectModel.length() == 0</code>.
+	 */
+	public boolean isObjectModelSupported(String objectModel) {
+		
+            if (objectModel == null) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                        XPATHErrorResources.ER_OBJECT_MODEL_NULL,
+                        new Object[] { this.getClass().getName() } );
+
+                throw new NullPointerException( fmsg );
+            }
+		
+            if (objectModel.length() == 0) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                        XPATHErrorResources.ER_OBJECT_MODEL_EMPTY,
+                        new Object[] { this.getClass().getName() } );
+                throw new IllegalArgumentException( fmsg );
+            }
+		
+	    // know how to support default object model, W3C DOM
+            if (objectModel.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) {
+                return true;
+            }
+		
+            // don't know how to support anything else
+            return false;
+	}
+
+        /**
+         * <p>Returns a new <code>XPath</code> object using the underlying
+         * object model determined when the factory was instantiated.</p>
+	 * 
+	 * @return New <code>XPath</code>
+	 */
+	public javax.xml.xpath.XPath newXPath() {
+	    return new org.apache.xpath.jaxp.XPathImpl(
+                    xPathVariableResolver, xPathFunctionResolver,
+                    featureSecureProcessing );
+	}
+	    
+	/**
+	 * <p>Set a feature for this <code>XPathFactory</code> and 
+         * <code>XPath</code>s created by this factory.</p>
+	 * 
+	 * <p>
+	 * Feature names are fully qualified {@link java.net.URI}s.
+	 * Implementations may define their own features.
+	 * An {@link XPathFactoryConfigurationException} is thrown if this
+         * <code>XPathFactory</code> or the <code>XPath</code>s
+	 *  it creates cannot support the feature.
+	 * It is possible for an <code>XPathFactory</code> to expose a feature
+         * value but be unable to change its state.
+	 * </p>
+	 * 
+	 * <p>See {@link javax.xml.xpath.XPathFactory} for full documentation
+         * of specific features.</p>
+	 * 
+	 * @param name Feature name.
+	 * @param value Is feature state <code>true</code> or <code>false</code>.
+	 *  
+	 * @throws XPathFactoryConfigurationException if this 
+         * <code>XPathFactory</code> or the <code>XPath</code>s
+	 *   it creates cannot support this feature.
+         * @throws NullPointerException if <code>name</code> is 
+         * <code>null</code>.
+	 */
+	public void setFeature(String name, boolean value)
+		throws XPathFactoryConfigurationException {
+			
+            // feature name cannot be null
+            if (name == null) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                        XPATHErrorResources.ER_FEATURE_NAME_NULL,
+                        new Object[] { CLASS_NAME, new Boolean( value) } );
+                throw new NullPointerException( fmsg );
+             }
+		
+            // secure processing?
+            if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+
+                featureSecureProcessing = value;
+						
+                // all done processing feature
+                return;
+            }
+		
+            // unknown feature
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_FEATURE_UNKNOWN,
+                    new Object[] { name, CLASS_NAME, new Boolean(value) } );
+            throw new XPathFactoryConfigurationException( fmsg );
+	}
+
+	/**
+	 * <p>Get the state of the named feature.</p>
+	 * 
+	 * <p>
+	 * Feature names are fully qualified {@link java.net.URI}s.
+	 * Implementations may define their own features.
+	 * An {@link XPathFactoryConfigurationException} is thrown if this
+         * <code>XPathFactory</code> or the <code>XPath</code>s
+	 * it creates cannot support the feature.
+	 * It is possible for an <code>XPathFactory</code> to expose a feature 
+         * value but be unable to change its state.
+	 * </p>
+	 * 
+	 * @param name Feature name.
+	 * 
+	 * @return State of the named feature.
+	 * 
+	 * @throws XPathFactoryConfigurationException if this 
+         * <code>XPathFactory</code> or the <code>XPath</code>s
+	 *   it creates cannot support this feature.
+         * @throws NullPointerException if <code>name</code> is 
+         * <code>null</code>.
+	 */
+	public boolean getFeature(String name)
+		throws XPathFactoryConfigurationException {
+
+            // feature name cannot be null
+            if (name == null) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                        XPATHErrorResources.ER_GETTING_NULL_FEATURE,
+                        new Object[] { CLASS_NAME } );
+                throw new NullPointerException( fmsg );
+            }
+		
+            // secure processing?
+            if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+                return featureSecureProcessing;
+            }
+		
+            // unknown feature
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_GETTING_UNKNOWN_FEATURE,
+                    new Object[] { name, CLASS_NAME } );
+
+            throw new XPathFactoryConfigurationException( fmsg );
+        }
+		
+	/**
+         * <p>Establish a default function resolver.</p>
+         * 
+	 * <p>Any <code>XPath</code> objects constructed from this factory will use
+	 * the specified resolver by default.</p>
+	 *
+	 * <p>A <code>NullPointerException</code> is thrown if 
+         * <code>resolver</code> is <code>null</code>.</p>
+         * 
+	 * @param resolver XPath function resolver.
+	 * 
+	 * @throws NullPointerException If <code>resolver</code> is 
+         * <code>null</code>.
+	 */
+        public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
+			
+            // resolver cannot be null
+            if (resolver == null) {
+                String fmsg = XSLMessages.createXPATHMessage(
+                        XPATHErrorResources.ER_NULL_XPATH_FUNCTION_RESOLVER,
+                        new Object[] {  CLASS_NAME } );
+                throw new NullPointerException( fmsg );
+            }
+			
+            xPathFunctionResolver = resolver;
+        }
+		
+	/**
+	 * <p>Establish a default variable resolver.</p>
+	 *
+	 * <p>Any <code>XPath</code> objects constructed from this factory will use
+	 * the specified resolver by default.</p>
+	 * 
+	 * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
+	 * 
+	 * @param resolver Variable resolver.
+	 * 
+	 *  @throws NullPointerException If <code>resolver</code> is 
+         * <code>null</code>.
+	 */
+	public void setXPathVariableResolver(XPathVariableResolver resolver) {
+
+		// resolver cannot be null
+		if (resolver == null) {
+                    String fmsg = XSLMessages.createXPATHMessage(
+                            XPATHErrorResources.ER_NULL_XPATH_VARIABLE_RESOLVER,
+                            new Object[] {  CLASS_NAME } );
+		    throw new NullPointerException( fmsg );
+		}
+			
+		xPathVariableResolver = resolver;
+	}
+}
+
+
+
diff --git a/src/main/java/org/apache/xpath/jaxp/XPathImpl.java b/src/main/java/org/apache/xpath/jaxp/XPathImpl.java
new file mode 100644
index 0000000..9889e48
--- /dev/null
+++ b/src/main/java/org/apache/xpath/jaxp/XPathImpl.java
@@ -0,0 +1,545 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// $Id: XPathImpl.java 524814 2007-04-02 15:52:11Z zongaro $
+
+package org.apache.xpath.jaxp;
+
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+import javax.xml.xpath.XPathExpression;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.*;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xalan.res.XSLMessages;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.traversal.NodeIterator;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.*;
+
+import java.io.IOException;
+
+/**
+ * The XPathImpl class provides implementation for the methods defined  in
+ * javax.xml.xpath.XPath interface. This provide simple access to the results
+ * of an XPath expression.
+ *
+ *
+ * @version $Revision: 524814 $
+ * @author  Ramesh Mandava
+ */
+public class XPathImpl implements javax.xml.xpath.XPath {
+
+    // Private variables
+    private XPathVariableResolver variableResolver;
+    private XPathFunctionResolver functionResolver;
+    private XPathVariableResolver origVariableResolver;
+    private XPathFunctionResolver origFunctionResolver;
+    private NamespaceContext namespaceContext=null;
+    private JAXPPrefixResolver prefixResolver;
+    // By default Extension Functions are allowed in XPath Expressions. If 
+    // Secure Processing Feature is set on XPathFactory then the invocation of
+    // extensions function need to throw XPathFunctionException
+    private boolean featureSecureProcessing = false; 
+
+    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) {
+        this.origVariableResolver = this.variableResolver = vr;
+        this.origFunctionResolver = this.functionResolver = fr;
+    }
+
+    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, 
+            boolean featureSecureProcessing ) {
+        this.origVariableResolver = this.variableResolver = vr;
+        this.origFunctionResolver = this.functionResolver = fr;
+        this.featureSecureProcessing = featureSecureProcessing;
+    }
+
+    /**
+     * <p>Establishes a variable resolver.</p>
+     *
+     * @param resolver Variable Resolver
+     */
+    public void setXPathVariableResolver(XPathVariableResolver resolver) {
+        if ( resolver == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"XPathVariableResolver"} );
+            throw new NullPointerException( fmsg );
+        }
+        this.variableResolver = resolver;
+    }
+
+    /**
+     * <p>Returns the current variable resolver.</p>
+     *
+     * @return Current variable resolver
+     */
+    public XPathVariableResolver getXPathVariableResolver() {
+        return variableResolver;
+    }
+
+    /**
+     * <p>Establishes a function resolver.</p>
+     *
+     * @param resolver XPath function resolver
+     */
+    public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
+        if ( resolver == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"XPathFunctionResolver"} );
+            throw new NullPointerException( fmsg );
+        }
+        this.functionResolver = resolver;
+    }
+
+    /**
+     * <p>Returns the current function resolver.</p>
+     *
+     * @return Current function resolver
+     */
+    public XPathFunctionResolver getXPathFunctionResolver() {
+        return functionResolver;
+    }
+
+    /**
+     * <p>Establishes a namespace context.</p>
+     *
+     * @param nsContext Namespace context to use
+     */
+    public void setNamespaceContext(NamespaceContext nsContext) {
+        if ( nsContext == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"NamespaceContext"} );
+            throw new NullPointerException( fmsg ); 
+        }
+        this.namespaceContext = nsContext;
+        this.prefixResolver = new JAXPPrefixResolver ( nsContext );
+    }
+
+    /**
+     * <p>Returns the current namespace context.</p>
+     *
+     * @return Current Namespace context
+     */
+    public NamespaceContext getNamespaceContext() {
+        return namespaceContext;
+    }
+
+    private static Document d = null;
+    
+    private static DocumentBuilder getParser() {
+        try {
+            // we'd really like to cache those DocumentBuilders, but we can't because:
+            // 1. thread safety. parsers are not thread-safe, so at least
+            //    we need one instance per a thread.
+            // 2. parsers are non-reentrant, so now we are looking at having a
+            // pool of parsers.
+            // 3. then the class loading issue. The look-up procedure of
+            //    DocumentBuilderFactory.newInstance() depends on context class loader
+            //    and system properties, which may change during the execution of JVM.
+            //
+            // so we really have to create a fresh DocumentBuilder every time we need one
+            // - KK
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            dbf.setNamespaceAware( true );
+            dbf.setValidating( false );
+            return dbf.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            // this should never happen with a well-behaving JAXP implementation. 
+            throw new Error(e.toString());
+        }
+    }
+
+    private static Document getDummyDocument( ) {
+        // we don't need synchronization here; even if two threads
+        // enter this code at the same time, we just waste a little time
+        if(d==null) {
+            DOMImplementation dim = getParser().getDOMImplementation();
+            d = dim.createDocument("http://java.sun.com/jaxp/xpath",
+                "dummyroot", null);
+        }
+        return d;
+    }
+
+    
+    private XObject eval(String expression, Object contextItem)
+        throws javax.xml.transform.TransformerException {
+        org.apache.xpath.XPath xpath = new org.apache.xpath.XPath( expression,
+            null, prefixResolver, org.apache.xpath.XPath.SELECT ); 
+        org.apache.xpath.XPathContext xpathSupport = null;
+
+        // Create an XPathContext that doesn't support pushing and popping of
+        // variable resolution scopes.  Sufficient for simple XPath 1.0
+        // expressions.
+        if ( functionResolver != null ) {
+            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
+                    functionResolver, featureSecureProcessing );
+            xpathSupport = new org.apache.xpath.XPathContext(jep, false);
+        } else { 
+            xpathSupport = new org.apache.xpath.XPathContext(false);
+        }
+
+        XObject xobj = null;
+        
+        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
+        
+        // If item is null, then we will create a a Dummy contextNode
+        if ( contextItem instanceof Node ) {
+            xobj = xpath.execute (xpathSupport, (Node)contextItem,
+                    prefixResolver );
+        } else {
+            xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
+        }
+ 
+        return xobj;
+    }
+        
+    /**
+     * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     * for context item evaluation,
+     * variable, function and <code>QName</code> resolution and return type conversion.</p>
+     *
+     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
+     * {@link XPathConstants#NUMBER NUMBER},
+     * {@link XPathConstants#STRING STRING},
+     * {@link XPathConstants#BOOLEAN BOOLEAN},
+     * {@link XPathConstants#NODE NODE} or
+     * {@link XPathConstants#NODESET NODESET})
+     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * <p>If a <code>null</code> value is provided for
+     * <code>item</code>, an empty document will be used for the
+     * context.
+     * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
+     * <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param expression The XPath expression.
+     * @param item The starting context (node or node list, for example).
+     * @param returnType The desired return type.
+     *
+     * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
+     *
+     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
+     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
+     */
+    public Object evaluate(String expression, Object item, QName returnType)
+            throws XPathExpressionException {
+        if ( expression == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"XPath expression"} );
+            throw new NullPointerException ( fmsg );
+        }
+        if ( returnType == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"returnType"} );
+            throw new NullPointerException ( fmsg );
+        }
+        // Checking if requested returnType is supported. returnType need to
+        // be defined in XPathConstants
+        if ( !isSupported ( returnType ) ) {
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                    new Object[] { returnType.toString() } );
+            throw new IllegalArgumentException ( fmsg );
+        }
+
+        try {
+ 
+            XObject resultObject = eval( expression, item );
+            return getResultAsType( resultObject, returnType );
+        } catch ( java.lang.NullPointerException npe ) {
+            // If VariableResolver returns null Or if we get 
+            // NullPointerException at this stage for some other reason
+            // then we have to reurn XPathException 
+            throw new XPathExpressionException ( npe );
+        } catch ( javax.xml.transform.TransformerException te ) {
+            Throwable nestedException = te.getException();
+            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+                throw (javax.xml.xpath.XPathFunctionException)nestedException;
+            } else {
+                // For any other exceptions we need to throw 
+                // XPathExpressionException ( as per spec )
+                throw new XPathExpressionException ( te );
+            }
+        } 
+        
+    }
+
+    private boolean isSupported( QName returnType ) {
+        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
+             ( returnType.equals( XPathConstants.NUMBER ) ) ||
+             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
+             ( returnType.equals( XPathConstants.NODE ) ) ||
+             ( returnType.equals( XPathConstants.NODESET ) )  ) {
+  
+            return true;
+        }
+        return false;
+     }
+
+    private Object getResultAsType( XObject resultObject, QName returnType )
+        throws javax.xml.transform.TransformerException {
+        // XPathConstants.STRING
+        if ( returnType.equals( XPathConstants.STRING ) ) { 
+            return resultObject.str();
+        }
+        // XPathConstants.NUMBER
+        if ( returnType.equals( XPathConstants.NUMBER ) ) { 
+            return new Double ( resultObject.num());
+        }
+        // XPathConstants.BOOLEAN
+        if ( returnType.equals( XPathConstants.BOOLEAN ) ) { 
+            return new Boolean( resultObject.bool());
+        }
+        // XPathConstants.NODESET ---ORdered, UNOrdered???
+        if ( returnType.equals( XPathConstants.NODESET ) ) { 
+            return resultObject.nodelist();
+        }
+        // XPathConstants.NODE
+        if ( returnType.equals( XPathConstants.NODE ) ) { 
+            NodeIterator ni = resultObject.nodeset(); 
+            //Return the first node, or null
+            return ni.nextNode();
+        }
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString()});
+        throw new IllegalArgumentException( fmsg );
+    }
+         
+            
+        
+    /**
+     * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
+     *
+     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
+     * {@link XPathConstants#STRING}.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec 
+     * for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If a <code>null</code> value is provided for
+     * <code>item</code>, an empty document will be used for the
+     * context.
+     * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param expression The XPath expression.
+     * @param item The starting context (node or node list, for example).
+     *
+     * @return The <code>String</code> that is the result of evaluating the expression and
+     *   converting the result to a <code>String</code>.
+     *
+     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
+     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+     */
+    public String evaluate(String expression, Object item)
+        throws XPathExpressionException {
+        return (String)this.evaluate( expression, item, XPathConstants.STRING );
+    }
+
+    /**
+     * <p>Compile an XPath expression for later evaluation.</p>
+     *
+     * <p>If <code>expression</code> contains any {@link XPathFunction}s,
+     * they must be available via the {@link XPathFunctionResolver}.
+     * An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code>
+     * cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
+     * 
+     * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param expression The XPath expression.
+     *
+     * @return Compiled XPath expression.
+
+     * @throws XPathExpressionException If <code>expression</code> cannot be compiled.
+     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+     */
+    public XPathExpression compile(String expression)
+        throws XPathExpressionException {
+        if ( expression == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"XPath expression"} );
+            throw new NullPointerException ( fmsg );
+        }
+        try {
+            org.apache.xpath.XPath xpath = new XPath (expression, null,
+                    prefixResolver, org.apache.xpath.XPath.SELECT );
+            // Can have errorListener
+            XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
+                    prefixResolver, functionResolver, variableResolver,
+                    featureSecureProcessing );
+            return ximpl;
+        } catch ( javax.xml.transform.TransformerException te ) {
+            throw new XPathExpressionException ( te ) ;
+        }
+    }
+
+
+    /**
+     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
+     * and return the result as the specified type.</p>
+     *
+     * <p>This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 
+     * for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
+     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
+     * then a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param expression The XPath expression.
+     * @param source The input source of the document to evaluate over.
+     * @param returnType The desired return type.
+     *
+     * @return The <code>Object</code> that encapsulates the result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If expression cannot be evaluated.
+     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
+     *   is <code>null</code>.
+     */
+    public Object evaluate(String expression, InputSource source, 
+            QName returnType) throws XPathExpressionException {
+        // Checking validity of different parameters
+        if( source== null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"source"} );
+            throw new NullPointerException ( fmsg );
+        }
+        if ( expression == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"XPath expression"} );
+            throw new NullPointerException ( fmsg );
+        }
+        if ( returnType == null ) {
+            String fmsg = XSLMessages.createXPATHMessage( 
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {"returnType"} );
+            throw new NullPointerException ( fmsg );
+        }
+
+        //Checking if requested returnType is supported. 
+        //returnType need to be defined in XPathConstants
+        if ( !isSupported ( returnType ) ) {
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                    new Object[] { returnType.toString() } );
+            throw new IllegalArgumentException ( fmsg );
+        }
+        
+        try {
+
+            Document document = getParser().parse( source );
+
+            XObject resultObject = eval( expression, document );
+            return getResultAsType( resultObject, returnType );
+        } catch ( SAXException e ) {
+            throw new XPathExpressionException ( e );
+        } catch( IOException e ) {
+            throw new XPathExpressionException ( e );            
+        } catch ( javax.xml.transform.TransformerException te ) {
+            Throwable nestedException = te.getException();
+            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+                throw (javax.xml.xpath.XPathFunctionException)nestedException;
+            } else {
+                throw new XPathExpressionException ( te );
+            }
+        }
+
+    } 
+ 
+
+
+
+    /**
+     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
+     * and return the result as a <code>String</code>.</p>
+     *
+     * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
+     * <code>returnType</code> of {@link XPathConstants#STRING}.</p>
+     *
+     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
+     * for context item evaluation,
+     * variable, function and QName resolution and return type conversion.</p>
+     *
+     * <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
+     * then a <code>NullPointerException</code> is thrown.</p>
+     *
+     * @param expression The XPath expression.
+     * @param source The <code>InputSource</code> of the document to evaluate over.
+     *
+     * @return The <code>String</code> that is the result of evaluating the expression and
+     *   converting the result to a <code>String</code>.
+     *
+     * @throws XPathExpressionException If expression cannot be evaluated.
+     * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
+     */
+    public String evaluate(String expression, InputSource source)
+        throws XPathExpressionException {
+        return (String)this.evaluate( expression, source, XPathConstants.STRING );
+    }
+
+    /**
+     * <p>Reset this <code>XPath</code> to its original configuration.</p>
+     *
+     * <p><code>XPath</code> is reset to the same state as when it was created with
+     * {@link XPathFactory#newXPath()}.
+     * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
+     * thus saving resources associated with the creation of new <code>XPath</code>s.</p>
+     *
+     * <p>The reset <code>XPath</code> is not guaranteed to have the same
+     * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
+     * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
+     * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>,
+     * <code>XPathVariableResolver</code>
+     * and <code>NamespaceContext</code>.</p>
+     */
+    public void reset() {
+        this.variableResolver = this.origVariableResolver;
+        this.functionResolver = this.origFunctionResolver;
+        this.namespaceContext = null;
+    }
+ 
+}
diff --git a/src/main/java/org/apache/xpath/objects/DTMXRTreeFrag.java b/src/main/java/org/apache/xpath/objects/DTMXRTreeFrag.java
new file mode 100755
index 0000000..2c75eb4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/DTMXRTreeFrag.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+/*
+ * 
+ * @author igorh
+ *
+ * Simple wrapper to DTM and XPathContext objects.
+ * Used in XRTreeFrag for caching references to the objects.
+ */
+ public final class DTMXRTreeFrag {
+  private DTM m_dtm;
+  private int m_dtmIdentity = DTM.NULL;
+  private XPathContext m_xctxt;
+ 
+  public DTMXRTreeFrag(int dtmIdentity, XPathContext xctxt){
+      m_xctxt = xctxt;
+      m_dtmIdentity = dtmIdentity;
+      m_dtm = xctxt.getDTM(dtmIdentity); 
+    }
+
+  public final void destruct(){
+    m_dtm = null;         
+    m_xctxt = null; 
+ }
+
+final  DTM getDTM(){return m_dtm;}
+public final  int getDTMIdentity(){return m_dtmIdentity;}
+final  XPathContext getXPathContext(){return m_xctxt;}
+
+public final int hashCode() { return m_dtmIdentity; }
+public final boolean equals(Object obj) {
+   if (obj instanceof DTMXRTreeFrag) {
+       return (m_dtmIdentity == ((DTMXRTreeFrag)obj).getDTMIdentity());
+   }
+   return false;
+ }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XBoolean.java b/src/main/java/org/apache/xpath/objects/XBoolean.java
new file mode 100644
index 0000000..9bf3049
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XBoolean.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XBoolean.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+/**
+ * This class represents an XPath boolean object, and is capable of
+ * converting the boolean to other types, such as a string.
+ * @xsl.usage advanced
+ */
+public class XBoolean extends XObject
+{
+    static final long serialVersionUID = -2964933058866100881L;
+
+  /**
+   * A true boolean object so we don't have to keep creating them.
+   * @xsl.usage internal
+   */
+  public static final XBoolean S_TRUE = new XBooleanStatic(true);
+
+  /**
+   * A true boolean object so we don't have to keep creating them.
+   * @xsl.usage internal
+   */
+  public static final XBoolean S_FALSE = new XBooleanStatic(false);
+
+  /** Value of the object.
+   *  @serial         */
+  private final boolean m_val;
+
+  /**
+   * Construct a XBoolean object.
+   *
+   * @param b Value of the boolean object
+   */
+  public XBoolean(boolean b)
+  {
+
+    super();
+
+    m_val = b;
+  }
+  
+  /**
+   * Construct a XBoolean object.
+   *
+   * @param b Value of the boolean object
+   */
+  public XBoolean(Boolean b)
+  {
+
+    super();
+
+    m_val = b.booleanValue();
+    setObject(b);
+  }
+
+
+  /**
+   * Tell that this is a CLASS_BOOLEAN.
+   *
+   * @return type of CLASS_BOOLEAN
+   */
+  public int getType()
+  {
+    return CLASS_BOOLEAN;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#BOOLEAN"
+   */
+  public String getTypeString()
+  {
+    return "#BOOLEAN";
+  }
+
+  /**
+   * Cast result object to a number.
+   *
+   * @return numeric value of the object value
+   */
+  public double num()
+  {
+    return m_val ? 1.0 : 0.0;
+  }
+
+  /**
+   * Cast result object to a boolean.
+   *
+   * @return The object value as a boolean
+   */
+  public boolean bool()
+  {
+    return m_val;
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The object's value as a string
+   */
+  public String str()
+  {
+    return m_val ? "true" : "false";
+  }
+
+  /**
+   * Return a java object that's closest to the representation
+   * that should be handed to an extension.
+   *
+   * @return The object's value as a java object
+   */
+  public Object object()
+  {
+    if(null == m_obj)
+      setObject(new Boolean(m_val));
+    return m_obj;
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare to this  
+   *
+   * @return True if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.equals(this);
+
+    try
+    {
+      return m_val == obj2.bool();
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XBooleanStatic.java b/src/main/java/org/apache/xpath/objects/XBooleanStatic.java
new file mode 100644
index 0000000..0e9d7b2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XBooleanStatic.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XBooleanStatic.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+/**
+ * This class doesn't have any XPathContext, so override
+ * whatever to ensure it works OK.
+ * @xsl.usage internal
+ */
+public class XBooleanStatic extends XBoolean
+{
+    static final long serialVersionUID = -8064147275772687409L;
+
+  /** The value of the object.
+   *  @serial          */
+  private final boolean m_val;
+
+  /**
+   * Construct a XBooleanStatic object.
+   *
+   * @param b The value of the object
+   */
+  public XBooleanStatic(boolean b)
+  {
+
+    super(b);
+
+    m_val = b;
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare to this 
+   *
+   * @return True if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+    try
+    {
+      return m_val == obj2.bool();
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/objects/XMLStringFactoryImpl.java b/src/main/java/org/apache/xpath/objects/XMLStringFactoryImpl.java
new file mode 100644
index 0000000..db42db0
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XMLStringFactoryImpl.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XMLStringFactoryImpl.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+
+/**
+ * Class XMLStringFactoryImpl creates XString versions of XMLStrings.
+ * @xsl.usage internal
+ */
+public class XMLStringFactoryImpl extends XMLStringFactory
+{
+  /** The XMLStringFactory to pass to DTM construction.   */
+  private static XMLStringFactory m_xstringfactory =
+    new XMLStringFactoryImpl();
+
+  /**
+   * Get the XMLStringFactory to pass to DTM construction.
+   *
+   *
+   * @return A never-null static reference to a String factory.
+   */
+  public static XMLStringFactory getFactory()
+  {
+    return m_xstringfactory;
+  }
+
+  /**
+   * Create a new XMLString from a Java string.
+   *
+   *
+   * @param string Java String reference, which must be non-null.
+   *
+   * @return An XMLString object that wraps the String reference.
+   */
+  public XMLString newstr(String string)
+  {
+    return new XString(string);
+  }
+
+  /**
+   * Create a XMLString from a FastStringBuffer.
+   *
+   *
+   * @param fsb FastStringBuffer reference, which must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   *
+   * @return An XMLString object that wraps the FastStringBuffer reference.
+   */
+  public XMLString newstr(FastStringBuffer fsb, int start, int length)
+  {
+    return new XStringForFSB(fsb, start, length);
+  }
+  
+  /**
+   * Create a XMLString from a FastStringBuffer.
+   *
+   *
+   * @param string FastStringBuffer reference, which must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   *
+   * @return An XMLString object that wraps the FastStringBuffer reference.
+   */
+  public XMLString newstr(char[] string, int start, int length)
+  {
+    return new XStringForChars(string, start, length);
+  }
+  
+  /**
+   * Get a cheap representation of an empty string.
+   * 
+   * @return An non-null reference to an XMLString that represents "".
+   */
+  public XMLString emptystr()
+  {
+    return XString.EMPTYSTRING;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XNodeSet.java b/src/main/java/org/apache/xpath/objects/XNodeSet.java
new file mode 100644
index 0000000..2b38506
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XNodeSet.java
@@ -0,0 +1,969 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XNodeSet.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.axes.NodeSequence;
+
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * This class represents an XPath nodeset object, and is capable of
+ * converting the nodeset to other types, such as a string.
+ * @xsl.usage general
+ */
+public class XNodeSet extends NodeSequence
+{  
+    static final long serialVersionUID = 1916026368035639667L;
+  /**
+   * Default constructor for derived objects.
+   */
+  protected XNodeSet()
+  {
+  }
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val Value of the XNodeSet object
+   */
+  public XNodeSet(DTMIterator val)
+  {
+  	super();
+  	if(val instanceof XNodeSet)
+  	{
+        final XNodeSet nodeSet = (XNodeSet) val;
+	    setIter(nodeSet.m_iter);
+	    m_dtmMgr = nodeSet.m_dtmMgr;
+	    m_last = nodeSet.m_last;
+        // First make sure the DTMIterator val has a cache,
+        // so if it doesn't have one, make one.
+	    if(!nodeSet.hasCache())
+	        nodeSet.setShouldCacheNodes(true);
+        
+        // Get the cache from val and use it ourselves (we share it).
+	    setObject(nodeSet.getIteratorCache());
+  	}
+  	else
+    	setIter(val);
+  }
+  
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val Value of the XNodeSet object
+   */
+  public XNodeSet(XNodeSet val)
+  {
+  	super();
+    setIter(val.m_iter);
+    m_dtmMgr = val.m_dtmMgr;
+    m_last = val.m_last;
+    if(!val.hasCache())
+    	val.setShouldCacheNodes(true);
+    setObject(val.m_obj);
+  }
+
+
+  /**
+   * Construct an empty XNodeSet object.  This is used to create a mutable 
+   * nodeset to which random nodes may be added.
+   */
+  public XNodeSet(DTMManager dtmMgr) 
+  {
+     this(DTM.NULL,dtmMgr);
+  }
+
+  /**
+   * Construct a XNodeSet object for one node.
+   *
+   * @param n Node to add to the new XNodeSet object
+   */
+  public XNodeSet(int n, DTMManager dtmMgr)
+  {
+
+    super(new NodeSetDTM(dtmMgr));
+    m_dtmMgr = dtmMgr;
+
+    if (DTM.NULL != n)
+    {
+      ((NodeSetDTM) m_obj).addNode(n);
+      m_last = 1;
+    }
+    else
+    	m_last = 0;
+  }
+
+  /**
+   * Tell that this is a CLASS_NODESET.
+   *
+   * @return type CLASS_NODESET
+   */
+  public int getType()
+  {
+    return CLASS_NODESET;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#NODESET"
+   */
+  public String getTypeString()
+  {
+    return "#NODESET";
+  }
+
+  /**
+   * Get numeric value of the string conversion from a single node.
+   *
+   * @param n Node to convert
+   *
+   * @return numeric value of the string conversion from a single node.
+   */
+  public double getNumberFromNode(int n)
+  {
+    XMLString xstr = m_dtmMgr.getDTM(n).getStringValue(n);
+    return xstr.toDouble();
+  }
+
+  /**
+   * Cast result object to a number.
+   *
+   * @return numeric value of the string conversion from the 
+   * next node in the NodeSetDTM, or NAN if no node was found
+   */
+  public double num()
+  {
+
+    int node = item(0);
+    return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
+  }
+  
+  /**
+   * Cast result object to a number, but allow side effects, such as the 
+   * incrementing of an iterator.
+   *
+   * @return numeric value of the string conversion from the 
+   * next node in the NodeSetDTM, or NAN if no node was found
+   */
+  public double numWithSideEffects()
+  {
+    int node = nextNode();
+
+    return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
+  }
+
+
+  /**
+   * Cast result object to a boolean.
+   *
+   * @return True if there is a next node in the nodeset
+   */
+  public boolean bool()
+  {
+    return (item(0) != DTM.NULL);
+  }
+  
+  /**
+   * Cast result object to a boolean, but allow side effects, such as the 
+   * incrementing of an iterator.
+   *
+   * @return True if there is a next node in the nodeset
+   */
+  public boolean boolWithSideEffects()
+  {
+    return (nextNode() != DTM.NULL);
+  }
+
+  
+  /**
+   * Get the string conversion from a single node.
+   *
+   * @param n Node to convert
+   *
+   * @return the string conversion from a single node.
+   */
+  public XMLString getStringFromNode(int n)
+  {
+    // %OPT%
+    // I guess we'll have to get a static instance of the DTM manager...
+    if(DTM.NULL != n)
+    {
+      return m_dtmMgr.getDTM(n).getStringValue(n);
+    }
+    else
+    {
+      return org.apache.xpath.objects.XString.EMPTYSTRING;
+    }
+  }
+  
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+    int node = item(0);
+	
+    if(node != DTM.NULL)
+    {
+      m_dtmMgr.getDTM(node).dispatchCharactersEvents(node, ch, false);
+    }
+    
+  }
+  
+  /**
+   * Cast result object to an XMLString.
+   *
+   * @return The document fragment node data or the empty string. 
+   */
+  public XMLString xstr()
+  {
+    int node = item(0);
+    return (node != DTM.NULL) ? getStringFromNode(node) : XString.EMPTYSTRING;
+  }
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
+  {
+    XString xstring = (XString)xstr();
+    xstring.appendToFsb(fsb);
+  }
+  
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return the string conversion from the next node in the nodeset
+   * or "" if there is no next node
+   */
+  public String str()
+  {
+    int node = item(0);
+    return (node != DTM.NULL) ? getStringFromNode(node).toString() : "";   
+  }
+  
+  /**
+   * Return a java object that's closest to the representation
+   * that should be handed to an extension.
+   *
+   * @return The object that this class wraps
+   */
+  public Object object()
+  {
+    if(null == m_obj)
+    	return this;
+    else
+    	return m_obj;
+  }
+
+  // %REVIEW%
+  // hmmm...
+//  /**
+//   * Cast result object to a result tree fragment.
+//   *
+//   * @param support The XPath context to use for the conversion 
+//   *
+//   * @return the nodeset as a result tree fragment.
+//   */
+//  public DocumentFragment rtree(XPathContext support)
+//  {
+//    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+//    DocumentBuilder db = dbf.newDocumentBuilder();
+//    Document myDoc = db.newDocument();
+//    
+//    DocumentFragment docFrag = myDoc.createDocumentFragment();
+//
+//    DTMIterator nl = iter();
+//    int node;
+//
+//    while (DTM.NULL != (node = nl.nextNode()))
+//    {
+//      frag.appendChild(node, true, true);
+//    }
+//
+//    return frag.getDocument();
+//  }
+
+  /**
+   * Cast result object to a nodelist.
+   *
+   * @return a NodeIterator.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeIterator nodeset() throws javax.xml.transform.TransformerException
+  {
+    return new org.apache.xml.dtm.ref.DTMNodeIterator(iter());
+  }
+  
+  /**
+   * Cast result object to a nodelist.
+   *
+   * @return a NodeList.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeList nodelist() throws javax.xml.transform.TransformerException
+  {
+    org.apache.xml.dtm.ref.DTMNodeList nodelist = new org.apache.xml.dtm.ref.DTMNodeList(this);
+    // Creating a DTMNodeList has the side-effect that it will create a clone
+    // XNodeSet with cache and run m_iter to the end. You cannot get any node
+    // from m_iter after this call. As a fix, we call SetVector() on the clone's 
+    // cache. See Bugzilla 14406.
+    XNodeSet clone = (XNodeSet)nodelist.getDTMIterator();
+    SetVector(clone.getVector());
+    return nodelist;
+  }
+
+  
+//  /**
+//   * Return a java object that's closest to the representation
+//   * that should be handed to an extension.
+//   *
+//   * @return The object that this class wraps
+//   */
+//  public Object object()
+//  {
+//    return new org.apache.xml.dtm.ref.DTMNodeList(iter());
+//  }
+
+  /**
+   * Return the iterator without cloning, etc.
+   */
+  public DTMIterator iterRaw()
+  {
+    return this;
+  }
+  
+  public void release(DTMIterator iter)
+  {
+  }
+  
+  /**
+   * Cast result object to a nodelist.
+   *
+   * @return The nodeset as a nodelist
+   */
+  public DTMIterator iter()
+  {
+    try
+    {
+    	if(hasCache())
+      		return cloneWithReset();
+      	else
+      		return this; // don't bother to clone... won't do any good!
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      throw new RuntimeException(cnse.getMessage());
+    }
+  }
+  
+  /**
+   * Get a fresh copy of the object.  For use with variables.
+   *
+   * @return A fresh nodelist.
+   */
+  public XObject getFresh()
+  {
+    try
+    {
+    	if(hasCache())
+      		return (XObject)cloneWithReset();
+      	else
+      		return this; // don't bother to clone... won't do any good!
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      throw new RuntimeException(cnse.getMessage());
+    }
+  }
+
+  /**
+   * Cast result object to a mutableNodeset.
+   *
+   * @return The nodeset as a mutableNodeset
+   */
+  public NodeSetDTM mutableNodeset()
+  {
+    NodeSetDTM mnl;
+
+    if(m_obj instanceof NodeSetDTM)
+    {
+      mnl = (NodeSetDTM) m_obj;
+    }
+    else
+    {
+      mnl = new NodeSetDTM(iter());
+      setObject(mnl);
+      setCurrentPos(0);
+    }
+
+    return mnl;
+  }
+
+  /** Less than comparator         */
+  static final LessThanComparator S_LT = new LessThanComparator();
+
+  /** Less than or equal comparator          */
+  static final LessThanOrEqualComparator S_LTE = new LessThanOrEqualComparator();
+
+  /** Greater than comparator         */
+  static final GreaterThanComparator S_GT = new GreaterThanComparator();
+
+  /** Greater than or equal comparator          */
+  static final GreaterThanOrEqualComparator S_GTE =
+    new GreaterThanOrEqualComparator();
+
+  /** Equal comparator         */
+  static final EqualComparator S_EQ = new EqualComparator();
+
+  /** Not equal comparator         */
+  static final NotEqualComparator S_NEQ = new NotEqualComparator();
+
+  /**
+   * Tell if one object is less than the other.
+   *
+   * @param obj2 Object to compare this nodeset to
+   * @param comparator Comparator to use
+   *
+   * @return See the comments below for each object type comparison 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean compare(XObject obj2, Comparator comparator)
+          throws javax.xml.transform.TransformerException
+  {
+
+    boolean result = false;
+    int type = obj2.getType();
+
+    if (XObject.CLASS_NODESET == type)
+    {
+      // %OPT% This should be XMLString based instead of string based...
+
+      // From http://www.w3.org/TR/xpath: 
+      // If both objects to be compared are node-sets, then the comparison 
+      // will be true if and only if there is a node in the first node-set 
+      // and a node in the second node-set such that the result of performing 
+      // the comparison on the string-values of the two nodes is true.
+      // Note this little gem from the draft:
+      // NOTE: If $x is bound to a node-set, then $x="foo" 
+      // does not mean the same as not($x!="foo"): the former 
+      // is true if and only if some node in $x has the string-value 
+      // foo; the latter is true if and only if all nodes in $x have 
+      // the string-value foo.
+      DTMIterator list1 = iterRaw();
+      DTMIterator list2 = ((XNodeSet) obj2).iterRaw();
+      int node1;
+      java.util.Vector node2Strings = null;
+
+      while (DTM.NULL != (node1 = list1.nextNode()))
+      {
+        XMLString s1 = getStringFromNode(node1);
+
+        if (null == node2Strings)
+        {
+          int node2;
+
+          while (DTM.NULL != (node2 = list2.nextNode()))
+          {
+            XMLString s2 = getStringFromNode(node2);
+
+            if (comparator.compareStrings(s1, s2))
+            {
+              result = true;
+
+              break;
+            }
+
+            if (null == node2Strings)
+              node2Strings = new java.util.Vector();
+
+            node2Strings.addElement(s2);
+          }
+        }
+        else
+        {
+          int n = node2Strings.size();
+
+          for (int i = 0; i < n; i++)
+          {
+            if (comparator.compareStrings(s1, (XMLString)node2Strings.elementAt(i)))
+            {
+              result = true;
+
+              break;
+            }
+          }
+        }
+      }
+      list1.reset();
+      list2.reset();
+    }
+    else if (XObject.CLASS_BOOLEAN == type)
+    {
+
+      // From http://www.w3.org/TR/xpath: 
+      // If one object to be compared is a node-set and the other is a boolean, 
+      // then the comparison will be true if and only if the result of 
+      // performing the comparison on the boolean and on the result of 
+      // converting the node-set to a boolean using the boolean function 
+      // is true.
+      double num1 = bool() ? 1.0 : 0.0;
+      double num2 = obj2.num();
+
+      result = comparator.compareNumbers(num1, num2);
+    }
+    else if (XObject.CLASS_NUMBER == type)
+    {
+
+      // From http://www.w3.org/TR/xpath: 
+      // If one object to be compared is a node-set and the other is a number, 
+      // then the comparison will be true if and only if there is a 
+      // node in the node-set such that the result of performing the 
+      // comparison on the number to be compared and on the result of 
+      // converting the string-value of that node to a number using 
+      // the number function is true. 
+      DTMIterator list1 = iterRaw();
+      double num2 = obj2.num();
+      int node;
+
+      while (DTM.NULL != (node = list1.nextNode()))
+      {
+        double num1 = getNumberFromNode(node);
+
+        if (comparator.compareNumbers(num1, num2))
+        {
+          result = true;
+
+          break;
+        }
+      }
+      list1.reset();
+    }
+    else if (XObject.CLASS_RTREEFRAG == type)
+    {
+      XMLString s2 = obj2.xstr();
+      DTMIterator list1 = iterRaw();
+      int node;
+
+      while (DTM.NULL != (node = list1.nextNode()))
+      {
+        XMLString s1 = getStringFromNode(node);
+
+        if (comparator.compareStrings(s1, s2))
+        {
+          result = true;
+
+          break;
+        }
+      }
+      list1.reset();
+    }
+    else if (XObject.CLASS_STRING == type)
+    {
+
+      // From http://www.w3.org/TR/xpath: 
+      // If one object to be compared is a node-set and the other is a 
+      // string, then the comparison will be true if and only if there 
+      // is a node in the node-set such that the result of performing 
+      // the comparison on the string-value of the node and the other 
+      // string is true. 
+      XMLString s2 = obj2.xstr();
+      DTMIterator list1 = iterRaw();
+      int node;
+
+      while (DTM.NULL != (node = list1.nextNode()))
+      {
+        XMLString s1 = getStringFromNode(node);
+        if (comparator.compareStrings(s1, s2))
+        {
+          result = true;
+
+          break;
+        }
+      }
+      list1.reset();
+    }
+    else
+    {
+      result = comparator.compareNumbers(this.num(), obj2.num());
+    }
+
+    return result;
+  }
+
+  /**
+   * Tell if one object is less than the other.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean lessThan(XObject obj2) throws javax.xml.transform.TransformerException
+  {
+    return compare(obj2, S_LT);
+  }
+
+  /**
+   * Tell if one object is less than or equal to the other.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean lessThanOrEqual(XObject obj2) throws javax.xml.transform.TransformerException
+  {
+    return compare(obj2, S_LTE);
+  }
+
+  /**
+   * Tell if one object is less than the other.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean greaterThan(XObject obj2) throws javax.xml.transform.TransformerException
+  {
+    return compare(obj2, S_GT);
+  }
+
+  /**
+   * Tell if one object is less than the other.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean greaterThanOrEqual(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+    return compare(obj2, S_GTE);
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+    try
+    {
+      return compare(obj2, S_EQ);
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+  }
+
+  /**
+   * Tell if two objects are functionally not equal.
+   *
+   * @param obj2 object to compare this nodeset to
+   *
+   * @return see this.compare(...) 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean notEquals(XObject obj2) throws javax.xml.transform.TransformerException
+  {
+    return compare(obj2, S_NEQ);
+  }
+}
+
+/**
+ * compares nodes for various boolean operations.
+ */
+abstract class Comparator
+{
+
+  /**
+   * Compare two strings
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare 
+   *
+   * @return Whether the strings are equal or not
+   */
+  abstract boolean compareStrings(XMLString s1, XMLString s2);
+
+  /**
+   * Compare two numbers
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return Whether the numbers are equal or not
+   */
+  abstract boolean compareNumbers(double n1, double n2);
+}
+
+/**
+ * Compare strings or numbers for less than.
+ */
+class LessThanComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for less than.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare 
+   *
+   * @return True if s1 is less than s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return (s1.toDouble() < s2.toDouble());
+    // return s1.compareTo(s2) < 0;
+  }
+
+  /**
+   * Compare two numbers for less than.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is less than n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 < n2;
+  }
+}
+
+/**
+ * Compare strings or numbers for less than or equal.
+ */
+class LessThanOrEqualComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for less than or equal.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare
+   *
+   * @return true if s1 is less than or equal to s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return (s1.toDouble() <= s2.toDouble());
+    // return s1.compareTo(s2) <= 0;
+  }
+
+  /**
+   * Compare two numbers for less than or equal.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is less than or equal to n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 <= n2;
+  }
+}
+
+/**
+ * Compare strings or numbers for greater than.
+ */
+class GreaterThanComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for greater than.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare
+   *
+   * @return true if s1 is greater than s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return (s1.toDouble() > s2.toDouble());
+    // return s1.compareTo(s2) > 0;
+  }
+
+  /**
+   * Compare two numbers for greater than.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is greater than n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 > n2;
+  }
+}
+
+/**
+ * Compare strings or numbers for greater than or equal.
+ */
+class GreaterThanOrEqualComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for greater than or equal.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare
+   *
+   * @return true if s1 is greater than or equal to s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return (s1.toDouble() >= s2.toDouble());
+    // return s1.compareTo(s2) >= 0;
+  }
+
+  /**
+   * Compare two numbers for greater than or equal.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is greater than or equal to n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 >= n2;
+  }
+}
+
+/**
+ * Compare strings or numbers for equality.
+ */
+class EqualComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for equality.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare
+   *
+   * @return true if s1 is equal to s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return s1.equals(s2);
+  }
+
+  /**
+   * Compare two numbers for equality.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is equal to n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 == n2;
+  }
+}
+
+/**
+ * Compare strings or numbers for non-equality.
+ */
+class NotEqualComparator extends Comparator
+{
+
+  /**
+   * Compare two strings for non-equality.
+   *
+   *
+   * @param s1 First string to compare
+   * @param s2 Second String to compare
+   *
+   * @return true if s1 is not equal to s2
+   */
+  boolean compareStrings(XMLString s1, XMLString s2)
+  {
+    return !s1.equals(s2);
+  }
+
+  /**
+   * Compare two numbers for non-equality.
+   *
+   *
+   * @param n1 First number to compare
+   * @param n2 Second number to compare
+   *
+   * @return true if n1 is not equal to n2
+   */
+  boolean compareNumbers(double n1, double n2)
+  {
+    return n1 != n2;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/objects/XNodeSetForDOM.java b/src/main/java/org/apache/xpath/objects/XNodeSetForDOM.java
new file mode 100644
index 0000000..7075d3e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XNodeSetForDOM.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XNodeSetForDOM.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * This class overrides the XNodeSet#object() method to provide the original 
+ * Node object, NodeList object, or NodeIterator.
+ */
+public class XNodeSetForDOM extends XNodeSet
+{
+    static final long serialVersionUID = -8396190713754624640L;
+  Object m_origObj;
+
+  public XNodeSetForDOM(Node node, DTMManager dtmMgr)
+  {
+    m_dtmMgr = dtmMgr;
+    m_origObj = node;
+    int dtmHandle = dtmMgr.getDTMHandleFromNode(node);
+    setObject(new NodeSetDTM(dtmMgr));
+    ((NodeSetDTM) m_obj).addNode(dtmHandle);
+  }
+  
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val Value of the XNodeSet object
+   */
+  public XNodeSetForDOM(XNodeSet val)
+  {
+  	super(val);
+  	if(val instanceof XNodeSetForDOM)
+    	m_origObj = ((XNodeSetForDOM)val).m_origObj;
+  }
+  
+  public XNodeSetForDOM(NodeList nodeList, XPathContext xctxt)
+  {
+    m_dtmMgr = xctxt.getDTMManager();
+    m_origObj = nodeList;
+
+    // JKESS 20020514: Longer-term solution is to force
+    // folks to request length through an accessor, so we can defer this
+    // retrieval... but that requires an API change.
+    // m_obj=new org.apache.xpath.NodeSetDTM(nodeList, xctxt);
+    org.apache.xpath.NodeSetDTM nsdtm=new org.apache.xpath.NodeSetDTM(nodeList, xctxt);
+    m_last=nsdtm.getLength();
+    setObject(nsdtm);   
+  }
+
+  public XNodeSetForDOM(NodeIterator nodeIter, XPathContext xctxt)
+  {
+    m_dtmMgr = xctxt.getDTMManager();
+    m_origObj = nodeIter;
+
+    // JKESS 20020514: Longer-term solution is to force
+    // folks to request length through an accessor, so we can defer this
+    // retrieval... but that requires an API change.
+    // m_obj = new org.apache.xpath.NodeSetDTM(nodeIter, xctxt);
+    org.apache.xpath.NodeSetDTM nsdtm=new org.apache.xpath.NodeSetDTM(nodeIter, xctxt);
+    m_last=nsdtm.getLength();
+    setObject(nsdtm);   
+  }
+  
+  /**
+   * Return the original DOM object that the user passed in.  For use primarily
+   * by the extension mechanism.
+   *
+   * @return The object that this class wraps
+   */
+  public Object object()
+  {
+    return m_origObj;
+  }
+  
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeIterator nodeset() throws javax.xml.transform.TransformerException
+  {
+    return (m_origObj instanceof NodeIterator) 
+                   ? (NodeIterator)m_origObj : super.nodeset();      
+  }
+  
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeList nodelist() throws javax.xml.transform.TransformerException
+  {
+    return (m_origObj instanceof NodeList) 
+                   ? (NodeList)m_origObj : super.nodelist();      
+  }
+
+
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XNull.java b/src/main/java/org/apache/xpath/objects/XNull.java
new file mode 100644
index 0000000..1a5fa82
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XNull.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XNull.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+
+/**
+ * This class represents an XPath null object, and is capable of
+ * converting the null to other types, such as a string.
+ * @xsl.usage general
+ */
+public class XNull extends XNodeSet
+{
+    static final long serialVersionUID = -6841683711458983005L;
+
+  /**
+   * Create an XObject.
+   */
+  public XNull()
+  {
+    super();
+  }
+
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return type CLASS_NULL
+   */
+  public int getType()
+  {
+    return CLASS_NULL;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#CLASS_NULL"
+   */
+  public String getTypeString()
+  {
+    return "#CLASS_NULL";
+  }
+
+  /**
+   * Cast result object to a number.
+   * 
+   * @return 0.0
+   */
+
+  public double num()
+  {
+    return 0.0;
+  }
+
+  /**
+   * Cast result object to a boolean.
+   *
+   * @return false
+   */
+  public boolean bool()
+  {
+    return false;
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return empty string ""
+   */
+  public String str()
+  {
+    return "";
+  }
+
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @param support XPath context to use for the conversion
+   *
+   * @return The object as a result tree fragment.
+   */
+  public int rtf(XPathContext support)
+  {
+    // DTM frag = support.createDocumentFragment();
+    // %REVIEW%
+    return DTM.NULL;
+  }
+
+//  /**
+//   * Cast result object to a nodelist.
+//   *
+//   * @return null
+//   */
+//  public DTMIterator iter()
+//  {
+//    return null;
+//  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if the given object is of type CLASS_NULL
+   */
+  public boolean equals(XObject obj2)
+  {
+    return obj2.getType() == CLASS_NULL;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/objects/XNumber.java b/src/main/java/org/apache/xpath/objects/XNumber.java
new file mode 100644
index 0000000..b56fec4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XNumber.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XNumber.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * This class represents an XPath number, and is capable of
+ * converting the number to other types, such as a string.
+ * @xsl.usage general
+ */
+public class XNumber extends XObject
+{
+    static final long serialVersionUID = -2720400709619020193L;
+
+  /** Value of the XNumber object.
+   *  @serial         */
+  double m_val;
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param d Value of the object
+   */
+  public XNumber(double d)
+  {
+    super();
+
+    m_val = d;
+  }
+  
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param num Value of the object
+   */
+  public XNumber(Number num)
+  {
+
+    super();
+
+    m_val = num.doubleValue();
+    setObject(num);
+  }
+
+  /**
+   * Tell that this is a CLASS_NUMBER.
+   *
+   * @return node type CLASS_NUMBER 
+   */
+  public int getType()
+  {
+    return CLASS_NUMBER;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#NUMBER" 
+   */
+  public String getTypeString()
+  {
+    return "#NUMBER";
+  }
+
+  /**
+   * Cast result object to a number.
+   *
+   * @return the value of the XNumber object
+   */
+  public double num()
+  {
+    return m_val;
+  }
+  
+  /**
+   * Evaluate expression to a number.
+   *
+   * @return 0.0
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt) 
+    throws javax.xml.transform.TransformerException
+  {
+
+    return m_val;
+  }
+
+  /**
+   * Cast result object to a boolean.
+   *
+   * @return false if the value is NaN or equal to 0.0
+   */
+  public boolean bool()
+  {
+    return (Double.isNaN(m_val) || (m_val == 0.0)) ? false : true;
+  }
+
+//  /**
+//   * Cast result object to a string.
+//   *
+//   * @return "NaN" if the number is NaN, Infinity or -Infinity if
+//   * the number is infinite or the string value of the number.
+//   */
+//  private static final int PRECISION = 16;
+//  public String str()
+//  {
+//
+//    if (Double.isNaN(m_val))
+//    {
+//      return "NaN";
+//    }
+//    else if (Double.isInfinite(m_val))
+//    {
+//      if (m_val > 0)
+//        return "Infinity";
+//      else
+//        return "-Infinity";
+//    }
+//
+//    long longVal = (long)m_val;
+//    if ((double)longVal == m_val)
+//      return Long.toString(longVal);
+//
+//
+//    String s = Double.toString(m_val);
+//    int len = s.length();
+//
+//    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
+//    {
+//      return s.substring(0, len - 2);
+//    }
+//
+//    int exp = 0;
+//    int e = s.indexOf('E');
+//    if (e != -1)
+//    {
+//      exp = Integer.parseInt(s.substring(e + 1));
+//      s = s.substring(0,e);
+//      len = e;
+//    }
+//
+//    // Calculate Significant Digits:
+//    // look from start of string for first digit
+//    // look from end for last digit
+//    // significant digits = end - start + (0 or 1 depending on decimal location)
+//
+//    int decimalPos = -1;
+//    int start = (s.charAt(0) == '-') ? 1 : 0;
+//    findStart: for( ; start < len; start++ )
+//    {
+//      switch (s.charAt(start))
+//      {
+//      case '0':
+//        break;
+//      case '.':
+//        decimalPos = start;
+//        break;
+//      default:
+//        break findStart;
+//      }
+//    }
+//    int end = s.length() - 1;
+//    findEnd: for( ; end > start; end-- )
+//    {
+//      switch (s.charAt(end))
+//      {
+//      case '0':
+//        break;
+//      case '.':
+//        decimalPos = end;
+//        break;
+//      default:
+//        break findEnd;
+//      }
+//    }
+//
+//    int sigDig = end - start;
+//
+//    // clarify decimal location if it has not yet been found
+//    if (decimalPos == -1)
+//      decimalPos = s.indexOf('.');
+//
+//    // if decimal is not between start and end, add one to sigDig
+//    if (decimalPos < start || decimalPos > end)
+//      ++sigDig;
+//
+//    // reduce significant digits to PRECISION if necessary
+//    if (sigDig > PRECISION)
+//    {
+//      // re-scale BigDecimal in order to get significant digits = PRECISION
+//      BigDecimal num = new BigDecimal(s);
+//      int newScale = num.scale() - (sigDig - PRECISION);
+//      if (newScale < 0)
+//        newScale = 0;
+//      s = num.setScale(newScale, BigDecimal.ROUND_HALF_UP).toString();
+//
+//      // remove trailing '0's; keep track of decimalPos
+//      int truncatePoint = s.length();
+//      while (s.charAt(--truncatePoint) == '0')
+//        ;
+//
+//      if (s.charAt(truncatePoint) == '.')
+//      {
+//        decimalPos = truncatePoint;
+//      }
+//      else
+//      {
+//        decimalPos = s.indexOf('.');
+//        truncatePoint += 1;
+//      }
+//
+//      s = s.substring(0, truncatePoint);
+//      len = s.length();
+//    }
+//
+//    // Account for exponent by adding zeros as needed 
+//    // and moving the decimal place
+//
+//    if (exp == 0)
+//       return s;
+//
+//    start = 0;
+//    String sign;
+//    if (s.charAt(0) == '-')
+//    {
+//      sign = "-";
+//      start++;
+//    }
+//    else
+//      sign = "";
+//
+//    String wholePart = s.substring(start, decimalPos);
+//    String decimalPart = s.substring(decimalPos + 1);
+//
+//    // get the number of digits right of the decimal
+//    int decimalLen = decimalPart.length();
+//
+//    if (exp >= decimalLen)
+//      return sign + wholePart + decimalPart + zeros(exp - decimalLen);
+//
+//    if (exp > 0)
+//      return sign + wholePart + decimalPart.substring(0, exp) + "."
+//             + decimalPart.substring(exp);
+//
+//    return sign + "0." + zeros(-1 - exp) + wholePart + decimalPart;
+//  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return "NaN" if the number is NaN, Infinity or -Infinity if
+   * the number is infinite or the string value of the number.
+   */
+  public String str()
+  {
+
+    if (Double.isNaN(m_val))
+    {
+      return "NaN";
+    }
+    else if (Double.isInfinite(m_val))
+    {
+      if (m_val > 0)
+        return "Infinity";
+      else
+        return "-Infinity";
+    }
+
+    double num = m_val;
+    String s = Double.toString(num);
+    int len = s.length();
+
+    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
+    {
+      s = s.substring(0, len - 2);
+
+      if (s.equals("-0"))
+        return "0";
+
+      return s;
+    }
+
+    int e = s.indexOf('E');
+
+    if (e < 0)
+    {
+      if (s.charAt(len - 1) == '0')
+        return s.substring(0, len - 1);
+      else
+        return s;
+    }
+
+    int exp = Integer.parseInt(s.substring(e + 1));
+    String sign;
+
+    if (s.charAt(0) == '-')
+    {
+      sign = "-";
+      s = s.substring(1);
+
+      --e;
+    }
+    else
+      sign = "";
+
+    int nDigits = e - 2;
+
+    if (exp >= nDigits)
+      return sign + s.substring(0, 1) + s.substring(2, e)
+             + zeros(exp - nDigits);
+
+    // Eliminate trailing 0's - bugzilla 14241
+    while (s.charAt(e-1) == '0')
+      e--;
+         
+    if (exp > 0)
+      return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "."
+             + s.substring(2 + exp, e);
+
+    return sign + "0." + zeros(-1 - exp) + s.substring(0, 1)
+           + s.substring(2, e);
+  }
+
+
+  /**
+   * Return a string of '0' of the given length
+   *
+   *
+   * @param n Length of the string to be returned
+   *
+   * @return a string of '0' with the given length
+   */
+  static private String zeros(int n)
+  {
+    if (n < 1)
+      return "";
+
+    char[] buf = new char[n];
+
+    for (int i = 0; i < n; i++)
+    {
+      buf[i] = '0';
+    }
+
+    return new String(buf);
+  }
+
+  /**
+   * Return a java object that's closest to the representation
+   * that should be handed to an extension.
+   *
+   * @return The value of this XNumber as a Double object
+   */
+  public Object object()
+  {
+    if(null == m_obj)
+      setObject(new Double(m_val));
+    return m_obj;
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return true if the two objects are equal 
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.
+    int t = obj2.getType();
+    try
+    {
+	    if (t == XObject.CLASS_NODESET)
+	      return obj2.equals(this);
+	    else if(t == XObject.CLASS_BOOLEAN)
+	      return obj2.bool() == bool();
+		else
+	       return m_val == obj2.num();
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+  }
+  
+  /**
+   * Tell if this expression returns a stable number that will not change during 
+   * iterations within the expression.  This is used to determine if a proximity 
+   * position predicate can indicate that no more searching has to occur.
+   * 
+   *
+   * @return true if the expression represents a stable number.
+   */
+  public boolean isStableNumber()
+  {
+    return true;
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	visitor.visitNumberLiteral(owner, this);
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XObject.java b/src/main/java/org/apache/xpath/objects/XObject.java
new file mode 100644
index 0000000..85b2369
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XObject.java
@@ -0,0 +1,759 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XObject.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import java.io.Serializable;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.NodeSetDTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathException;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.res.XPATHErrorResources;
+
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * This class represents an XPath object, and is capable of
+ * converting the object to various types, such as a string.
+ * This class acts as the base class to other XPath type objects,
+ * such as XString, and provides polymorphic casting capabilities.
+ * @xsl.usage general
+ */
+public class XObject extends Expression implements Serializable, Cloneable
+{
+    static final long serialVersionUID = -821887098985662951L;
+
+  /**
+   * The java object which this object wraps.
+   *  @serial  
+   */
+  protected Object m_obj;  // This may be NULL!!!
+
+  /**
+   * Create an XObject.
+   */
+  public XObject(){}
+
+  /**
+   * Create an XObject.
+   *
+   * @param obj Can be any object, should be a specific type
+   * for derived classes, or null.
+   */
+  public XObject(Object obj)
+  {
+    setObject(obj);
+  }
+  
+  protected void setObject(Object obj) {
+      m_obj = obj;
+  }
+
+  /**
+   * For support of literal objects in xpaths.
+   *
+   * @param xctxt The XPath execution context.
+   *
+   * @return This object.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return this;
+  }
+
+  /**
+   * Specify if it's OK for detach to release the iterator for reuse.
+   * This function should be called with a value of false for objects that are 
+   * stored in variables.
+   * Calling this with a value of false on a XNodeSet will cause the nodeset 
+   * to be cached.
+   *
+   * @param allowRelease true if it is OK for detach to release this iterator
+   * for pooling.
+   */
+  public void allowDetachToRelease(boolean allowRelease){}
+
+  /**
+   * Detaches the <code>DTMIterator</code> from the set which it iterated
+   * over, releasing any computational resources and placing the iterator
+   * in the INVALID state. After <code>detach</code> has been invoked,
+   * calls to <code>nextNode</code> or <code>previousNode</code> will
+   * raise a runtime exception.
+   */
+  public void detach(){}
+
+  /**
+   * Forces the object to release it's resources.  This is more harsh than
+   * detach().
+   */
+  public void destruct()
+  {
+
+    if (null != m_obj)
+    {
+      allowDetachToRelease(true);
+      detach();
+
+      setObject(null);
+    }
+  }
+  
+  /**
+   * Reset for fresh reuse.
+   */
+  public void reset()
+  {
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+    xstr().dispatchCharactersEvents(ch);
+  }
+
+  /**
+   * Create the right XObject based on the type of the object passed.  This 
+   * function can not make an XObject that exposes DOM Nodes, NodeLists, and 
+   * NodeIterators to the XSLT stylesheet as node-sets.
+   *
+   * @param val The java object which this object will wrap.
+   *
+   * @return the right XObject based on the type of the object passed.
+   */
+  static public XObject create(Object val)
+  {
+    return XObjectFactory.create(val);
+  }
+  
+  /**
+   * Create the right XObject based on the type of the object passed.
+   * This function <emph>can</emph> make an XObject that exposes DOM Nodes, NodeLists, and 
+   * NodeIterators to the XSLT stylesheet as node-sets.
+   *
+   * @param val The java object which this object will wrap.
+   * @param xctxt The XPath context.
+   *
+   * @return the right XObject based on the type of the object passed.
+   */
+  static public XObject create(Object val, XPathContext xctxt)
+  {
+    return XObjectFactory.create(val, xctxt);
+  }
+
+  /** Constant for NULL object type */
+  public static final int CLASS_NULL = -1;
+
+  /** Constant for UNKNOWN object type */
+  public static final int CLASS_UNKNOWN = 0;
+
+  /** Constant for BOOLEAN  object type */
+  public static final int CLASS_BOOLEAN = 1;
+
+  /** Constant for NUMBER object type */
+  public static final int CLASS_NUMBER = 2;
+
+  /** Constant for STRING object type */
+  public static final int CLASS_STRING = 3;
+
+  /** Constant for NODESET object type */
+  public static final int CLASS_NODESET = 4;
+
+  /** Constant for RESULT TREE FRAGMENT object type */
+  public static final int CLASS_RTREEFRAG = 5;
+
+  /** Represents an unresolved variable type as an integer. */
+  public static final int CLASS_UNRESOLVEDVARIABLE = 600;
+
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return CLASS_UNKNOWN
+   */
+  public int getType()
+  {
+    return CLASS_UNKNOWN;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#UNKNOWN" + object class name
+   */
+  public String getTypeString()
+  {
+    return "#UNKNOWN (" + object().getClass().getName() + ")";
+  }
+
+  /**
+   * Cast result object to a number. Always issues an error.
+   *
+   * @return 0.0
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num() throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_NUMBER,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a number");
+
+    return 0.0;
+  }
+  
+  /**
+   * Cast result object to a number, but allow side effects, such as the 
+   * incrementing of an iterator.
+   *
+   * @return numeric value of the string conversion from the 
+   * next node in the NodeSetDTM, or NAN if no node was found
+   */
+  public double numWithSideEffects()  throws javax.xml.transform.TransformerException
+  {
+    return num();
+  }
+
+  /**
+   * Cast result object to a boolean. Always issues an error.
+   *
+   * @return false
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool() throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_NUMBER,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a number");
+
+    return false;
+  }
+  
+  /**
+   * Cast result object to a boolean, but allow side effects, such as the 
+   * incrementing of an iterator.
+   *
+   * @return True if there is a next node in the nodeset
+   */
+  public boolean boolWithSideEffects() throws javax.xml.transform.TransformerException
+  {
+    return bool();
+  }
+
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public XMLString xstr()
+  {
+    return XMLStringFactoryImpl.getFactory().newstr(str());
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The object as a string
+   */
+  public String str()
+  {
+    return (m_obj != null) ? m_obj.toString() : "";
+  }
+
+  /**
+   * Return the string representation of the object
+   *
+   *
+   * @return the string representation of the object
+   */
+  public String toString()
+  {
+    return str();
+  }
+
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @param support XPath context to use for the conversion
+   *
+   * @return the objec as a result tree fragment.
+   */
+  public int rtf(XPathContext support)
+  {
+
+    int result = rtf();
+
+    if (DTM.NULL == result)
+    {
+      DTM frag = support.createDocumentFragment();
+
+      // %OPT%
+      frag.appendTextChild(str());
+
+      result = frag.getDocument();
+    }
+
+    return result;
+  }
+  
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @param support XPath context to use for the conversion
+   *
+   * @return the objec as a result tree fragment.
+   */
+  public DocumentFragment rtree(XPathContext support)
+  {
+    DocumentFragment docFrag = null;
+    int result = rtf();
+
+    if (DTM.NULL == result)
+    {
+      DTM frag = support.createDocumentFragment();
+
+      // %OPT%
+      frag.appendTextChild(str());
+
+      docFrag = (DocumentFragment)frag.getNode(frag.getDocument());
+    }
+    else
+    {
+      DTM frag = support.getDTM(result);
+      docFrag = (DocumentFragment)frag.getNode(frag.getDocument());
+    }
+
+    return docFrag;
+  }
+  
+  
+  /**
+   * For functions to override.
+   *
+   * @return null
+   */
+  public DocumentFragment rtree()
+  {
+    return null;
+  }
+
+  /**
+   * For functions to override.
+   *
+   * @return null
+   */
+  public int rtf()
+  {
+    return DTM.NULL;
+  }
+
+  /**
+   * Return a java object that's closest to the representation
+   * that should be handed to an extension.
+   *
+   * @return The object that this class wraps
+   */
+  public Object object()
+  {
+    return m_obj;
+  }
+
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public DTMIterator iter() throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_NODELIST,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a NodeList!");
+
+    return null;
+  }
+  
+  /**
+   * Get a fresh copy of the object.  For use with variables.
+   *
+   * @return This object, unless overridden by subclass.
+   */
+  public XObject getFresh()
+  {
+    return this;
+  }
+
+  
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeIterator nodeset() throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_NODELIST,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a NodeList!");
+
+    return null;
+  }
+  
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return null
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeList nodelist() throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_NODELIST,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a NodeList!");
+
+    return null;
+  }
+
+
+  /**
+   * Cast result object to a nodelist. Always issues an error.
+   *
+   * @return The object as a NodeSetDTM.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public NodeSetDTM mutableNodeset()
+          throws javax.xml.transform.TransformerException
+  {
+
+    error(XPATHErrorResources.ER_CANT_CONVERT_TO_MUTABLENODELIST,
+          new Object[]{ getTypeString() });  //"Can not convert "+getTypeString()+" to a NodeSetDTM!");
+
+    return (NodeSetDTM) m_obj;
+  }
+
+  /**
+   * Cast object to type t.
+   *
+   * @param t Type of object to cast this to
+   * @param support XPath context to use for the conversion
+   *
+   * @return This object as the given type t
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public Object castToType(int t, XPathContext support)
+          throws javax.xml.transform.TransformerException
+  {
+
+    Object result;
+
+    switch (t)
+    {
+    case CLASS_STRING :
+      result = str();
+      break;
+    case CLASS_NUMBER :
+      result = new Double(num());
+      break;
+    case CLASS_NODESET :
+      result = iter();
+      break;
+    case CLASS_BOOLEAN :
+      result = new Boolean(bool());
+      break;
+    case CLASS_UNKNOWN :
+      result = m_obj;
+      break;
+
+    // %TBD%  What to do here?
+    //    case CLASS_RTREEFRAG :
+    //      result = rtree(support);
+    //      break;
+    default :
+      error(XPATHErrorResources.ER_CANT_CONVERT_TO_TYPE,
+            new Object[]{ getTypeString(),
+                          Integer.toString(t) });  //"Can not convert "+getTypeString()+" to a type#"+t);
+
+      result = null;
+    }
+
+    return result;
+  }
+
+  /**
+   * Tell if one object is less than the other.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is less than the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean lessThan(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.  Because the arguments 
+    // are backwards, we call the opposite comparison
+    // function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.greaterThan(this);
+
+    return this.num() < obj2.num();
+  }
+
+  /**
+   * Tell if one object is less than or equal to the other.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is less than or equal to the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean lessThanOrEqual(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.  Because the arguments 
+    // are backwards, we call the opposite comparison
+    // function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.greaterThanOrEqual(this);
+
+    return this.num() <= obj2.num();
+  }
+
+  /**
+   * Tell if one object is greater than the other.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is greater than the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean greaterThan(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.  Because the arguments 
+    // are backwards, we call the opposite comparison
+    // function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.lessThan(this);
+
+    return this.num() > obj2.num();
+  }
+
+  /**
+   * Tell if one object is greater than or equal to the other.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is greater than or equal to the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean greaterThanOrEqual(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.  Because the arguments 
+    // are backwards, we call the opposite comparison
+    // function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.lessThanOrEqual(this);
+
+    return this.num() >= obj2.num();
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is equal to the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.equals(this);
+
+    if (null != m_obj)
+    {
+      return m_obj.equals(obj2.m_obj);
+    }
+    else
+    {
+      return obj2.m_obj == null;
+    }
+  }
+
+  /**
+   * Tell if two objects are functionally not equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if this object is not equal to the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean notEquals(XObject obj2)
+          throws javax.xml.transform.TransformerException
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.
+    if (obj2.getType() == XObject.CLASS_NODESET)
+      return obj2.notEquals(this);
+
+    return !equals(obj2);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Error message to issue
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void error(String msg)
+          throws javax.xml.transform.TransformerException
+  {
+    error(msg, null);
+  }
+
+  /**
+   * Tell the user of an error, and probably throw an
+   * exception.
+   *
+   * @param msg Error message to issue
+   * @param args Arguments to use in the message
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected void error(String msg, Object[] args)
+          throws javax.xml.transform.TransformerException
+  {
+
+    String fmsg = XSLMessages.createXPATHMessage(msg, args);
+
+    // boolean shouldThrow = support.problem(m_support.XPATHPROCESSOR, 
+    //                                      m_support.ERROR,
+    //                                      null, 
+    //                                      null, fmsg, 0, 0);
+    // if(shouldThrow)
+    {
+      throw new XPathException(fmsg, this);
+    }
+  }
+  
+  
+  /**
+   * XObjects should not normally need to fix up variables.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+
+  /**
+   * Cast result object to a string.
+   *
+   *
+   * NEEDSDOC @param fsb
+   * @return The string this wraps or the empty string if null
+   */
+  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
+  {
+    fsb.append(str());
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	assertion(false, "callVisitors should not be called for this object!!!");
+  }
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	// If equals at the expression level calls deepEquals, I think we're 
+  	// still safe from infinite recursion since this object overrides 
+  	// equals.  I hope.
+  	if(!this.equals((XObject)expr))
+  		return false;
+  		
+  	return true;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XObjectFactory.java b/src/main/java/org/apache/xpath/objects/XObjectFactory.java
new file mode 100644
index 0000000..2a5176e
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XObjectFactory.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XObjectFactory.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisIterator;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.OneStepIterator;
+
+
+public class XObjectFactory
+{
+  
+  /**
+   * Create the right XObject based on the type of the object passed.  This 
+   * function can not make an XObject that exposes DOM Nodes, NodeLists, and 
+   * NodeIterators to the XSLT stylesheet as node-sets.
+   *
+   * @param val The java object which this object will wrap.
+   *
+   * @return the right XObject based on the type of the object passed.
+   */
+  static public XObject create(Object val)
+  {
+
+    XObject result;
+
+    if (val instanceof XObject)
+    {
+      result = (XObject) val;
+    }
+    else if (val instanceof String)
+    {
+      result = new XString((String) val);
+    }
+    else if (val instanceof Boolean)
+    {
+      result = new XBoolean((Boolean)val);
+    }
+    else if (val instanceof Double)
+    {
+      result = new XNumber(((Double) val));
+    }
+    else
+    {
+      result = new XObject(val);
+    }
+
+    return result;
+  }
+  
+  /**
+   * Create the right XObject based on the type of the object passed.
+   * This function <emph>can</emph> make an XObject that exposes DOM Nodes, NodeLists, and 
+   * NodeIterators to the XSLT stylesheet as node-sets.
+   *
+   * @param val The java object which this object will wrap.
+   * @param xctxt The XPath context.
+   *
+   * @return the right XObject based on the type of the object passed.
+   */
+  static public XObject create(Object val, XPathContext xctxt)
+  {
+
+    XObject result;
+
+    if (val instanceof XObject)
+    {
+      result = (XObject) val;
+    }
+    else if (val instanceof String)
+    {
+      result = new XString((String) val);
+    }
+    else if (val instanceof Boolean)
+    {
+      result = new XBoolean((Boolean)val);
+    }
+    else if (val instanceof Number)
+    {
+      result = new XNumber(((Number) val));
+    }
+    else if (val instanceof DTM)
+    {
+      DTM dtm = (DTM)val;
+      try
+      {
+        int dtmRoot = dtm.getDocument();
+        DTMAxisIterator iter = dtm.getAxisIterator(Axis.SELF);
+        iter.setStartNode(dtmRoot);
+        DTMIterator iterator = new OneStepIterator(iter, Axis.SELF);
+        iterator.setRoot(dtmRoot, xctxt);
+        result = new XNodeSet(iterator);
+      }
+      catch(Exception ex)
+      {
+        throw new org.apache.xml.utils.WrappedRuntimeException(ex);
+      }
+    }
+    else if (val instanceof DTMAxisIterator)
+    {
+      DTMAxisIterator iter = (DTMAxisIterator)val;
+      try
+      {
+        DTMIterator iterator = new OneStepIterator(iter, Axis.SELF);
+        iterator.setRoot(iter.getStartNode(), xctxt);
+        result = new XNodeSet(iterator);
+      }
+      catch(Exception ex)
+      {
+        throw new org.apache.xml.utils.WrappedRuntimeException(ex);
+      }
+    }
+    else if (val instanceof DTMIterator)
+    {
+      result = new XNodeSet((DTMIterator) val);
+    }
+    // This next three instanceofs are a little worrysome, since a NodeList 
+    // might also implement a Node!
+    else if (val instanceof org.w3c.dom.Node)
+    {
+      result = new XNodeSetForDOM((org.w3c.dom.Node)val, xctxt);
+    }
+    // This must come after org.w3c.dom.Node, since many Node implementations 
+    // also implement NodeList.
+    else if (val instanceof org.w3c.dom.NodeList)
+    {
+      result = new XNodeSetForDOM((org.w3c.dom.NodeList)val, xctxt);
+    }
+    else if (val instanceof org.w3c.dom.traversal.NodeIterator)
+    {
+      result = new XNodeSetForDOM((org.w3c.dom.traversal.NodeIterator)val, xctxt);
+    }
+    else
+    {
+      result = new XObject(val);
+    }
+
+    return result;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/objects/XRTreeFrag.java b/src/main/java/org/apache/xpath/objects/XRTreeFrag.java
new file mode 100644
index 0000000..048f8ab
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XRTreeFrag.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XRTreeFrag.java 469368 2006-10-31 04:41:36Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.RTFIterator;
+
+import org.w3c.dom.NodeList;
+
+/**
+ * This class represents an XPath result tree fragment object, and is capable of
+ * converting the RTF to other types, such as a string.
+ * @xsl.usage general
+ */
+public class XRTreeFrag extends XObject implements Cloneable
+{
+    static final long serialVersionUID = -3201553822254911567L;
+  private DTMXRTreeFrag m_DTMXRTreeFrag;
+  private int m_dtmRoot = DTM.NULL;
+  protected boolean m_allowRelease = false;
+
+
+  /**
+   * Create an XRTreeFrag Object.
+   *
+   */
+  public XRTreeFrag(int root, XPathContext xctxt, ExpressionNode parent)
+  {
+    super(null);
+    exprSetParent(parent);
+    initDTM(root, xctxt);    
+  }
+  
+  /**
+   * Create an XRTreeFrag Object.
+   *
+   */
+  public XRTreeFrag(int root, XPathContext xctxt)
+  {
+    super(null); 
+   initDTM(root, xctxt); 
+  }
+  
+  private final void initDTM(int root, XPathContext xctxt){
+    m_dtmRoot = root;
+    final DTM dtm = xctxt.getDTM(root);
+    if(dtm != null){
+      m_DTMXRTreeFrag = xctxt.getDTMXRTreeFrag(xctxt.getDTMIdentity(dtm));
+    }
+  }
+  
+  /**
+   * Return a java object that's closest to the representation
+   * that should be handed to an extension.
+   *
+   * @return The object that this class wraps
+   */
+  public Object object()
+  {
+    if (m_DTMXRTreeFrag.getXPathContext() != null)
+      return new org.apache.xml.dtm.ref.DTMNodeIterator((DTMIterator)(new org.apache.xpath.NodeSetDTM(m_dtmRoot, m_DTMXRTreeFrag.getXPathContext().getDTMManager())));
+    else
+      return super.object();
+  }
+  
+  /**
+   * Create an XRTreeFrag Object.
+   *
+   */
+  public XRTreeFrag(Expression expr)
+  {
+    super(expr);
+  }
+    
+  /**
+   * Specify if it's OK for detach to release the iterator for reuse.
+   * 
+   * @param allowRelease true if it is OK for detach to release this iterator 
+   * for pooling.
+   */
+  public void allowDetachToRelease(boolean allowRelease)
+  {
+    m_allowRelease = allowRelease;
+  }
+
+  /**
+   * Detaches the <code>DTMIterator</code> from the set which it iterated
+   * over, releasing any computational resources and placing the iterator
+   * in the INVALID state. After <code>detach</code> has been invoked,
+   * calls to <code>nextNode</code> or <code>previousNode</code> will
+   * raise a runtime exception.
+   * 
+   * In general, detach should only be called once on the object.
+   */
+  public void detach(){
+    if(m_allowRelease){
+    	m_DTMXRTreeFrag.destruct();
+      setObject(null);
+    }
+  }
+  
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return type CLASS_RTREEFRAG 
+   */
+  public int getType()
+  {
+    return CLASS_RTREEFRAG;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#RTREEFRAG"
+   */
+  public String getTypeString()
+  {
+    return "#RTREEFRAG";
+  }
+
+  /**
+   * Cast result object to a number.
+   *
+   * @return The result tree fragment as a number or NaN
+   */
+  public double num()
+    throws javax.xml.transform.TransformerException
+  {
+
+    XMLString s = xstr();
+
+    return s.toDouble();
+  }
+
+  /**
+   * Cast result object to a boolean.  This always returns true for a RTreeFrag
+   * because it is treated like a node-set with a single root node.
+   *
+   * @return true
+   */
+  public boolean bool()
+  {
+    return true;
+  }
+  
+  private XMLString m_xmlStr = null;
+  
+  /**
+   * Cast result object to an XMLString.
+   *
+   * @return The document fragment node data or the empty string. 
+   */
+  public XMLString xstr()
+  {
+    if(null == m_xmlStr)
+      m_xmlStr = m_DTMXRTreeFrag.getDTM().getStringValue(m_dtmRoot);
+    
+    return m_xmlStr;
+  }
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
+  {
+    XString xstring = (XString)xstr();
+    xstring.appendToFsb(fsb);
+  }
+
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The document fragment node data or the empty string. 
+   */
+  public String str()
+  {
+    String str = m_DTMXRTreeFrag.getDTM().getStringValue(m_dtmRoot).toString();
+
+    return (null == str) ? "" : str;
+  }
+
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @return The document fragment this wraps
+   */
+  public int rtf()
+  {
+    return m_dtmRoot;
+  }
+
+  /**
+   * Cast result object to a DTMIterator.
+   * dml - modified to return an RTFIterator for
+   * benefit of EXSLT object-type function in 
+   * {@code org.apache.xalan.lib.ExsltCommon}.
+   * @return The document fragment as a DTMIterator
+   */
+  public DTMIterator asNodeIterator()
+  {
+    return new RTFIterator(m_dtmRoot, m_DTMXRTreeFrag.getXPathContext().getDTMManager());
+  }
+
+  /**
+   * Cast result object to a nodelist. (special function).
+   *
+   * @return The document fragment as a nodelist
+   */
+  public NodeList convertToNodeset()
+  {
+
+    if (m_obj instanceof NodeList)
+      return (NodeList) m_obj;
+    else
+      return new org.apache.xml.dtm.ref.DTMNodeList(asNodeIterator());
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return True if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    try
+    {
+      if (XObject.CLASS_NODESET == obj2.getType())
+      {
+  
+        // In order to handle the 'all' semantics of 
+        // nodeset comparisons, we always call the 
+        // nodeset function.
+        return obj2.equals(this);
+      }
+      else if (XObject.CLASS_BOOLEAN == obj2.getType())
+      {
+        return bool() == obj2.bool();
+      }
+      else if (XObject.CLASS_NUMBER == obj2.getType())
+      {
+        return num() == obj2.num();
+      }
+      else if (XObject.CLASS_NODESET == obj2.getType())
+      {
+        return xstr().equals(obj2.xstr());
+      }
+      else if (XObject.CLASS_STRING == obj2.getType())
+      {
+        return xstr().equals(obj2.xstr());
+      }
+      else if (XObject.CLASS_RTREEFRAG == obj2.getType())
+      {
+  
+        // Probably not so good.  Think about this.
+        return xstr().equals(obj2.xstr());
+      }
+      else
+      {
+        return super.equals(obj2);
+      }
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+      throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XRTreeFragSelectWrapper.java b/src/main/java/org/apache/xpath/objects/XRTreeFragSelectWrapper.java
new file mode 100644
index 0000000..5449e71
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XRTreeFragSelectWrapper.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XRTreeFragSelectWrapper.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class makes an select statement act like an result tree fragment.
+ */
+public class XRTreeFragSelectWrapper extends XRTreeFrag implements Cloneable
+{
+    static final long serialVersionUID = -6526177905590461251L;
+  public XRTreeFragSelectWrapper(Expression expr)
+  {
+    super(expr);
+  }
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    ((Expression)m_obj).fixupVariables(vars, globalsSize);
+  }
+  
+  /**
+   * For support of literal objects in xpaths.
+   *
+   * @param xctxt The XPath execution context.
+   *
+   * @return the result of executing the select expression
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+	 XObject m_selected;
+     m_selected = ((Expression)m_obj).execute(xctxt);
+     m_selected.allowDetachToRelease(m_allowRelease);
+     if (m_selected.getType() == CLASS_STRING)
+       return m_selected;
+     else
+       return new XString(m_selected.str());
+  }
+    
+  /**
+   * Detaches the <code>DTMIterator</code> from the set which it iterated
+   * over, releasing any computational resources and placing the iterator
+   * in the INVALID state. After <code>detach</code> has been invoked,
+   * calls to <code>nextNode</code> or <code>previousNode</code> will
+   * raise a runtime exception.
+   * 
+   * In general, detach should only be called once on the object.
+   */
+  public void detach()
+  {
+	throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_DETACH_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"detach() not supported by XRTreeFragSelectWrapper!");
+  }
+  
+  /**
+   * Cast result object to a number.
+   *
+   * @return The result tree fragment as a number or NaN
+   */
+  public double num()
+    throws javax.xml.transform.TransformerException
+  {
+
+	throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NUM_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"num() not supported by XRTreeFragSelectWrapper!");
+  }
+
+  
+  /**
+   * Cast result object to an XMLString.
+   *
+   * @return The document fragment node data or the empty string. 
+   */
+  public XMLString xstr()
+  {
+	throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XSTR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"xstr() not supported by XRTreeFragSelectWrapper!");
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The document fragment node data or the empty string. 
+   */
+  public String str()
+  {
+	throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_STR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"str() not supported by XRTreeFragSelectWrapper!");
+  }
+  
+  /**
+   * Tell what kind of class this is.
+   *
+   * @return the string type
+   */
+  public int getType()
+  {
+    return CLASS_STRING;
+  }
+
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @return The document fragment this wraps
+   */
+  public int rtf()
+  {
+    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"rtf() not supported by XRTreeFragSelectWrapper!");
+  }
+
+  /**
+   * Cast result object to a DTMIterator.
+   *
+   * @return The document fragment as a DTMIterator
+   */
+  public DTMIterator asNodeIterator()
+  {
+    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER, null)); //"asNodeIterator() not supported by XRTreeFragSelectWrapper!");
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XString.java b/src/main/java/org/apache/xpath/objects/XString.java
new file mode 100644
index 0000000..963b832
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XString.java
@@ -0,0 +1,1122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XString.java 570108 2007-08-27 13:30:57Z zongaro $
+ */
+package org.apache.xpath.objects;
+
+import java.util.Locale;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.XMLCharacterRecognizer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+
+/**
+ * This class represents an XPath string object, and is capable of
+ * converting the string to other types, such as a number.
+ * @xsl.usage general
+ */
+public class XString extends XObject implements XMLString
+{
+    static final long serialVersionUID = 2020470518395094525L;
+
+  /** Empty string XString object */
+  public static final XString EMPTYSTRING = new XString("");
+
+  /**
+   * Construct a XString object.  This constructor exists for derived classes.
+   *
+   * @param val String object this will wrap.
+   */
+  protected XString(Object val)
+  {
+    super(val);
+  }
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val String object this will wrap.
+   */
+  public XString(String val)
+  {
+    super(val);
+  }
+
+  /**
+   * Tell that this is a CLASS_STRING.
+   *
+   * @return type CLASS_STRING
+   */
+  public int getType()
+  {
+    return CLASS_STRING;
+  }
+
+  /**
+   * Given a request type, return the equivalent string.
+   * For diagnostic purposes.
+   *
+   * @return type string "#STRING"
+   */
+  public String getTypeString()
+  {
+    return "#STRING";
+  }
+
+  /**
+   * Tell if this object contains a java String object.
+   *
+   * @return true if this XMLString can return a string without creating one.
+   */
+  public boolean hasString()
+  {
+    return true;
+  }
+
+  /**
+   * Cast result object to a number.
+   *
+   * @return 0.0 if this string is null, numeric value of this string
+   * or NaN
+   */
+  public double num()
+  {
+    return toDouble();
+  }
+
+  /**
+   * Convert a string to a double -- Allowed input is in fixed
+   * notation ddd.fff.
+   *
+   * @return A double value representation of the string, or return Double.NaN
+   * if the string can not be converted.
+   */
+  public double toDouble()
+  {
+    /* XMLCharacterRecognizer.isWhiteSpace(char c) methods treats the following 
+     * characters as white space characters.
+     * ht - horizontal tab, nl - newline , cr - carriage return and sp - space
+     * trim() methods by default also takes care of these white space characters
+     * So trim() method is used to remove leading and trailing white spaces.
+     */
+	XMLString s = trim();
+	double result = Double.NaN;
+	for (int i = 0; i < s.length(); i++)
+	{
+		char c = s.charAt(i);
+    if (c != '-' && c != '.' && ( c < 0X30 || c > 0x39)) {
+            // The character is not a '-' or a '.' or a digit
+            // then return NaN because something is wrong.
+			return result;
+        }
+	}
+	try
+	{
+		result = Double.parseDouble(s.toString());
+	} catch (NumberFormatException e){}
+
+	return result;
+}
+
+  /**
+   * Cast result object to a boolean.
+   *
+   * @return True if the length of this string object is greater
+   * than 0.
+   */
+  public boolean bool()
+  {
+    return str().length() > 0;
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public XMLString xstr()
+  {
+    return this;
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public String str()
+  {
+    return (null != m_obj) ? ((String) m_obj) : "";
+  }
+
+  /**
+   * Cast result object to a result tree fragment.
+   *
+   * @param support Xpath context to use for the conversion
+   *
+   * @return A document fragment with this string as a child node
+   */
+  public int rtf(XPathContext support)
+  {
+
+    DTM frag = support.createDocumentFragment();
+
+    frag.appendTextChild(str());
+
+    return frag.getDocument();
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+
+    String str = str();
+
+    ch.characters(str.toCharArray(), 0, str.length());
+  }
+
+  /**
+   * Directly call the
+   * comment method on the passed LexicalHandler for the
+   * string-value.
+   *
+   * @param lh A non-null reference to a LexicalHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
+          throws org.xml.sax.SAXException
+  {
+
+    String str = str();
+
+    lh.comment(str.toCharArray(), 0, str.length());
+  }
+
+  /**
+   * Returns the length of this string.
+   *
+   * @return  the length of the sequence of characters represented by this
+   *          object.
+   */
+  public int length()
+  {
+    return str().length();
+  }
+
+  /**
+   * Returns the character at the specified index. An index ranges
+   * from <code>0</code> to <code>length() - 1</code>. The first character
+   * of the sequence is at index <code>0</code>, the next at index
+   * <code>1</code>, and so on, as for array indexing.
+   *
+   * @param      index   the index of the character.
+   * @return     the character at the specified index of this string.
+   *             The first character is at index <code>0</code>.
+   * @exception  IndexOutOfBoundsException  if the <code>index</code>
+   *             argument is negative or not less than the length of this
+   *             string.
+   */
+  public char charAt(int index)
+  {
+    return str().charAt(index);
+  }
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
+  {
+    str().getChars(srcBegin, srcEnd, dst, dstBegin);
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return true if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    // In order to handle the 'all' semantics of 
+    // nodeset comparisons, we always call the 
+    // nodeset function.
+    int t = obj2.getType();
+    try
+    {
+	    if (XObject.CLASS_NODESET == t)
+	      return obj2.equals(this);
+	    // If at least one object to be compared is a boolean, then each object 
+	    // to be compared is converted to a boolean as if by applying the 
+	    // boolean function. 
+	    else if(XObject.CLASS_BOOLEAN == t)
+	    	return obj2.bool() == bool();
+	    // Otherwise, if at least one object to be compared is a number, then each object 
+	    // to be compared is converted to a number as if by applying the number function. 
+	    else if(XObject.CLASS_NUMBER == t)
+	    	return obj2.num() == num();
+    }
+    catch(javax.xml.transform.TransformerException te)
+    {
+    	throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    }
+
+    // Otherwise, both objects to be compared are converted to strings as 
+    // if by applying the string function. 
+    return xstr().equals(obj2.xstr());
+  }
+
+  /**
+   * Compares this string to the specified <code>String</code>.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   obj2   the object to compare this <code>String</code> against.
+   * @return  <code>true</code> if the <code>String</code>s are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(String obj2) {
+    return str().equals(obj2);
+  }
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param obj2   the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(XMLString obj2)
+  {
+    if (obj2 != null) {
+      if (!obj2.hasString()) {
+        return obj2.equals(str());
+      } else {
+        return str().equals(obj2.toString());
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   obj2       the object to compare this <code>String</code>
+   *                     against.
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(Object obj2)
+  {
+
+    if (null == obj2)
+      return false;
+
+      // In order to handle the 'all' semantics of 
+      // nodeset comparisons, we always call the 
+      // nodeset function.
+    else if (obj2 instanceof XNodeSet)
+      return obj2.equals(this);
+    else if(obj2 instanceof XNumber)
+    	return obj2.equals(this);
+    else
+      return str().equals(obj2.toString());
+  }
+
+  /**
+   * Compares this <code>String</code> to another <code>String</code>,
+   * ignoring case considerations.  Two strings are considered equal
+   * ignoring case if they are of the same length, and corresponding
+   * characters in the two strings are equal ignoring case.
+   *
+   * @param   anotherString   the <code>String</code> to compare this
+   *                          <code>String</code> against.
+   * @return  <code>true</code> if the argument is not <code>null</code>
+   *          and the <code>String</code>s are equal,
+   *          ignoring case; <code>false</code> otherwise.
+   * @see     #equals(Object)
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see java.lang.Character#toUpperCase(char)
+   */
+  public boolean equalsIgnoreCase(String anotherString)
+  {
+    return str().equalsIgnoreCase(anotherString);
+  }
+
+  /**
+   * Compares two strings lexicographically.
+   *
+   * @param   xstr   the <code>String</code> to be compared.
+   *
+   * @return  the value <code>0</code> if the argument string is equal to
+   *          this string; a value less than <code>0</code> if this string
+   *          is lexicographically less than the string argument; and a
+   *          value greater than <code>0</code> if this string is
+   *          lexicographically greater than the string argument.
+   * @exception java.lang.NullPointerException if <code>anotherString</code>
+   *          is <code>null</code>.
+   */
+  public int compareTo(XMLString xstr)
+  {
+
+    int len1 = this.length();
+    int len2 = xstr.length();
+    int n = Math.min(len1, len2);
+    int i = 0;
+    int j = 0;
+
+    while (n-- != 0)
+    {
+      char c1 = this.charAt(i);
+      char c2 = xstr.charAt(j);
+
+      if (c1 != c2)
+      {
+        return c1 - c2;
+      }
+
+      i++;
+      j++;
+    }
+
+    return len1 - len2;
+  }
+
+  /**
+   * Compares two strings lexicographically, ignoring case considerations.
+   * This method returns an integer whose sign is that of
+   * <code>this.toUpperCase().toLowerCase().compareTo(
+   * str.toUpperCase().toLowerCase())</code>.
+   * <p>
+   * Note that this method does <em>not</em> take locale into account,
+   * and will result in an unsatisfactory ordering for certain locales.
+   * The java.text package provides <em>collators</em> to allow
+   * locale-sensitive ordering.
+   *
+   * @param   str   the <code>String</code> to be compared.
+   * @return  a negative integer, zero, or a positive integer as the
+   *          the specified String is greater than, equal to, or less
+   *          than this String, ignoring case considerations.
+   * @see     java.text.Collator#compare(String, String)
+   * @since   1.2
+   */
+  public int compareToIgnoreCase(XMLString str)
+  {
+    // %REVIEW%  Like it says, @since 1.2. Doesn't exist in earlier
+    // versions of Java, hence we can't yet shell out to it. We can implement
+    // it as character-by-character compare, but doing so efficiently
+    // is likely to be (ahem) interesting.
+    //  
+    // However, since nobody is actually _using_ this method yet:
+    //    return str().compareToIgnoreCase(str.toString());
+    
+    throw new org.apache.xml.utils.WrappedRuntimeException(
+      new java.lang.NoSuchMethodException(
+        "Java 1.2 method, not yet implemented"));
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(String prefix, int toffset)
+  {
+    return str().startsWith(prefix, toffset);
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(String prefix)
+  {
+    return startsWith(prefix, 0);
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(XMLString prefix, int toffset)
+  {
+
+    int to = toffset;
+    int tlim = this.length();
+    int po = 0;
+    int pc = prefix.length();
+
+    // Note: toffset might be near -1>>>1.
+    if ((toffset < 0) || (toffset > tlim - pc))
+    {
+      return false;
+    }
+
+    while (--pc >= 0)
+    {
+      if (this.charAt(to) != prefix.charAt(po))
+      {
+        return false;
+      }
+
+      to++;
+      po++;
+    }
+
+    return true;
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(XMLString prefix)
+  {
+    return startsWith(prefix, 0);
+  }
+
+  /**
+   * Tests if this string ends with the specified suffix.
+   *
+   * @param   suffix   the suffix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a suffix of the character sequence represented by
+   *          this object; <code>false</code> otherwise. Note that the
+   *          result will be <code>true</code> if the argument is the
+   *          empty string or is equal to this <code>String</code> object
+   *          as determined by the {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>suffix</code> is
+   *          <code>null</code>.
+   */
+  public boolean endsWith(String suffix)
+  {
+    return str().endsWith(suffix);
+  }
+
+  /**
+   * Returns a hashcode for this string. The hashcode for a
+   * <code>String</code> object is computed as
+   * <blockquote><pre>
+   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+   * </pre></blockquote>
+   * using <code>int</code> arithmetic, where <code>s[i]</code> is the
+   * <i>i</i>th character of the string, <code>n</code> is the length of
+   * the string, and <code>^</code> indicates exponentiation.
+   * (The hash value of the empty string is zero.)
+   *
+   * @return  a hash code value for this object.
+   */
+  public int hashCode()
+  {
+    return str().hashCode();
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character. If a character with value <code>ch</code> occurs
+   * in the character sequence represented by this <code>String</code>
+   * object, then the index of the first such occurrence is returned --
+   * that is, the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is <code>true</code>. If no such character occurs in this string,
+   * then <code>-1</code> is returned.
+   *
+   * @param   ch   a character.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public int indexOf(int ch)
+  {
+    return str().indexOf(ch);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character, starting the search at the specified index.
+   * <p>
+   * If a character with value <code>ch</code> occurs in the character
+   * sequence represented by this <code>String</code> object at an index
+   * no smaller than <code>fromIndex</code>, then the index of the first
+   * such occurrence is returned--that is, the smallest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is true. If no such character occurs in this string at or after
+   * position <code>fromIndex</code>, then <code>-1</code> is returned.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If it
+   * is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object that is greater
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur.
+   */
+  public int indexOf(int ch, int fromIndex)
+  {
+    return str().indexOf(ch, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character. That is, the index returned is the largest
+   * value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is true.
+   * The String is searched backwards starting at the last character.
+   *
+   * @param   ch   a character.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public int lastIndexOf(int ch)
+  {
+    return str().lastIndexOf(ch);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of the
+   * specified character, searching backward starting at the specified
+   * index. That is, the index returned is the largest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * this.charAt(k) == ch) && (k <= fromIndex)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of <code>fromIndex</code>. If it is
+   *          greater than or equal to the length of this string, it has
+   *          the same effect as if it were equal to one less than the
+   *          length of this string: this entire string may be searched.
+   *          If it is negative, it has the same effect as if it were -1:
+   *          -1 is returned.
+   * @return  the index of the last occurrence of the character in the
+   *          character sequence represented by this object that is less
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur before that point.
+   */
+  public int lastIndexOf(int ch, int fromIndex)
+  {
+    return str().lastIndexOf(ch, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int indexOf(String str)
+  {
+    return str().indexOf(str);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring. The integer returned is the smallest value
+   * <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   *
+   * @param   str   any string.
+   * @return  if the string argument occurs as a substring within this
+   *          object, then the index of the first character of the first
+   *          such substring is returned; if it does not occur as a
+   *          substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int indexOf(XMLString str)
+  {
+    return str().indexOf(str.toString());
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified substring, starting at the specified index. The integer
+   * returned is the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.startsWith(str, <i>k</i>) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is <code>true</code>.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If
+   * it is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from.
+   * @return  If the string argument occurs as a substring within this
+   *          object at a starting index no smaller than
+   *          <code>fromIndex</code>, then the index of the first character
+   *          of the first such substring is returned. If it does not occur
+   *          as a substring starting at <code>fromIndex</code> or beyond,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>
+   */
+  public int indexOf(String str, int fromIndex)
+  {
+    return str().indexOf(str, fromIndex);
+  }
+
+  /**
+   * Returns the index within this string of the rightmost occurrence
+   * of the specified substring.  The rightmost empty string "" is
+   * considered to occur at the index value <code>this.length()</code>.
+   * The returned index is the largest value <i>k</i> such that
+   * <blockquote><pre>
+   * this.startsWith(str, k)
+   * </pre></blockquote>
+   * is true.
+   *
+   * @param   str   the substring to search for.
+   * @return  if the string argument occurs one or more times as a substring
+   *          within this object, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as
+   *          a substring, <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException  if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int lastIndexOf(String str)
+  {
+    return str().lastIndexOf(str);
+  }
+
+  /**
+   * Returns the index within this string of the last occurrence of
+   * the specified substring.
+   *
+   * @param   str         the substring to search for.
+   * @param   fromIndex   the index to start the search from. There is no
+   *          restriction on the value of fromIndex. If it is greater than
+   *          the length of this string, it has the same effect as if it
+   *          were equal to the length of this string: this entire string
+   *          may be searched. If it is negative, it has the same effect
+   *          as if it were -1: -1 is returned.
+   * @return  If the string argument occurs one or more times as a substring
+   *          within this object at a starting index no greater than
+   *          <code>fromIndex</code>, then the index of the first character of
+   *          the last such substring is returned. If it does not occur as a
+   *          substring starting at <code>fromIndex</code> or earlier,
+   *          <code>-1</code> is returned.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public int lastIndexOf(String str, int fromIndex)
+  {
+    return str().lastIndexOf(str, fromIndex);
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins with the character at the specified index and
+   * extends to the end of this string. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "unhappy".substring(2) returns "happy"
+   * "Harbison".substring(3) returns "bison"
+   * "emptiness".substring(9) returns "" (an empty string)
+   * </pre></blockquote>
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if
+   *             <code>beginIndex</code> is negative or larger than the
+   *             length of this <code>String</code> object.
+   */
+  public XMLString substring(int beginIndex)
+  {
+    return new XString(str().substring(beginIndex));
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins at the specified <code>beginIndex</code> and
+   * extends to the character at index <code>endIndex - 1</code>.
+   * Thus the length of the substring is <code>endIndex-beginIndex</code>.
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @param      endIndex     the ending index, exclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if the
+   *             <code>beginIndex</code> is negative, or
+   *             <code>endIndex</code> is larger than the length of
+   *             this <code>String</code> object, or
+   *             <code>beginIndex</code> is larger than
+   *             <code>endIndex</code>.
+   */
+  public XMLString substring(int beginIndex, int endIndex)
+  {
+    return new XString(str().substring(beginIndex, endIndex));
+  }
+
+  /**
+   * Concatenates the specified string to the end of this string.
+   *
+   * @param   str   the <code>String</code> that is concatenated to the end
+   *                of this <code>String</code>.
+   * @return  a string that represents the concatenation of this object's
+   *          characters followed by the string argument's characters.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public XMLString concat(String str)
+  {
+
+    // %REVIEW% Make an FSB here?
+    return new XString(str().concat(str));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the given <code>Locale</code>.
+   *
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public XMLString toLowerCase(Locale locale)
+  {
+    return new XString(str().toLowerCase(locale));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to lower
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   * <p>
+   *
+   * @return  the string, converted to lowercase.
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public XMLString toLowerCase()
+  {
+    return new XString(str().toLowerCase());
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the given locale.
+   * @param locale use the case transformation rules for this locale
+   * @return the String, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toLowerCase(Locale)
+   */
+  public XMLString toUpperCase(Locale locale)
+  {
+    return new XString(str().toUpperCase(locale));
+  }
+
+  /**
+   * Converts all of the characters in this <code>String</code> to upper
+   * case using the rules of the default locale, which is returned
+   * by <code>Locale.getDefault</code>.
+   *
+   * <p>
+   * If no character in this string has a different uppercase version,
+   * based on calling the <code>toUpperCase</code> method defined by
+   * <code>Character</code>, then the original string is returned.
+   * <p>
+   * Otherwise, this method creates a new <code>String</code> object
+   * representing a character sequence identical in length to the
+   * character sequence represented by this <code>String</code> object and
+   * with every character equal to the result of applying the method
+   * <code>Character.toUpperCase</code> to the corresponding character of
+   * this <code>String</code> object. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "Fahrvergn&uuml;gen".toUpperCase() returns "FAHRVERGN&Uuml;GEN"
+   * "Visit Ljubinje!".toUpperCase() returns "VISIT LJUBINJE!"
+   * </pre></blockquote>
+   *
+   * @return  the string, converted to uppercase.
+   * @see     java.lang.Character#toUpperCase(char)
+   * @see     java.lang.String#toUpperCase(Locale)
+   */
+  public XMLString toUpperCase()
+  {
+    return new XString(str().toUpperCase());
+  }
+
+  /**
+   * Removes white space from both ends of this string.
+   *
+   * @return  this string, with white space removed from the front and end.
+   */
+  public XMLString trim()
+  {
+    return new XString(str().trim());
+  }
+
+  /**
+   * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition
+   * of whitespace.  Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
+   * the definition of <CODE>S</CODE></A> for details.
+   * @param   ch      Character to check as XML whitespace.
+   * @return          =true if <var>ch</var> is XML whitespace; otherwise =false.
+   */
+  private static boolean isSpace(char ch)
+  {
+    return XMLCharacterRecognizer.isWhiteSpace(ch);  // Take the easy way out for now.
+  }
+
+  /**
+   * Conditionally trim all leading and trailing whitespace in the specified String.
+   * All strings of white space are
+   * replaced by a single space character (#x20), except spaces after punctuation which
+   * receive double spaces if doublePunctuationSpaces is true.
+   * This function may be useful to a formatter, but to get first class
+   * results, the formatter should probably do it's own white space handling
+   * based on the semantics of the formatting object.
+   *
+   * @param   trimHead    Trim leading whitespace?
+   * @param   trimTail    Trim trailing whitespace?
+   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
+   * @return              The trimmed string.
+   */
+  public XMLString fixWhiteSpace(boolean trimHead, boolean trimTail,
+                                 boolean doublePunctuationSpaces)
+  {
+
+    // %OPT% !!!!!!!
+    int len = this.length();
+    char[] buf = new char[len];
+
+    this.getChars(0, len, buf, 0);
+
+    boolean edit = false;
+    int s;
+
+    for (s = 0; s < len; s++)
+    {
+      if (isSpace(buf[s]))
+      {
+        break;
+      }
+    }
+
+    /* replace S to ' '. and ' '+ -> single ' '. */
+    int d = s;
+    boolean pres = false;
+
+    for (; s < len; s++)
+    {
+      char c = buf[s];
+
+      if (isSpace(c))
+      {
+        if (!pres)
+        {
+          if (' ' != c)
+          {
+            edit = true;
+          }
+
+          buf[d++] = ' ';
+
+          if (doublePunctuationSpaces && (s != 0))
+          {
+            char prevChar = buf[s - 1];
+
+            if (!((prevChar == '.') || (prevChar == '!')
+                  || (prevChar == '?')))
+            {
+              pres = true;
+            }
+          }
+          else
+          {
+            pres = true;
+          }
+        }
+        else
+        {
+          edit = true;
+          pres = true;
+        }
+      }
+      else
+      {
+        buf[d++] = c;
+        pres = false;
+      }
+    }
+
+    if (trimTail && 1 <= d && ' ' == buf[d - 1])
+    {
+      edit = true;
+
+      d--;
+    }
+
+    int start = 0;
+
+    if (trimHead && 0 < d && ' ' == buf[0])
+    {
+      edit = true;
+
+      start++;
+    }
+
+    XMLStringFactory xsf = XMLStringFactoryImpl.getFactory();
+
+    return edit ? xsf.newstr(new String(buf, start, d - start)) : this;
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	visitor.visitStringLiteral(owner, this);
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/objects/XStringForChars.java b/src/main/java/org/apache/xpath/objects/XStringForChars.java
new file mode 100644
index 0000000..fe18d23
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XStringForChars.java
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XStringForChars.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xpath.res.XPATHErrorResources;
+
+
+/**
+ * This class will wrap a FastStringBuffer and allow for
+ */
+public class XStringForChars extends XString
+{
+    static final long serialVersionUID = -2235248887220850467L;
+  /** The start position in the fsb. */
+  int m_start;
+  
+  /** The length of the string. */
+  int m_length;
+  
+  protected String m_strCache = null;
+  
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val FastStringBuffer object this will wrap, must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   */
+  public XStringForChars(char[] val, int start, int length)
+  {
+    super(val);
+    m_start = start;
+    m_length = length;
+    if(null == val)
+      throw new IllegalArgumentException(
+                          XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FASTSTRINGBUFFER_CANNOT_BE_NULL, null)); //"The FastStringBuffer argument can not be null!!");
+  }
+
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val String object this will wrap.
+   */
+  private XStringForChars(String val)
+  {
+    super(val);
+    throw new IllegalArgumentException(
+                      XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XSTRINGFORCHARS_CANNOT_TAKE_STRING, null)); //"XStringForChars can not take a string for an argument!");
+  }
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public FastStringBuffer fsb()
+  {
+    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FSB_NOT_SUPPORTED_XSTRINGFORCHARS, null)); //"fsb() not supported for XStringForChars!");
+  }
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
+  {
+    fsb.append((char[])m_obj, m_start, m_length);
+  }
+
+  
+  /**
+   * Tell if this object contains a java String object.
+   * 
+   * @return true if this XMLString can return a string without creating one.
+   */
+  public boolean hasString()
+  {
+    return (null != m_strCache);
+  }
+
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public String str()
+  {
+    if(null == m_strCache)
+      m_strCache = new String((char[])m_obj, m_start, m_length);
+    
+    return m_strCache;
+  }
+  
+
+  /**
+   * Since this object is incomplete without the length and the offset, we 
+   * have to convert to a string when this function is called.
+   *
+   * @return The java String representation of this object.
+   */
+  public Object object()
+  {
+    return str();
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+      throws org.xml.sax.SAXException
+  {
+    ch.characters((char[])m_obj, m_start, m_length);
+  }
+      
+  /**
+   * Directly call the
+   * comment method on the passed LexicalHandler for the
+   * string-value.
+   *
+   * @param lh A non-null reference to a LexicalHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
+      throws org.xml.sax.SAXException
+  {
+    lh.comment((char[])m_obj, m_start, m_length);
+  }
+  
+  /**
+   * Returns the length of this string.
+   *
+   * @return  the length of the sequence of characters represented by this
+   *          object.
+   */
+  public int length()
+  {
+    return m_length;
+  }
+
+  /**
+   * Returns the character at the specified index. An index ranges
+   * from <code>0</code> to <code>length() - 1</code>. The first character
+   * of the sequence is at index <code>0</code>, the next at index
+   * <code>1</code>, and so on, as for array indexing.
+   *
+   * @param      index   the index of the character.
+   * @return     the character at the specified index of this string.
+   *             The first character is at index <code>0</code>.
+   * @exception  IndexOutOfBoundsException  if the <code>index</code>
+   *             argument is negative or not less than the length of this
+   *             string.
+   */
+  public char charAt(int index)
+  {
+    return ((char[])m_obj)[index+m_start];
+  }
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
+  {
+    System.arraycopy((char[])m_obj, m_start+srcBegin, dst, dstBegin, srcEnd);
+  }
+  
+}
diff --git a/src/main/java/org/apache/xpath/objects/XStringForFSB.java b/src/main/java/org/apache/xpath/objects/XStringForFSB.java
new file mode 100644
index 0000000..083bfbc
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/XStringForFSB.java
@@ -0,0 +1,986 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XStringForFSB.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.objects;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.XMLCharacterRecognizer;
+import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * This class will wrap a FastStringBuffer and allow for
+ */
+public class XStringForFSB extends XString
+{
+    static final long serialVersionUID = -1533039186550674548L;
+
+  /** The start position in the fsb. */
+  int m_start;
+
+  /** The length of the string. */
+  int m_length;
+
+  /** If the str() function is called, the string will be cached here. */
+  protected String m_strCache = null;
+
+  /** cached hash code */
+  protected int m_hash = 0;
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val FastStringBuffer object this will wrap, must be non-null.
+   * @param start The start position in the array.
+   * @param length The number of characters to read from the array.
+   */
+  public XStringForFSB(FastStringBuffer val, int start, int length)
+  {
+
+    super(val);
+
+    m_start = start;
+    m_length = length;
+
+    if (null == val)
+      throw new IllegalArgumentException(
+        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FASTSTRINGBUFFER_CANNOT_BE_NULL, null));
+  }
+
+  /**
+   * Construct a XNodeSet object.
+   *
+   * @param val String object this will wrap.
+   */
+  private XStringForFSB(String val)
+  {
+
+    super(val);
+
+    throw new IllegalArgumentException(
+      XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FSB_CANNOT_TAKE_STRING, null)); // "XStringForFSB can not take a string for an argument!");
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public FastStringBuffer fsb()
+  {
+    return ((FastStringBuffer) m_obj);
+  }
+  
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
+  {
+    // %OPT% !!! FSB has to be updated to take partial fsb's for append.
+    fsb.append(str());
+  }
+
+  /**
+   * Tell if this object contains a java String object.
+   *
+   * @return true if this XMLString can return a string without creating one.
+   */
+  public boolean hasString()
+  {
+    return (null != m_strCache);
+  }
+
+//  /** NEEDSDOC Field strCount */
+//  public static int strCount = 0;
+//
+//  /** NEEDSDOC Field xtable */
+//  static java.util.Hashtable xtable = new java.util.Hashtable();
+
+  /**
+   * Since this object is incomplete without the length and the offset, we 
+   * have to convert to a string when this function is called.
+   *
+   * @return The java String representation of this object.
+   */
+  public Object object()
+  {
+    return str();
+  }
+
+  /**
+   * Cast result object to a string.
+   *
+   * @return The string this wraps or the empty string if null
+   */
+  public String str()
+  {
+
+    if (null == m_strCache)
+    {
+      m_strCache = fsb().getString(m_start, m_length);
+
+//      strCount++;
+//
+//      RuntimeException e = new RuntimeException("Bad!  Bad!");
+//      java.io.CharArrayWriter writer = new java.io.CharArrayWriter();
+//      java.io.PrintWriter pw = new java.io.PrintWriter(writer);
+//
+//      e.printStackTrace(pw);
+//
+//      String str = writer.toString();
+//
+//      str = str.substring(0, 600);
+//
+//      if (null == xtable.get(str))
+//      {
+//        xtable.put(str, str);
+//        System.out.println(str);
+//      }
+//      System.out.println("strCount: " + strCount);
+
+//      throw e;
+//      e.printStackTrace();
+      // System.exit(-1);
+    }
+
+    return m_strCache;
+  }
+
+  /**
+   * Directly call the
+   * characters method on the passed ContentHandler for the
+   * string-value. Multiple calls to the
+   * ContentHandler's characters methods may well occur for a single call to
+   * this method.
+   *
+   * @param ch A non-null reference to a ContentHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
+          throws org.xml.sax.SAXException
+  {
+    fsb().sendSAXcharacters(ch, m_start, m_length);
+  }
+
+  /**
+   * Directly call the
+   * comment method on the passed LexicalHandler for the
+   * string-value.
+   *
+   * @param lh A non-null reference to a LexicalHandler.
+   *
+   * @throws org.xml.sax.SAXException
+   */
+  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
+          throws org.xml.sax.SAXException
+  {
+    fsb().sendSAXComment(lh, m_start, m_length);
+  }
+
+  /**
+   * Returns the length of this string.
+   *
+   * @return  the length of the sequence of characters represented by this
+   *          object.
+   */
+  public int length()
+  {
+    return m_length;
+  }
+
+  /**
+   * Returns the character at the specified index. An index ranges
+   * from <code>0</code> to <code>length() - 1</code>. The first character
+   * of the sequence is at index <code>0</code>, the next at index
+   * <code>1</code>, and so on, as for array indexing.
+   *
+   * @param      index   the index of the character.
+   * @return     the character at the specified index of this string.
+   *             The first character is at index <code>0</code>.
+   * @exception  IndexOutOfBoundsException  if the <code>index</code>
+   *             argument is negative or not less than the length of this
+   *             string.
+   */
+  public char charAt(int index)
+  {
+    return fsb().charAt(m_start + index);
+  }
+
+  /**
+   * Copies characters from this string into the destination character
+   * array.
+   *
+   * @param      srcBegin   index of the first character in the string
+   *                        to copy.
+   * @param      srcEnd     index after the last character in the string
+   *                        to copy.
+   * @param      dst        the destination array.
+   * @param      dstBegin   the start offset in the destination array.
+   * @exception IndexOutOfBoundsException If any of the following
+   *            is true:
+   *            <ul><li><code>srcBegin</code> is negative.
+   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
+   *            <li><code>srcEnd</code> is greater than the length of this
+   *                string
+   *            <li><code>dstBegin</code> is negative
+   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
+   *                <code>dst.length</code></ul>
+   * @exception NullPointerException if <code>dst</code> is <code>null</code>
+   */
+  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
+  {
+
+    // %OPT% Need to call this on FSB when it is implemented.
+    // %UNTESTED% (I don't think anyone calls this yet?)
+    int n = srcEnd - srcBegin;
+
+    if (n > m_length)
+      n = m_length;
+
+    if (n > (dst.length - dstBegin))
+      n = (dst.length - dstBegin);
+
+    int end = srcBegin + m_start + n;
+    int d = dstBegin;
+    FastStringBuffer fsb = fsb();
+
+    for (int i = srcBegin + m_start; i < end; i++)
+    {
+      dst[d++] = fsb.charAt(i);
+    }
+  }
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   obj2       the object to compare this <code>String</code>
+   *                     against.
+   *
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(XMLString obj2)
+  {
+
+    if (this == obj2)
+    {
+      return true;
+    }
+
+    int n = m_length;
+
+    if (n == obj2.length())
+    {
+      FastStringBuffer fsb = fsb();
+      int i = m_start;
+      int j = 0;
+
+      while (n-- != 0)
+      {
+        if (fsb.charAt(i) != obj2.charAt(j))
+        {
+          return false;
+        }
+
+        i++;
+        j++;
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param obj2 Object to compare this to
+   *
+   * @return true if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(XObject obj2)
+  {
+
+    if (this == obj2)
+    {
+      return true;
+    }
+    if(obj2.getType() == XObject.CLASS_NUMBER)
+    	return obj2.equals(this);
+
+    String str = obj2.str();
+    int n = m_length;
+
+    if (n == str.length())
+    {
+      FastStringBuffer fsb = fsb();
+      int i = m_start;
+      int j = 0;
+
+      while (n-- != 0)
+      {
+        if (fsb.charAt(i) != str.charAt(j))
+        {
+          return false;
+        }
+
+        i++;
+        j++;
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Tell if two objects are functionally equal.
+   *
+   * @param anotherString Object to compare this to
+   *
+   * @return true if the two objects are equal
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean equals(String anotherString)
+  {
+
+    int n = m_length;
+
+    if (n == anotherString.length())
+    {
+      FastStringBuffer fsb = fsb();
+      int i = m_start;
+      int j = 0;
+
+      while (n-- != 0)
+      {
+        if (fsb.charAt(i) != anotherString.charAt(j))
+        {
+          return false;
+        }
+
+        i++;
+        j++;
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Compares this string to the specified object.
+   * The result is <code>true</code> if and only if the argument is not
+   * <code>null</code> and is a <code>String</code> object that represents
+   * the same sequence of characters as this object.
+   *
+   * @param   obj2       the object to compare this <code>String</code>
+   *                     against.
+   *
+   * @return  <code>true</code> if the <code>String </code>are equal;
+   *          <code>false</code> otherwise.
+   * @see     java.lang.String#compareTo(java.lang.String)
+   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
+   */
+  public boolean equals(Object obj2)
+  {
+
+    if (null == obj2)
+      return false;
+      
+    if(obj2 instanceof XNumber)
+    	return obj2.equals(this);
+
+      // In order to handle the 'all' semantics of 
+      // nodeset comparisons, we always call the 
+      // nodeset function.
+    else if (obj2 instanceof XNodeSet)
+      return obj2.equals(this);
+    else if (obj2 instanceof XStringForFSB)
+      return equals((XMLString) obj2);
+    else
+      return equals(obj2.toString());
+  }
+
+  /**
+   * Compares this <code>String</code> to another <code>String</code>,
+   * ignoring case considerations.  Two strings are considered equal
+   * ignoring case if they are of the same length, and corresponding
+   * characters in the two strings are equal ignoring case.
+   *
+   * @param   anotherString   the <code>String</code> to compare this
+   *                          <code>String</code> against.
+   * @return  <code>true</code> if the argument is not <code>null</code>
+   *          and the <code>String</code>s are equal,
+   *          ignoring case; <code>false</code> otherwise.
+   * @see     #equals(Object)
+   * @see     java.lang.Character#toLowerCase(char)
+   * @see java.lang.Character#toUpperCase(char)
+   */
+  public boolean equalsIgnoreCase(String anotherString)
+  {
+    return (m_length == anotherString.length())
+           ? str().equalsIgnoreCase(anotherString) : false;
+  }
+
+  /**
+   * Compares two strings lexicographically.
+   *
+   * @param   xstr   the <code>String</code> to be compared.
+   *
+   * @return  the value <code>0</code> if the argument string is equal to
+   *          this string; a value less than <code>0</code> if this string
+   *          is lexicographically less than the string argument; and a
+   *          value greater than <code>0</code> if this string is
+   *          lexicographically greater than the string argument.
+   * @exception java.lang.NullPointerException if <code>anotherString</code>
+   *          is <code>null</code>.
+   */
+  public int compareTo(XMLString xstr)
+  {
+
+    int len1 = m_length;
+    int len2 = xstr.length();
+    int n = Math.min(len1, len2);
+    FastStringBuffer fsb = fsb();
+    int i = m_start;
+    int j = 0;
+
+    while (n-- != 0)
+    {
+      char c1 = fsb.charAt(i);
+      char c2 = xstr.charAt(j);
+
+      if (c1 != c2)
+      {
+        return c1 - c2;
+      }
+
+      i++;
+      j++;
+    }
+
+    return len1 - len2;
+  }
+
+  /**
+   * Compares two strings lexicographically, ignoring case considerations.
+   * This method returns an integer whose sign is that of
+   * <code>this.toUpperCase().toLowerCase().compareTo(
+   * str.toUpperCase().toLowerCase())</code>.
+   * <p>
+   * Note that this method does <em>not</em> take locale into account,
+   * and will result in an unsatisfactory ordering for certain locales.
+   * The java.text package provides <em>collators</em> to allow
+   * locale-sensitive ordering.
+   *
+   * @param   xstr   the <code>String</code> to be compared.
+   *
+   * @return  a negative integer, zero, or a positive integer as the
+   *          the specified String is greater than, equal to, or less
+   *          than this String, ignoring case considerations.
+   * @see     java.text.Collator#compare(String, String)
+   * @since   1.2
+   */
+  public int compareToIgnoreCase(XMLString xstr)
+  {
+
+    int len1 = m_length;
+    int len2 = xstr.length();
+    int n = Math.min(len1, len2);
+    FastStringBuffer fsb = fsb();
+    int i = m_start;
+    int j = 0;
+
+    while (n-- != 0)
+    {
+      char c1 = Character.toLowerCase(fsb.charAt(i));
+      char c2 = Character.toLowerCase(xstr.charAt(j));
+
+      if (c1 != c2)
+      {
+        return c1 - c2;
+      }
+
+      i++;
+      j++;
+    }
+
+    return len1 - len2;
+  }
+
+  /**
+   * Returns a hashcode for this string. The hashcode for a
+   * <code>String</code> object is computed as
+   * <blockquote><pre>
+   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+   * </pre></blockquote>
+   * using <code>int</code> arithmetic, where <code>s[i]</code> is the
+   * <i>i</i>th character of the string, <code>n</code> is the length of
+   * the string, and <code>^</code> indicates exponentiation.
+   * (The hash value of the empty string is zero.)
+   *
+   * @return  a hash code value for this object.
+   */
+  public int hashCode()
+  {
+    // Commenting this out because in JDK1.1.8 and VJ++
+    // we don't match XMLStrings. Defaulting to the super
+    // causes us to create a string, but at this point
+    // this only seems to get called in key processing.
+    // Maybe we can live with it?
+    
+/*
+    int h = m_hash;
+
+    if (h == 0)
+    {
+      int off = m_start;
+      int len = m_length;
+      FastStringBuffer fsb = fsb();
+
+      for (int i = 0; i < len; i++)
+      {
+        h = 31 * h + fsb.charAt(off);
+
+        off++;
+      }
+
+      m_hash = h;
+    }
+    */
+
+    return super.hashCode(); // h;
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix beginning
+   * a specified index.
+   *
+   * @param   prefix    the prefix.
+   * @param   toffset   where to begin looking in the string.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the substring of this object starting
+   *          at index <code>toffset</code>; <code>false</code> otherwise.
+   *          The result is <code>false</code> if <code>toffset</code> is
+   *          negative or greater than the length of this
+   *          <code>String</code> object; otherwise the result is the same
+   *          as the result of the expression
+   *          <pre>
+   *          this.subString(toffset).startsWith(prefix)
+   *          </pre>
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   */
+  public boolean startsWith(XMLString prefix, int toffset)
+  {
+
+    FastStringBuffer fsb = fsb();
+    int to = m_start + toffset;
+    int tlim = m_start + m_length;
+    int po = 0;
+    int pc = prefix.length();
+
+    // Note: toffset might be near -1>>>1.
+    if ((toffset < 0) || (toffset > m_length - pc))
+    {
+      return false;
+    }
+
+    while (--pc >= 0)
+    {
+      if (fsb.charAt(to) != prefix.charAt(po))
+      {
+        return false;
+      }
+
+      to++;
+      po++;
+    }
+
+    return true;
+  }
+
+  /**
+   * Tests if this string starts with the specified prefix.
+   *
+   * @param   prefix   the prefix.
+   * @return  <code>true</code> if the character sequence represented by the
+   *          argument is a prefix of the character sequence represented by
+   *          this string; <code>false</code> otherwise.
+   *          Note also that <code>true</code> will be returned if the
+   *          argument is an empty string or is equal to this
+   *          <code>String</code> object as determined by the
+   *          {@link #equals(Object)} method.
+   * @exception java.lang.NullPointerException if <code>prefix</code> is
+   *          <code>null</code>.
+   * @since   JDK1. 0
+   */
+  public boolean startsWith(XMLString prefix)
+  {
+    return startsWith(prefix, 0);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character. If a character with value <code>ch</code> occurs
+   * in the character sequence represented by this <code>String</code>
+   * object, then the index of the first such occurrence is returned --
+   * that is, the smallest value <i>k</i> such that:
+   * <blockquote><pre>
+   * this.charAt(<i>k</i>) == ch
+   * </pre></blockquote>
+   * is <code>true</code>. If no such character occurs in this string,
+   * then <code>-1</code> is returned.
+   *
+   * @param   ch   a character.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object, or
+   *          <code>-1</code> if the character does not occur.
+   */
+  public int indexOf(int ch)
+  {
+    return indexOf(ch, 0);
+  }
+
+  /**
+   * Returns the index within this string of the first occurrence of the
+   * specified character, starting the search at the specified index.
+   * <p>
+   * If a character with value <code>ch</code> occurs in the character
+   * sequence represented by this <code>String</code> object at an index
+   * no smaller than <code>fromIndex</code>, then the index of the first
+   * such occurrence is returned--that is, the smallest value <i>k</i>
+   * such that:
+   * <blockquote><pre>
+   * (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
+   * </pre></blockquote>
+   * is true. If no such character occurs in this string at or after
+   * position <code>fromIndex</code>, then <code>-1</code> is returned.
+   * <p>
+   * There is no restriction on the value of <code>fromIndex</code>. If it
+   * is negative, it has the same effect as if it were zero: this entire
+   * string may be searched. If it is greater than the length of this
+   * string, it has the same effect as if it were equal to the length of
+   * this string: <code>-1</code> is returned.
+   *
+   * @param   ch          a character.
+   * @param   fromIndex   the index to start the search from.
+   * @return  the index of the first occurrence of the character in the
+   *          character sequence represented by this object that is greater
+   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
+   *          if the character does not occur.
+   */
+  public int indexOf(int ch, int fromIndex)
+  {
+
+    int max = m_start + m_length;
+    FastStringBuffer fsb = fsb();
+
+    if (fromIndex < 0)
+    {
+      fromIndex = 0;
+    }
+    else if (fromIndex >= m_length)
+    {
+
+      // Note: fromIndex might be near -1>>>1.
+      return -1;
+    }
+
+    for (int i = m_start + fromIndex; i < max; i++)
+    {
+      if (fsb.charAt(i) == ch)
+      {
+        return i - m_start;
+      }
+    }
+
+    return -1;
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins with the character at the specified index and
+   * extends to the end of this string. <p>
+   * Examples:
+   * <blockquote><pre>
+   * "unhappy".substring(2) returns "happy"
+   * "Harbison".substring(3) returns "bison"
+   * "emptiness".substring(9) returns "" (an empty string)
+   * </pre></blockquote>
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if
+   *             <code>beginIndex</code> is negative or larger than the
+   *             length of this <code>String</code> object.
+   */
+  public XMLString substring(int beginIndex)
+  {
+
+    int len = m_length - beginIndex;
+
+    if (len <= 0)
+      return XString.EMPTYSTRING;
+    else
+    {
+      int start = m_start + beginIndex;
+
+      return new XStringForFSB(fsb(), start, len);
+    }
+  }
+
+  /**
+   * Returns a new string that is a substring of this string. The
+   * substring begins at the specified <code>beginIndex</code> and
+   * extends to the character at index <code>endIndex - 1</code>.
+   * Thus the length of the substring is <code>endIndex-beginIndex</code>.
+   *
+   * @param      beginIndex   the beginning index, inclusive.
+   * @param      endIndex     the ending index, exclusive.
+   * @return     the specified substring.
+   * @exception  IndexOutOfBoundsException  if the
+   *             <code>beginIndex</code> is negative, or
+   *             <code>endIndex</code> is larger than the length of
+   *             this <code>String</code> object, or
+   *             <code>beginIndex</code> is larger than
+   *             <code>endIndex</code>.
+   */
+  public XMLString substring(int beginIndex, int endIndex)
+  {
+
+    int len = endIndex - beginIndex;
+
+    if (len > m_length)
+      len = m_length;
+
+    if (len <= 0)
+      return XString.EMPTYSTRING;
+    else
+    {
+      int start = m_start + beginIndex;
+
+      return new XStringForFSB(fsb(), start, len);
+    }
+  }
+
+  /**
+   * Concatenates the specified string to the end of this string.
+   *
+   * @param   str   the <code>String</code> that is concatenated to the end
+   *                of this <code>String</code>.
+   * @return  a string that represents the concatenation of this object's
+   *          characters followed by the string argument's characters.
+   * @exception java.lang.NullPointerException if <code>str</code> is
+   *          <code>null</code>.
+   */
+  public XMLString concat(String str)
+  {
+
+    // %OPT% Make an FSB here?
+    return new XString(str().concat(str));
+  }
+
+  /**
+   * Removes white space from both ends of this string.
+   *
+   * @return  this string, with white space removed from the front and end.
+   */
+  public XMLString trim()
+  {
+    return fixWhiteSpace(true, true, false);
+  }
+
+  /**
+   * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition
+   * of whitespace.  Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
+   * the definition of <CODE>S</CODE></A> for details.
+   * @param   ch      Character to check as XML whitespace.
+   * @return          =true if <var>ch</var> is XML whitespace; otherwise =false.
+   */
+  private static boolean isSpace(char ch)
+  {
+    return XMLCharacterRecognizer.isWhiteSpace(ch);  // Take the easy way out for now.
+  }
+
+  /**
+   * Conditionally trim all leading and trailing whitespace in the specified String.
+   * All strings of white space are
+   * replaced by a single space character (#x20), except spaces after punctuation which
+   * receive double spaces if doublePunctuationSpaces is true.
+   * This function may be useful to a formatter, but to get first class
+   * results, the formatter should probably do it's own white space handling
+   * based on the semantics of the formatting object.
+   *
+   * @param   trimHead    Trim leading whitespace?
+   * @param   trimTail    Trim trailing whitespace?
+   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
+   * @return              The trimmed string.
+   */
+  public XMLString fixWhiteSpace(boolean trimHead, boolean trimTail,
+                                 boolean doublePunctuationSpaces)
+  {
+
+    int end = m_length + m_start;
+    char[] buf = new char[m_length];
+    FastStringBuffer fsb = fsb();
+    boolean edit = false;
+
+    /* replace S to ' '. and ' '+ -> single ' '. */
+    int d = 0;
+    boolean pres = false;
+
+    for (int s = m_start; s < end; s++)
+    {
+      char c = fsb.charAt(s);
+
+      if (isSpace(c))
+      {
+        if (!pres)
+        {
+          if (' ' != c)
+          {
+            edit = true;
+          }
+
+          buf[d++] = ' ';
+
+          if (doublePunctuationSpaces && (d != 0))
+          {
+            char prevChar = buf[d - 1];
+
+            if (!((prevChar == '.') || (prevChar == '!')
+                  || (prevChar == '?')))
+            {
+              pres = true;
+            }
+          }
+          else
+          {
+            pres = true;
+          }
+        }
+        else
+        {
+          edit = true;
+          pres = true;
+        }
+      }
+      else
+      {
+        buf[d++] = c;
+        pres = false;
+      }
+    }
+
+    if (trimTail && 1 <= d && ' ' == buf[d - 1])
+    {
+      edit = true;
+
+      d--;
+    }
+
+    int start = 0;
+
+    if (trimHead && 0 < d && ' ' == buf[0])
+    {
+      edit = true;
+
+      start++;
+    }
+
+    XMLStringFactory xsf = XMLStringFactoryImpl.getFactory();
+
+    return edit ? xsf.newstr(buf, start, d - start) : this;
+  }
+
+  /**
+   * Convert a string to a double -- Allowed input is in fixed
+   * notation ddd.fff.
+   *
+   * %OPT% CHECK PERFORMANCE against generating a Java String and
+   * converting it to double. The advantage of running in native
+   * machine code -- perhaps even microcode, on some systems -- may
+   * more than make up for the cost of allocating and discarding the
+   * additional object. We need to benchmark this. 
+   *
+   * %OPT% More importantly, we need to decide whether we _care_ about
+   * the performance of this operation. Does XString.toDouble constitute
+   * any measurable percentage of our typical runtime? I suspect not!
+   *
+   * @return A double value representation of the string, or return Double.NaN 
+   * if the string can not be converted.  */
+  public double toDouble()
+  {
+    if(m_length == 0)
+      return Double.NaN;
+    int i;
+    char c;
+    String valueString = fsb().getString(m_start,m_length);
+    
+    // The following are permitted in the Double.valueOf, but not by the XPath spec:
+    // - a plus sign
+    // - The use of e or E to indicate exponents
+    // - trailing f, F, d, or D
+    // See function comments; not sure if this is slower than actually doing the
+    // conversion ourselves (as was before).
+    
+    for (i=0;i<m_length;i++)
+      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
+        break;
+    if (i == m_length) return Double.NaN;
+    if (valueString.charAt(i) == '-')
+      i++;
+    for (;i<m_length;i++) {
+      c = valueString.charAt(i);
+      if (c != '.' && (c < '0' || c > '9'))
+        break;
+    }   	    	
+    for (;i<m_length;i++)
+      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
+        break;
+    if (i != m_length)
+      return Double.NaN;
+    	
+    try {
+      return new Double(valueString).doubleValue();
+    } catch (NumberFormatException nfe) {
+      // This should catch double periods, empty strings.
+      return Double.NaN;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/xpath/objects/package.html b/src/main/java/org/apache/xpath/objects/package.html
new file mode 100644
index 0000000..d596ba3
--- /dev/null
+++ b/src/main/java/org/apache/xpath/objects/package.html
@@ -0,0 +1,27 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath objects Package.</title>
+  <body>
+    <p>Implementation of XPath polymorphic type objects -- this package will grow 
+    as XPath objects are expanded to support XML Schema data types.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/operations/And.java b/src/main/java/org/apache/xpath/operations/And.java
new file mode 100644
index 0000000..b7f3eab
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/And.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: And.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'and' operation expression executer.
+ */
+public class And extends Operation
+{
+    static final long serialVersionUID = 392330077126534022L;
+
+  /**
+   * AND two expressions and return the boolean result. Override
+   * superclass method for optimization purposes.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return {@link org.apache.xpath.objects.XBoolean#S_TRUE} or 
+   * {@link org.apache.xpath.objects.XBoolean#S_FALSE}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    XObject expr1 = m_left.execute(xctxt);
+
+    if (expr1.bool())
+    {
+      XObject expr2 = m_right.execute(xctxt);
+
+      return expr2.bool() ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+    }
+    else
+      return XBoolean.S_FALSE;
+  }
+  
+  /**
+   * Evaluate this operation directly to a boolean.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a boolean.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return (m_left.bool(xctxt) && m_right.bool(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Bool.java b/src/main/java/org/apache/xpath/operations/Bool.java
new file mode 100644
index 0000000..2dd9c6a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Bool.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Bool.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'boolean()' operation expression executer.
+ */
+public class Bool extends UnaryOperation
+{
+    static final long serialVersionUID = 44705375321914635L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject right) throws javax.xml.transform.TransformerException
+  {
+
+    if (XObject.CLASS_BOOLEAN == right.getType())
+      return right;
+    else
+      return right.bool() ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+  
+  /**
+   * Evaluate this operation directly to a boolean.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a boolean.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return m_right.bool(xctxt);
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Div.java b/src/main/java/org/apache/xpath/operations/Div.java
new file mode 100644
index 0000000..f8b74e1
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Div.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Div.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'div' operation expression executer.
+ */
+public class Div extends Operation
+{
+    static final long serialVersionUID = 6220756595959798135L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(left.num() / right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return (m_left.num(xctxt) / m_right.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Equals.java b/src/main/java/org/apache/xpath/operations/Equals.java
new file mode 100644
index 0000000..8be4186
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Equals.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Equals.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '=' operation expression executer.
+ */
+public class Equals extends Operation
+{
+    static final long serialVersionUID = -2658315633903426134L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return left.equals(right) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+  
+  /**
+   * Execute a binary operation by calling execute on each of the operands,
+   * and then calling the operate method on the derived class.
+   *
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The XObject result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    XObject left = m_left.execute(xctxt, true);
+    XObject right = m_right.execute(xctxt, true);
+
+    boolean result = left.equals(right) ? true : false;
+	left.detach();
+	right.detach();
+    return result;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Gt.java b/src/main/java/org/apache/xpath/operations/Gt.java
new file mode 100644
index 0000000..3190c83
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Gt.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Gt.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '>' operation expression executer.
+ */
+public class Gt extends Operation
+{
+    static final long serialVersionUID = 8927078751014375950L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return left.greaterThan(right) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Gte.java b/src/main/java/org/apache/xpath/operations/Gte.java
new file mode 100644
index 0000000..fd49c4a
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Gte.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Gte.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '>=' operation expression executer.
+ */
+public class Gte extends Operation
+{
+    static final long serialVersionUID = 9142945909906680220L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return left.greaterThanOrEqual(right)
+           ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Lt.java b/src/main/java/org/apache/xpath/operations/Lt.java
new file mode 100644
index 0000000..e023fcb
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Lt.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Lt.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '<' operation expression executer.
+ */
+public class Lt extends Operation
+{
+    static final long serialVersionUID = 3388420509289359422L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return left.lessThan(right) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Lte.java b/src/main/java/org/apache/xpath/operations/Lte.java
new file mode 100644
index 0000000..cc29b52
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Lte.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Lte.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '<=' operation expression executer.
+ */
+public class Lte extends Operation
+{
+    static final long serialVersionUID = 6945650810527140228L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return left.lessThanOrEqual(right) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Minus.java b/src/main/java/org/apache/xpath/operations/Minus.java
new file mode 100644
index 0000000..4659419
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Minus.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Minus.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The binary '-' operation expression executer.
+ */
+public class Minus extends Operation
+{
+    static final long serialVersionUID = -5297672838170871043L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the 
+   *         result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(left.num() - right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return (m_left.num(xctxt) - m_right.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Mod.java b/src/main/java/org/apache/xpath/operations/Mod.java
new file mode 100644
index 0000000..61e3308
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Mod.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Mod.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'mod' operation expression executer.
+ */
+public class Mod extends Operation
+{
+    static final long serialVersionUID = 5009471154238918201L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(left.num() % right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return (m_left.num(xctxt) % m_right.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Mult.java b/src/main/java/org/apache/xpath/operations/Mult.java
new file mode 100644
index 0000000..2948497
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Mult.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Mult.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '*' operation expression executer.
+ */
+public class Mult extends Operation
+{
+    static final long serialVersionUID = -4956770147013414675L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(left.num() * right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return (m_left.num(xctxt) * m_right.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Neg.java b/src/main/java/org/apache/xpath/operations/Neg.java
new file mode 100644
index 0000000..e61c045
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Neg.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Neg.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The unary '-' operation expression executer.
+ */
+public class Neg extends UnaryOperation
+{
+    static final long serialVersionUID = -6280607702375702291L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject right) throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(-right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return -(m_right.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/NotEquals.java b/src/main/java/org/apache/xpath/operations/NotEquals.java
new file mode 100644
index 0000000..7ba51a2
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/NotEquals.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NotEquals.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '!=' operation expression executer.
+ */
+public class NotEquals extends Operation
+{
+    static final long serialVersionUID = -7869072863070586900L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return (left.notEquals(right)) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Number.java b/src/main/java/org/apache/xpath/operations/Number.java
new file mode 100644
index 0000000..dc5cad0
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Number.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Number.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'number()' operation expression executer.
+ */
+public class Number extends UnaryOperation
+{
+    static final long serialVersionUID = 7196954482871619765L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject right) throws javax.xml.transform.TransformerException
+  {
+
+    if (XObject.CLASS_NUMBER == right.getType())
+      return right;
+    else
+      return new XNumber(right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return m_right.num(xctxt);
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Operation.java b/src/main/java/org/apache/xpath/operations/Operation.java
new file mode 100644
index 0000000..f601ae6
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Operation.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Operation.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The baseclass for a binary operation.
+ */
+public class Operation extends Expression implements ExpressionOwner
+{
+    static final long serialVersionUID = -3037139537171050430L;
+
+  /** The left operand expression.
+   *  @serial */
+  protected Expression m_left;
+
+  /** The right operand expression.
+   *  @serial */
+  protected Expression m_right;
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_left.fixupVariables(vars, globalsSize);
+    m_right.fixupVariables(vars, globalsSize);
+  }
+
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+
+    if (null != m_left && m_left.canTraverseOutsideSubtree())
+      return true;
+
+    if (null != m_right && m_right.canTraverseOutsideSubtree())
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Set the left and right operand expressions for this operation.
+   *
+   *
+   * @param l The left expression operand.
+   * @param r The right expression operand.
+   */
+  public void setLeftRight(Expression l, Expression r)
+  {
+    m_left = l;
+    m_right = r;
+    l.exprSetParent(this);
+    r.exprSetParent(this);
+  }
+
+  /**
+   * Execute a binary operation by calling execute on each of the operands,
+   * and then calling the operate method on the derived class.
+   *
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The XObject result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    XObject left = m_left.execute(xctxt, true);
+    XObject right = m_right.execute(xctxt, true);
+
+    XObject result = operate(left, right);
+    left.detach();
+    right.detach();
+    return result;
+  }
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return null;  // no-op
+  }
+
+  /** @return the left operand of binary operation, as an Expression.
+   */
+  public Expression getLeftOperand(){
+    return m_left;
+  }
+
+  /** @return the right operand of binary operation, as an Expression.
+   */
+  public Expression getRightOperand(){
+    return m_right;
+  }
+  
+  class LeftExprOwner implements ExpressionOwner
+  {
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_left;
+    }
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(Operation.this);
+    	m_left = exp;
+    }
+  }
+
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	if(visitor.visitBinaryOperation(owner, this))
+  	{
+  		m_left.callVisitors(new LeftExprOwner(), visitor);
+  		m_right.callVisitors(this, visitor);
+  	}
+  }
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_right;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_right = exp;
+  }
+
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	if(!m_left.deepEquals(((Operation)expr).m_left))
+  		return false;
+  		
+  	if(!m_right.deepEquals(((Operation)expr).m_right))
+  		return false;
+  		
+  	return true;
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/Or.java b/src/main/java/org/apache/xpath/operations/Or.java
new file mode 100644
index 0000000..769d5f9
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Or.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Or.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'or' operation expression executer.
+ */
+public class Or extends Operation
+{
+    static final long serialVersionUID = -644107191353853079L;
+
+  /**
+   * OR two expressions and return the boolean result. Override
+   * superclass method for optimization purposes.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return {@link org.apache.xpath.objects.XBoolean#S_TRUE} or 
+   * {@link org.apache.xpath.objects.XBoolean#S_FALSE}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    XObject expr1 = m_left.execute(xctxt);
+
+    if (!expr1.bool())
+    {
+      XObject expr2 = m_right.execute(xctxt);
+
+      return expr2.bool() ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+    }
+    else
+      return XBoolean.S_TRUE;
+  }
+  
+  /**
+   * Evaluate this operation directly to a boolean.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a boolean.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public boolean bool(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return (m_left.bool(xctxt) || m_right.bool(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Plus.java b/src/main/java/org/apache/xpath/operations/Plus.java
new file mode 100644
index 0000000..81980da
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Plus.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Plus.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The '+' operation expression executer.
+ */
+public class Plus extends Operation
+{
+    static final long serialVersionUID = -4492072861616504256L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber(left.num() + right.num());
+  }
+  
+  /**
+   * Evaluate this operation directly to a double.
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The result of the operation as a double.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double num(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    return (m_right.num(xctxt) + m_left.num(xctxt));
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Quo.java b/src/main/java/org/apache/xpath/operations/Quo.java
new file mode 100644
index 0000000..fe07694
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Quo.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Quo.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The 'quo' operation expression executer. (no longer supported by XPath).
+ * @deprecated
+ */
+public class Quo extends Operation
+{
+    static final long serialVersionUID = 693765299196169905L;
+
+  // Actually, this is no longer supported by xpath...
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right)
+          throws javax.xml.transform.TransformerException
+  {
+    return new XNumber((int) (left.num() / right.num()));
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/String.java b/src/main/java/org/apache/xpath/operations/String.java
new file mode 100644
index 0000000..c32678c
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/String.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: String.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * The 'string()' operation expression executer.
+ */
+public class String extends UnaryOperation
+{
+    static final long serialVersionUID = 2973374377453022888L;
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject right) throws javax.xml.transform.TransformerException
+  {
+    return (XString)right.xstr(); // semi-safe cast.
+  }
+}
diff --git a/src/main/java/org/apache/xpath/operations/UnaryOperation.java b/src/main/java/org/apache/xpath/operations/UnaryOperation.java
new file mode 100644
index 0000000..394ce88
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/UnaryOperation.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: UnaryOperation.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The unary operation base class.
+ */
+public abstract class UnaryOperation extends Expression implements ExpressionOwner
+{
+    static final long serialVersionUID = 6536083808424286166L;
+
+  /** The operand for the operation.
+   *  @serial */
+  protected Expression m_right;
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_right.fixupVariables(vars, globalsSize);
+  }
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+
+    if (null != m_right && m_right.canTraverseOutsideSubtree())
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Set the expression operand for the operation.
+   *
+   *
+   * @param r The expression operand to which the unary operation will be 
+   *          applied.
+   */
+  public void setRight(Expression r)
+  {
+    m_right = r;
+    r.exprSetParent(this);
+  }
+
+  /**
+   * Execute the operand and apply the unary operation to the result.
+   *
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return An XObject that represents the result of applying the unary 
+   *         operation to the evaluated operand.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    return operate(m_right.execute(xctxt));
+  }
+
+  /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public abstract XObject operate(XObject right)
+    throws javax.xml.transform.TransformerException;
+
+  /** @return the operand of unary operation, as an Expression.
+   */
+  public Expression getOperand(){
+    return m_right;
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	if(visitor.visitUnaryOperation(owner, this))
+  	{
+  		m_right.callVisitors(this, visitor);
+  	}
+  }
+
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_right;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+  	exp.exprSetParent(this);
+  	m_right = exp;
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	if(!m_right.deepEquals(((UnaryOperation)expr).m_right))
+  		return false;
+  		
+  	return true;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/Variable.java b/src/main/java/org/apache/xpath/operations/Variable.java
new file mode 100644
index 0000000..ab8358d
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/Variable.java
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: Variable.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.axes.PathComponent;
+import org.apache.xpath.axes.WalkerFactory;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+
+
+/**
+ * The variable reference expression executer.
+ */
+public class Variable extends Expression implements PathComponent
+{
+    static final long serialVersionUID = -4334975375609297049L;
+  /** Tell if fixupVariables was called.
+   *  @serial   */
+  private boolean m_fixUpWasCalled = false;
+
+  /** The qualified name of the variable.
+   *  @serial   */
+  protected QName m_qname;
+  
+  /**
+   * The index of the variable, which is either an absolute index to a 
+   * global, or, if higher than the globals area, must be adjusted by adding 
+   * the offset to the current stack frame.
+   */
+  protected int m_index;
+  
+  /**
+   * Set the index for the variable into the stack.  For advanced use only. You 
+   * must know what you are doing to use this.
+   * 
+   * @param index a global or local index.
+   */
+  public void setIndex(int index)
+  {
+  	m_index = index;
+  }
+  
+  /**
+   * Set the index for the variable into the stack.  For advanced use only.
+   * 
+   * @return index a global or local index.
+   */
+  public int getIndex()
+  {
+  	return m_index;
+  }
+  
+  /**
+   * Set whether or not this is a global reference.  For advanced use only.
+   * 
+   * @param isGlobal true if this should be a global variable reference.
+   */
+  public void setIsGlobal(boolean isGlobal)
+  {
+  	m_isGlobal = isGlobal;
+  }
+  
+  /**
+   * Set the index for the variable into the stack.  For advanced use only.
+   * 
+   * @return true if this should be a global variable reference.
+   */
+  public boolean getGlobal()
+  {
+  	return m_isGlobal;
+  }
+
+  
+  
+
+  
+  protected boolean m_isGlobal = false;
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    m_fixUpWasCalled = true;
+    int sz = vars.size();
+
+    for (int i = vars.size()-1; i >= 0; i--) 
+    {
+      QName qn = (QName)vars.elementAt(i);
+      // System.out.println("qn: "+qn);
+      if(qn.equals(m_qname))
+      {
+        
+        if(i < globalsSize)
+        {
+          m_isGlobal = true;
+          m_index = i;
+        }
+        else
+        {
+          m_index = i-globalsSize;
+        }
+          
+        return;
+      }
+    }
+    
+    java.lang.String msg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_COULD_NOT_FIND_VAR, 
+                                             new Object[]{m_qname.toString()});
+                                             
+    TransformerException te = new TransformerException(msg, this);
+                                             
+    throw new org.apache.xml.utils.WrappedRuntimeException(te);
+    
+  }
+
+
+  /**
+   * Set the qualified name of the variable.
+   *
+   * @param qname Must be a non-null reference to a qualified name.
+   */
+  public void setQName(QName qname)
+  {
+    m_qname = qname;
+  }
+  
+  /**
+   * Get the qualified name of the variable.
+   *
+   * @return A non-null reference to a qualified name.
+   */
+  public QName getQName()
+  {
+    return m_qname;
+  }
+  
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public XObject execute(XPathContext xctxt)
+    throws javax.xml.transform.TransformerException
+  {
+  	return execute(xctxt, false);
+  }
+
+
+  /**
+   * Dereference the variable, and return the reference value.  Note that lazy 
+   * evaluation will occur.  If a variable within scope is not found, a warning 
+   * will be sent to the error listener, and an empty nodeset will be returned.
+   *
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The evaluated variable, or an empty nodeset if not found.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, boolean destructiveOK) throws javax.xml.transform.TransformerException
+  {
+    org.apache.xml.utils.PrefixResolver xprefixResolver = xctxt.getNamespaceContext();
+
+    XObject result;
+    // Is the variable fetched always the same?
+    // XObject result = xctxt.getVariable(m_qname);
+    if(m_fixUpWasCalled)
+    {    
+      if(m_isGlobal)
+        result = xctxt.getVarStack().getGlobalVariable(xctxt, m_index, destructiveOK);
+      else
+        result = xctxt.getVarStack().getLocalVariable(xctxt, m_index, destructiveOK);
+    } 
+    else {  
+    	result = xctxt.getVarStack().getVariableOrParam(xctxt,m_qname);
+    }
+  
+      if (null == result)
+      {
+        // This should now never happen...
+        warn(xctxt, XPATHErrorResources.WG_ILLEGAL_VARIABLE_REFERENCE,
+             new Object[]{ m_qname.getLocalPart() });  //"VariableReference given for variable out "+
+  //      (new RuntimeException()).printStackTrace();
+  //      error(xctxt, XPATHErrorResources.ER_COULDNOT_GET_VAR_NAMED,
+  //            new Object[]{ m_qname.getLocalPart() });  //"Could not get variable named "+varName);
+        
+        result = new XNodeSet(xctxt.getDTMManager());
+      }
+  
+      return result;
+//    }
+//    else
+//    {
+//      // Hack city... big time.  This is needed to evaluate xpaths from extensions, 
+//      // pending some bright light going off in my head.  Some sort of callback?
+//      synchronized(this)
+//      {
+//      	org.apache.xalan.templates.ElemVariable vvar= getElemVariable();
+//      	if(null != vvar)
+//      	{
+//          m_index = vvar.getIndex();
+//          m_isGlobal = vvar.getIsTopLevel();
+//          m_fixUpWasCalled = true;
+//          return execute(xctxt);
+//      	}
+//      }
+//      throw new javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VAR_NOT_RESOLVABLE, new Object[]{m_qname.toString()})); //"Variable not resolvable: "+m_qname);
+//    }
+  }
+  
+  /**
+   * Get the XSLT ElemVariable that this sub-expression references.  In order for 
+   * this to work, the SourceLocator must be the owning ElemTemplateElement.
+   * @return The dereference to the ElemVariable, or null if not found.
+   */
+  public org.apache.xalan.templates.ElemVariable getElemVariable()
+  {
+  	
+    // Get the current ElemTemplateElement, and then walk backwards in 
+    // document order, searching 
+    // for an xsl:param element or xsl:variable element that matches our 
+    // qname.  If we reach the top level, use the StylesheetRoot's composed
+    // list of top level variables and parameters.
+    
+    org.apache.xalan.templates.ElemVariable vvar = null;	
+    org.apache.xpath.ExpressionNode owner = getExpressionOwner();
+
+    if (null != owner && owner instanceof org.apache.xalan.templates.ElemTemplateElement)
+    {
+
+      org.apache.xalan.templates.ElemTemplateElement prev = 
+        (org.apache.xalan.templates.ElemTemplateElement) owner;
+
+      if (!(prev instanceof org.apache.xalan.templates.Stylesheet))
+      {            
+        while ( prev != null && !(prev.getParentNode() instanceof org.apache.xalan.templates.Stylesheet) )
+        {
+          org.apache.xalan.templates.ElemTemplateElement savedprev = prev;
+
+          while (null != (prev = prev.getPreviousSiblingElem()))
+          {
+            if(prev instanceof org.apache.xalan.templates.ElemVariable)
+            {
+              vvar = (org.apache.xalan.templates.ElemVariable) prev;
+            
+              if (vvar.getName().equals(m_qname))
+              {
+                return vvar;
+              }
+              vvar = null; 	 	
+            }
+          }
+          prev = savedprev.getParentElem();
+        }
+      }
+      if (prev != null)
+        vvar = prev.getStylesheetRoot().getVariableOrParamComposed(m_qname);
+    }
+    return vvar;
+
+  }
+  
+  /**
+   * Tell if this expression returns a stable number that will not change during 
+   * iterations within the expression.  This is used to determine if a proximity 
+   * position predicate can indicate that no more searching has to occur.
+   * 
+   *
+   * @return true if the expression represents a stable number.
+   */
+  public boolean isStableNumber()
+  {
+    return true;
+  }
+  
+  /** 
+   * Get the analysis bits for this walker, as defined in the WalkerFactory.
+   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
+   */
+  public int getAnalysisBits()
+  {
+  	org.apache.xalan.templates.ElemVariable vvar = getElemVariable();
+  	if(null != vvar)
+  	{
+  		XPath xpath = vvar.getSelect();
+  		if(null != xpath)
+  		{
+	  		Expression expr = xpath.getExpression();
+	  		if(null != expr && expr instanceof PathComponent)
+	  		{
+	  			return ((PathComponent)expr).getAnalysisBits();
+	  		}
+  		}
+  	}
+    return WalkerFactory.BIT_FILTER;
+  }
+
+
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	visitor.visitVariableRef(owner, this);
+  }
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	if(!m_qname.equals(((Variable)expr).m_qname))
+  		return false;
+  		
+  	// We have to make sure that the qname really references 
+  	// the same variable element.
+    if(getElemVariable() != ((Variable)expr).getElemVariable())
+    	return false;
+  		
+  	return true;
+  }
+  
+  static final java.lang.String PSUEDOVARNAMESPACE = "http://xml.apache.org/xalan/psuedovar";
+  
+  /**
+   * Tell if this is a psuedo variable reference, declared by Xalan instead 
+   * of by the user.
+   */
+  public boolean isPsuedoVarRef()
+  {
+  	java.lang.String ns = m_qname.getNamespaceURI();
+  	if((null != ns) && ns.equals(PSUEDOVARNAMESPACE))
+  	{
+  		if(m_qname.getLocalName().startsWith("#"))
+  			return true;
+  	}
+  	return false;
+  }
+  
+
+}
diff --git a/src/main/java/org/apache/xpath/operations/VariableSafeAbsRef.java b/src/main/java/org/apache/xpath/operations/VariableSafeAbsRef.java
new file mode 100644
index 0000000..63e4324
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/VariableSafeAbsRef.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: VariableSafeAbsRef.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+
+
+/**
+ * This is a "smart" variable reference that is used in situations where 
+ * an absolute path is optimized into a variable reference, but may 
+ * be used in some situations where the document context may have changed.
+ * For instance, in select="document(doc/@href)//name[//salary &gt; 7250]", the 
+ * root in the predicate will be different for each node in the set.  While 
+ * this is easy to detect statically in this case, in other cases static 
+ * detection would be very hard or impossible.  So, this class does a dynamic check 
+ * to make sure the document context of the referenced variable is the same as 
+ * the current document context, and, if it is not, execute the referenced variable's 
+ * expression with the current context instead.
+ */
+public class VariableSafeAbsRef extends Variable
+{
+    static final long serialVersionUID = -9174661990819967452L;
+	
+  /**
+   * Dereference the variable, and return the reference value.  Note that lazy 
+   * evaluation will occur.  If a variable within scope is not found, a warning 
+   * will be sent to the error listener, and an empty nodeset will be returned.
+   *
+   *
+   * @param xctxt The runtime execution context.
+   *
+   * @return The evaluated variable, or an empty nodeset if not found.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, boolean destructiveOK) 
+  	throws javax.xml.transform.TransformerException
+  {
+  	XNodeSet xns = (XNodeSet)super.execute(xctxt, destructiveOK);
+  	DTMManager dtmMgr = xctxt.getDTMManager();
+  	int context = xctxt.getContextNode();
+  	if(dtmMgr.getDTM(xns.getRoot()).getDocument() != 
+  	   dtmMgr.getDTM(context).getDocument())
+  	{
+  		Expression expr = (Expression)xns.getContainedIter();
+  		xns = (XNodeSet)expr.asIterator(xctxt, context);
+  	}
+  	return xns;
+  }
+
+}
+
diff --git a/src/main/java/org/apache/xpath/operations/package.html b/src/main/java/org/apache/xpath/operations/package.html
new file mode 100644
index 0000000..e91d869
--- /dev/null
+++ b/src/main/java/org/apache/xpath/operations/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>Xalan XPath operations.</title>
+  <body>
+    <p>Support for XPath operations, such as +, -, string(), etc.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/package.html b/src/main/java/org/apache/xpath/package.html
new file mode 100644
index 0000000..2536a57
--- /dev/null
+++ b/src/main/java/org/apache/xpath/package.html
@@ -0,0 +1,27 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath support Package.</title>
+  <body>
+    <p>Implementation of XPath; for the most part, only classes meant for public use are
+    found at this root level of the XPath packages.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/patterns/ContextMatchStepPattern.java b/src/main/java/org/apache/xpath/patterns/ContextMatchStepPattern.java
new file mode 100644
index 0000000..54ecfae
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/ContextMatchStepPattern.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: ContextMatchStepPattern.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.WalkerFactory;
+import org.apache.xpath.objects.XObject;
+/**
+ * Special context node pattern matcher.
+ */
+public class ContextMatchStepPattern extends StepPattern
+{
+    static final long serialVersionUID = -1888092779313211942L;
+
+  /**
+   * Construct a ContextMatchStepPattern.
+   *
+   */
+  public ContextMatchStepPattern(int axis, int paxis)
+  {
+    super(DTMFilter.SHOW_ALL, axis, paxis);
+  }
+
+  /**
+   * Execute this pattern step, including predicates.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
+      return getStaticScore();
+    else
+      return this.SCORE_NONE;
+  }
+  
+  /**
+   * Execute the match pattern step relative to another step.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * NEEDSDOC @param prevStep
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject executeRelativePathPattern(
+          XPathContext xctxt, StepPattern prevStep)
+            throws javax.xml.transform.TransformerException
+  {
+
+    XObject score = NodeTest.SCORE_NONE;
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+
+    if (null != dtm)
+    {
+      int predContext = xctxt.getCurrentNode();
+      DTMAxisTraverser traverser;
+      
+      int axis = m_axis;
+      
+      boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis);
+      boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot()) 
+                                 == DTM.ATTRIBUTE_NODE);
+
+      if((Axis.PRECEDING == axis) && iterRootIsAttr)
+      {
+        axis = Axis.PRECEDINGANDANCESTOR;
+      }
+      
+      traverser = dtm.getAxisTraverser(axis);
+
+      for (int relative = traverser.first(context); DTM.NULL != relative;
+              relative = traverser.next(context, relative))
+      {
+        try
+        {
+          xctxt.pushCurrentNode(relative);
+
+          score = execute(xctxt);
+
+          if (score != NodeTest.SCORE_NONE)
+          {
+	      //score = executePredicates( xctxt, prevStep, SCORE_OTHER, 
+	      //       predContext, relative);
+	      if (executePredicates(xctxt, dtm, context))
+		  return score;
+	      
+	      score = NodeTest.SCORE_NONE;
+          }
+          
+          if(needToTraverseAttrs && iterRootIsAttr
+             && (DTM.ELEMENT_NODE == dtm.getNodeType(relative)))
+          {
+            int xaxis = Axis.ATTRIBUTE;
+            for (int i = 0; i < 2; i++) 
+            {            
+              DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis);
+        
+              for (int arelative = atraverser.first(relative); 
+                      DTM.NULL != arelative;
+                      arelative = atraverser.next(relative, arelative))
+              {
+                try
+                {
+                  xctxt.pushCurrentNode(arelative);
+        
+                  score = execute(xctxt);
+        
+                  if (score != NodeTest.SCORE_NONE)
+                  {
+		      //score = executePredicates( xctxt, prevStep, SCORE_OTHER, 
+		      //       predContext, arelative);
+        
+                    if (score != NodeTest.SCORE_NONE)
+                      return score;
+                  }
+                }
+                finally
+                {
+                  xctxt.popCurrentNode();
+                }
+              }
+              xaxis = Axis.NAMESPACE;
+            }
+          }
+
+        }
+        finally
+        {
+          xctxt.popCurrentNode();
+        }
+      }
+
+    }
+
+    return score;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/patterns/FunctionPattern.java b/src/main/java/org/apache/xpath/patterns/FunctionPattern.java
new file mode 100644
index 0000000..3a45c05
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/FunctionPattern.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: FunctionPattern.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Match pattern step that contains a function.
+ * @xsl.usage advanced
+ */
+public class FunctionPattern extends StepPattern
+{
+    static final long serialVersionUID = -5426793413091209944L;
+
+  /**
+   * Construct a FunctionPattern from a
+   * {@link org.apache.xpath.functions.Function expression}.
+   *
+   * NEEDSDOC @param expr
+   */
+  public FunctionPattern(Expression expr, int axis, int predaxis)
+  {
+
+    super(0, null, null, axis, predaxis);
+
+    m_functionExpr = expr;
+  }
+
+  /**
+   * Static calc of match score.
+   */
+  public final void calcScore()
+  {
+
+    m_score = SCORE_OTHER;
+
+    if (null == m_targetString)
+      calcTargetString();
+  }
+
+  /**
+   * Should be a {@link org.apache.xpath.functions.Function expression}.
+   *  @serial   
+   */
+  Expression m_functionExpr;
+  
+  /**
+   * This function is used to fixup variables from QNames to stack frame 
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list 
+   * should be searched backwards for the first qualified name that 
+   * corresponds to the variable reference qname.  The position of the 
+   * QName in the vector from the start of the vector will be its position 
+   * in the stack frame (but variables above the globalsTop value will need 
+   * to be offset to the current stack frame).
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    super.fixupVariables(vars, globalsSize);
+    m_functionExpr.fixupVariables(vars, globalsSize);
+  }
+
+  
+  /**
+   * Test a node to see if it matches the given node test.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, int context)
+          throws javax.xml.transform.TransformerException
+  {
+
+    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
+    XNumber score = SCORE_NONE;
+
+    if (null != nl)
+    {
+      int n;
+
+      while (DTM.NULL != (n = nl.nextNode()))
+      {
+        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
+
+        if (score == SCORE_OTHER)
+        {
+          context = n;
+
+          break;
+        }
+      }
+
+      // nl.detach();
+    }
+    nl.detach();
+
+    return score;
+  }
+  
+  /**
+   * Test a node to see if it matches the given node test.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, int context, 
+                         DTM dtm, int expType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
+    XNumber score = SCORE_NONE;
+
+    if (null != nl)
+    {
+      int n;
+
+      while (DTM.NULL != (n = nl.nextNode()))
+      {
+        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
+
+        if (score == SCORE_OTHER)
+        {
+          context = n;
+
+          break;
+        }
+      }
+
+      nl.detach();
+    }
+
+    return score;
+  }
+  
+  /**
+   * Test a node to see if it matches the given node test.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+
+    int context = xctxt.getCurrentNode();
+    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
+    XNumber score = SCORE_NONE;
+
+    if (null != nl)
+    {
+      int n;
+
+      while (DTM.NULL != (n = nl.nextNode()))
+      {
+        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
+
+        if (score == SCORE_OTHER)
+        {
+          context = n;
+
+          break;
+        }
+      }
+
+      nl.detach();
+    }
+
+    return score;
+  }
+  
+  class FunctionOwner implements ExpressionOwner
+  {
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_functionExpr;
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(FunctionPattern.this);
+    	m_functionExpr = exp;
+    }
+  }
+  
+  /**
+   * Call the visitor for the function.
+   */
+  protected void callSubtreeVisitors(XPathVisitor visitor)
+  {
+    m_functionExpr.callVisitors(new FunctionOwner(), visitor);
+    super.callSubtreeVisitors(visitor);
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/patterns/NodeTest.java b/src/main/java/org/apache/xpath/patterns/NodeTest.java
new file mode 100644
index 0000000..9829146
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/NodeTest.java
@@ -0,0 +1,692 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeTest.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This is the basic node test class for both match patterns and location path
+ * steps.
+ * @xsl.usage advanced
+ */
+public class NodeTest extends Expression
+{
+    static final long serialVersionUID = -5736721866747906182L;
+
+  /**
+   * The namespace or local name for node tests with a wildcard.
+   *  @see <a href="http://www.w3.org/TR/xpath#NT-NameTest">the XPath NameTest production.</a> 
+   */
+  public static final String WILD = "*";
+
+  /**
+   * The URL to pass to the Node#supports method, to see if the
+   * DOM has already been stripped of whitespace nodes. 
+   */
+  public static final String SUPPORTS_PRE_STRIPPING =
+    "http://xml.apache.org/xpath/features/whitespace-pre-stripping";
+
+  /**
+   * This attribute determines which node types are accepted.
+   * @serial
+   */
+  protected int m_whatToShow;
+
+  /**
+   * Special bitmap for match patterns starting with a function.
+   * Make sure this does not conflict with {@link org.w3c.dom.traversal.NodeFilter}.
+   */
+  public static final int SHOW_BYFUNCTION = 0x00010000;
+
+  /**
+   * This attribute determines which node types are accepted.
+   * These constants are defined in the {@link org.w3c.dom.traversal.NodeFilter}
+   * interface.
+   *
+   * @return bitset mainly defined in {@link org.w3c.dom.traversal.NodeFilter}.
+   */
+  public int getWhatToShow()
+  {
+    return m_whatToShow;
+  }
+  
+  /**
+   * This attribute determines which node types are accepted.
+   * These constants are defined in the {@link org.w3c.dom.traversal.NodeFilter}
+   * interface.
+   *
+   * @param what bitset mainly defined in {@link org.w3c.dom.traversal.NodeFilter}.
+   */
+  public void setWhatToShow(int what)
+  {
+    m_whatToShow = what;
+  }
+
+  /**
+   * The namespace to be tested for, which may be null.
+   *  @serial 
+   */
+  String m_namespace;
+
+  /**
+   * Return the namespace to be tested.
+   *
+   * @return The namespace to be tested for, or {@link #WILD}, or null.
+   */
+  public String getNamespace()
+  {
+    return m_namespace;
+  }
+
+  /**
+   * Set the namespace to be tested.
+   *
+   * @param ns The namespace to be tested for, or {@link #WILD}, or null.
+   */
+  public void setNamespace(String ns)
+  {
+    m_namespace = ns;
+  }
+
+  /**
+   * The local name to be tested for.
+   *  @serial 
+   */
+  protected String m_name;
+
+  /**
+   * Return the local name to be tested.
+   *
+   * @return the local name to be tested, or {@link #WILD}, or an empty string.
+   */
+  public String getLocalName()
+  {
+    return (null == m_name) ? "" : m_name;
+  }
+
+  /**
+   * Set the local name to be tested.
+   *
+   * @param name the local name to be tested, or {@link #WILD}, or an empty string.
+   */
+  public void setLocalName(String name)
+  {
+    m_name = name;
+  }
+
+  /**
+   * Statically calculated score for this test.  One of
+   *  {@link #SCORE_NODETEST},
+   *  {@link #SCORE_NONE},
+   *  {@link #SCORE_NSWILD},
+   *  {@link #SCORE_QNAME}, or
+   *  {@link #SCORE_OTHER}.
+   *  @serial
+   */
+  XNumber m_score;
+
+  /**
+   * The match score if the pattern consists of just a NodeTest.
+   *  @see <a href="http://www.w3.org/TR/xslt#conflict">XSLT Specification - 5.5 Conflict Resolution for Template Rules</a> 
+   */
+  public static final XNumber SCORE_NODETEST =
+    new XNumber(XPath.MATCH_SCORE_NODETEST);
+
+  /**
+   * The match score if the pattern pattern has the form NCName:*.
+   *  @see <a href="http://www.w3.org/TR/xslt#conflict">XSLT Specification - 5.5 Conflict Resolution for Template Rules</a> 
+   */
+  public static final XNumber SCORE_NSWILD =
+    new XNumber(XPath.MATCH_SCORE_NSWILD);
+
+  /**
+   * The match score if the pattern has the form
+   * of a QName optionally preceded by an @ character.
+   *  @see <a href="http://www.w3.org/TR/xslt#conflict">XSLT Specification - 5.5 Conflict Resolution for Template Rules</a> 
+   */
+  public static final XNumber SCORE_QNAME =
+    new XNumber(XPath.MATCH_SCORE_QNAME);
+
+  /**
+   * The match score if the pattern consists of something
+   * other than just a NodeTest or just a qname.
+   *  @see <a href="http://www.w3.org/TR/xslt#conflict">XSLT Specification - 5.5 Conflict Resolution for Template Rules</a> 
+   */
+  public static final XNumber SCORE_OTHER =
+    new XNumber(XPath.MATCH_SCORE_OTHER);
+
+  /**
+   * The match score if no match is made.
+   *  @see <a href="http://www.w3.org/TR/xslt#conflict">XSLT Specification - 5.5 Conflict Resolution for Template Rules</a> 
+   */
+  public static final XNumber SCORE_NONE =
+    new XNumber(XPath.MATCH_SCORE_NONE);
+
+  /**
+   * Construct an NodeTest that tests for namespaces and node names.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   * @param namespace The namespace to be tested.
+   * @param name The local name to be tested.
+   */
+  public NodeTest(int whatToShow, String namespace, String name)
+  {
+    initNodeTest(whatToShow, namespace, name);
+  }
+
+  /**
+   * Construct an NodeTest that doesn't test for node names.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   */
+  public NodeTest(int whatToShow)
+  {
+    initNodeTest(whatToShow);
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	NodeTest nt = (NodeTest)expr;
+
+  	if(null != nt.m_name)
+  	{
+  		if(null == m_name)
+  			return false;
+  		else if(!nt.m_name.equals(m_name))
+  			return false;
+  	}
+  	else if(null != m_name)
+  		return false;
+
+  	if(null != nt.m_namespace)
+  	{
+  		if(null == m_namespace)
+  			return false;
+  		else if(!nt.m_namespace.equals(m_namespace))
+  			return false;
+  	}
+  	else if(null != m_namespace)
+  		return false;
+  		  		
+  	if(m_whatToShow != nt.m_whatToShow)
+  		return false;
+  		
+  	if(m_isTotallyWild != nt.m_isTotallyWild)
+  		return false;
+
+	return true;
+  }
+
+  /**
+   * Null argument constructor.
+   */
+  public NodeTest(){}
+
+  /**
+   * Initialize this node test by setting the whatToShow property, and
+   * calculating the score that this test will return if a test succeeds.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   */
+  public void initNodeTest(int whatToShow)
+  {
+
+    m_whatToShow = whatToShow;
+
+    calcScore();
+  }
+
+  /**
+   * Initialize this node test by setting the whatToShow property and the
+   * namespace and local name, and
+   * calculating the score that this test will return if a test succeeds.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   * @param namespace The namespace to be tested.
+   * @param name The local name to be tested.
+   */
+  public void initNodeTest(int whatToShow, String namespace, String name)
+  {
+
+    m_whatToShow = whatToShow;
+    m_namespace = namespace;
+    m_name = name;
+
+    calcScore();
+  }
+
+  /**
+   * True if this test has a null namespace and a local name of {@link #WILD}.
+   *  @serial 
+   */
+  private boolean m_isTotallyWild;
+  
+  /**
+   * Get the static score for this node test.
+   * @return Should be one of the SCORE_XXX constants.
+   */
+  public XNumber getStaticScore()
+  {
+    return m_score;
+  }
+  
+  /**
+   * Set the static score for this node test.
+   * @param score Should be one of the SCORE_XXX constants.
+   */
+  public void setStaticScore(XNumber score)
+  {
+    m_score = score;
+  }
+
+  /**
+   * Static calc of match score.
+   */
+  protected void calcScore()
+  {
+
+    if ((m_namespace == null) && (m_name == null))
+      m_score = SCORE_NODETEST;
+    else if (((m_namespace == WILD) || (m_namespace == null))
+             && (m_name == WILD))
+      m_score = SCORE_NODETEST;
+    else if ((m_namespace != WILD) && (m_name == WILD))
+      m_score = SCORE_NSWILD;
+    else
+      m_score = SCORE_QNAME;
+
+    m_isTotallyWild = (m_namespace == null && m_name == WILD);
+  }
+
+  /**
+   * Get the score that this test will return if a test succeeds.
+   *
+   *
+   * @return the score that this test will return if a test succeeds.
+   */
+  public double getDefaultScore()
+  {
+    return m_score.num();
+  }
+  
+  /**
+   * Tell what node type to test, if not DTMFilter.SHOW_ALL.
+   *
+   * @param whatToShow Bit set defined mainly by 
+   *        {@link org.apache.xml.dtm.DTMFilter}.
+   * @return the node type for the whatToShow.  Since whatToShow can specify 
+   *         multiple types, it will return the first bit tested that is on, 
+   *         so the caller of this function should take care that this is 
+   *         the function they really want to call.  If none of the known bits
+   *         are set, this function will return zero.
+   */
+  public static int getNodeTypeTest(int whatToShow)
+  {
+    // %REVIEW% Is there a better way?
+    if (0 != (whatToShow & DTMFilter.SHOW_ELEMENT))
+      return DTM.ELEMENT_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ATTRIBUTE))
+      return DTM.ATTRIBUTE_NODE;
+      
+    if (0 != (whatToShow & DTMFilter.SHOW_TEXT))
+      return DTM.TEXT_NODE;
+      
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT))
+      return DTM.DOCUMENT_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT_FRAGMENT))
+      return DTM.DOCUMENT_FRAGMENT_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_NAMESPACE))
+      return DTM.NAMESPACE_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_COMMENT))
+      return DTM.COMMENT_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_PROCESSING_INSTRUCTION))
+      return DTM.PROCESSING_INSTRUCTION_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT_TYPE))
+      return DTM.DOCUMENT_TYPE_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ENTITY))
+      return DTM.ENTITY_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ENTITY_REFERENCE))
+      return DTM.ENTITY_REFERENCE_NODE;
+
+    if (0 != (whatToShow & DTMFilter.SHOW_NOTATION))
+      return DTM.NOTATION_NODE;
+      
+    if (0 != (whatToShow & DTMFilter.SHOW_CDATA_SECTION))
+      return DTM.CDATA_SECTION_NODE;
+
+
+    return 0;
+  }
+
+
+  /**
+   * Do a diagnostics dump of a whatToShow bit set.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by 
+   *        {@link org.apache.xml.dtm.DTMFilter}.
+   */
+  public static void debugWhatToShow(int whatToShow)
+  {
+
+    java.util.Vector v = new java.util.Vector();
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ATTRIBUTE))
+      v.addElement("SHOW_ATTRIBUTE");
+      
+    if (0 != (whatToShow & DTMFilter.SHOW_NAMESPACE))
+      v.addElement("SHOW_NAMESPACE");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_CDATA_SECTION))
+      v.addElement("SHOW_CDATA_SECTION");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_COMMENT))
+      v.addElement("SHOW_COMMENT");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT))
+      v.addElement("SHOW_DOCUMENT");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT_FRAGMENT))
+      v.addElement("SHOW_DOCUMENT_FRAGMENT");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_DOCUMENT_TYPE))
+      v.addElement("SHOW_DOCUMENT_TYPE");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ELEMENT))
+      v.addElement("SHOW_ELEMENT");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ENTITY))
+      v.addElement("SHOW_ENTITY");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_ENTITY_REFERENCE))
+      v.addElement("SHOW_ENTITY_REFERENCE");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_NOTATION))
+      v.addElement("SHOW_NOTATION");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_PROCESSING_INSTRUCTION))
+      v.addElement("SHOW_PROCESSING_INSTRUCTION");
+
+    if (0 != (whatToShow & DTMFilter.SHOW_TEXT))
+      v.addElement("SHOW_TEXT");
+
+    int n = v.size();
+
+    for (int i = 0; i < n; i++)
+    {
+      if (i > 0)
+        System.out.print(" | ");
+
+      System.out.print(v.elementAt(i));
+    }
+
+    if (0 == n)
+      System.out.print("empty whatToShow: " + whatToShow);
+
+    System.out.println();
+  }
+
+  /**
+   * Two names are equal if they and either both are null or
+   * the name t is wild and the name p is non-null, or the two
+   * strings are equal.
+   *
+   * @param p part string from the node.
+   * @param t target string, which may be {@link #WILD}.
+   *
+   * @return true if the strings match according to the rules of this method.
+   */
+  private static final boolean subPartMatch(String p, String t)
+  {
+
+    // boolean b = (p == t) || ((null != p) && ((t == WILD) || p.equals(t)));
+    // System.out.println("subPartMatch - p: "+p+", t: "+t+", result: "+b);
+    return (p == t) || ((null != p) && ((t == WILD) || p.equals(t)));
+  }
+
+  /**
+   * This is temporary to patch over Xerces issue with representing DOM
+   * namespaces as "".
+   *
+   * @param p part string from the node, which may represent the null namespace
+   *        as null or as "".
+   * @param t target string, which may be {@link #WILD}.
+   *
+   * @return true if the strings match according to the rules of this method.
+   */
+  private static final boolean subPartMatchNS(String p, String t)
+  {
+
+    return (p == t)
+           || ((null != p)
+               && ((p.length() > 0)
+                   ? ((t == WILD) || p.equals(t)) : null == t));
+  }
+
+  /**
+   * Tell what the test score is for the given node.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   * @param context The node being tested.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, int context)
+          throws javax.xml.transform.TransformerException
+  {
+
+    DTM dtm = xctxt.getDTM(context);
+    short nodeType = dtm.getNodeType(context);
+
+    if (m_whatToShow == DTMFilter.SHOW_ALL)
+      return m_score;
+
+    int nodeBit = (m_whatToShow & (0x00000001 << (nodeType - 1)));
+
+    switch (nodeBit)
+    {
+    case DTMFilter.SHOW_DOCUMENT_FRAGMENT :
+    case DTMFilter.SHOW_DOCUMENT :
+      return SCORE_OTHER;
+    case DTMFilter.SHOW_COMMENT :
+      return m_score;
+    case DTMFilter.SHOW_CDATA_SECTION :
+    case DTMFilter.SHOW_TEXT :
+
+      // was: 
+      // return (!xctxt.getDOMHelper().shouldStripSourceNode(context))
+      //       ? m_score : SCORE_NONE;
+      return m_score;
+    case DTMFilter.SHOW_PROCESSING_INSTRUCTION :
+      return subPartMatch(dtm.getNodeName(context), m_name)
+             ? m_score : SCORE_NONE;
+
+    // From the draft: "Two expanded names are equal if they 
+    // have the same local part, and either both have no URI or 
+    // both have the same URI."
+    // "A node test * is true for any node of the principal node type. 
+    // For example, child::* will select all element children of the 
+    // context node, and attribute::* will select all attributes of 
+    // the context node."
+    // "A node test can have the form NCName:*. In this case, the prefix 
+    // is expanded in the same way as with a QName using the context 
+    // namespace declarations. The node test will be true for any node 
+    // of the principal type whose expanded name has the URI to which 
+    // the prefix expands, regardless of the local part of the name."
+    case DTMFilter.SHOW_NAMESPACE :
+    {
+      String ns = dtm.getLocalName(context);
+
+      return (subPartMatch(ns, m_name)) ? m_score : SCORE_NONE;
+    }
+    case DTMFilter.SHOW_ATTRIBUTE :
+    case DTMFilter.SHOW_ELEMENT :
+    {
+      return (m_isTotallyWild || (subPartMatchNS(dtm.getNamespaceURI(context), m_namespace) && subPartMatch(dtm.getLocalName(context), m_name)))
+             ? m_score : SCORE_NONE;
+    }
+    default :
+      return SCORE_NONE;
+    }  // end switch(testType)
+  }
+  
+  /**
+   * Tell what the test score is for the given node.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   * @param context The node being tested.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, int context, 
+                         DTM dtm, int expType)
+          throws javax.xml.transform.TransformerException
+  {
+
+    if (m_whatToShow == DTMFilter.SHOW_ALL)
+      return m_score;
+
+    int nodeBit = (m_whatToShow & (0x00000001 
+                   << ((dtm.getNodeType(context)) - 1)));
+
+    switch (nodeBit)
+    {
+    case DTMFilter.SHOW_DOCUMENT_FRAGMENT :
+    case DTMFilter.SHOW_DOCUMENT :
+      return SCORE_OTHER;
+    case DTMFilter.SHOW_COMMENT :
+      return m_score;
+    case DTMFilter.SHOW_CDATA_SECTION :
+    case DTMFilter.SHOW_TEXT :
+
+      // was: 
+      // return (!xctxt.getDOMHelper().shouldStripSourceNode(context))
+      //       ? m_score : SCORE_NONE;
+      return m_score;
+    case DTMFilter.SHOW_PROCESSING_INSTRUCTION :
+      return subPartMatch(dtm.getNodeName(context), m_name)
+             ? m_score : SCORE_NONE;
+
+    // From the draft: "Two expanded names are equal if they 
+    // have the same local part, and either both have no URI or 
+    // both have the same URI."
+    // "A node test * is true for any node of the principal node type. 
+    // For example, child::* will select all element children of the 
+    // context node, and attribute::* will select all attributes of 
+    // the context node."
+    // "A node test can have the form NCName:*. In this case, the prefix 
+    // is expanded in the same way as with a QName using the context 
+    // namespace declarations. The node test will be true for any node 
+    // of the principal type whose expanded name has the URI to which 
+    // the prefix expands, regardless of the local part of the name."
+    case DTMFilter.SHOW_NAMESPACE :
+    {
+      String ns = dtm.getLocalName(context);
+
+      return (subPartMatch(ns, m_name)) ? m_score : SCORE_NONE;
+    }
+    case DTMFilter.SHOW_ATTRIBUTE :
+    case DTMFilter.SHOW_ELEMENT :
+    {
+      return (m_isTotallyWild || (subPartMatchNS(dtm.getNamespaceURI(context), m_namespace) && subPartMatch(dtm.getLocalName(context), m_name)))
+             ? m_score : SCORE_NONE;
+    }
+    default :
+      return SCORE_NONE;
+    }  // end switch(testType)
+  }
+
+  /**
+   * Test the current node to see if it matches the given node test.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return execute(xctxt, xctxt.getCurrentNode());
+  }
+  
+  /**
+   * Node tests by themselves do not need to fix up variables.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    // no-op
+  }
+
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	assertion(false, "callVisitors should not be called for this object!!!");  	
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/patterns/NodeTestFilter.java b/src/main/java/org/apache/xpath/patterns/NodeTestFilter.java
new file mode 100644
index 0000000..82bbc8b
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/NodeTestFilter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: NodeTestFilter.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+/**
+ * This interface should be implemented by Nodes and/or iterators,
+ * when they need to know what the node test is before they do
+ * getNextChild, etc.
+ */
+public interface NodeTestFilter
+{
+
+  /**
+   * Set the node test for this filter.
+   *
+   *
+   * @param nodeTest Reference to a NodeTest that may be used to predetermine 
+   *                 what nodes to return.
+   */
+  void setNodeTest(NodeTest nodeTest);
+}
diff --git a/src/main/java/org/apache/xpath/patterns/StepPattern.java b/src/main/java/org/apache/xpath/patterns/StepPattern.java
new file mode 100644
index 0000000..463b671
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/StepPattern.java
@@ -0,0 +1,1053 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: StepPattern.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+import org.apache.xml.dtm.Axis;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMFilter;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.axes.SubContextList;
+import org.apache.xpath.compiler.PsuedoNames;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This class represents a single pattern match step.
+ * @xsl.usage advanced
+ */
+public class StepPattern extends NodeTest implements SubContextList, ExpressionOwner
+{
+    static final long serialVersionUID = 9071668960168152644L;
+
+  /** The axis for this test. */
+  protected int m_axis;
+
+  /**
+   * Construct a StepPattern that tests for namespaces and node names.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   * @param namespace The namespace to be tested.
+   * @param name The local name to be tested.
+   * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
+   * @param axisForPredicate No longer used.
+   */
+  public StepPattern(int whatToShow, String namespace, String name, int axis,
+                     int axisForPredicate)
+  {
+
+    super(whatToShow, namespace, name);
+
+    m_axis = axis;
+  }
+
+  /**
+   * Construct a StepPattern that doesn't test for node names.
+   *
+   *
+   * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
+   * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
+   * @param axisForPredicate No longer used.
+   */
+  public StepPattern(int whatToShow, int axis, int axisForPredicate)
+  {
+
+    super(whatToShow);
+
+    m_axis = axis;
+  }
+
+  /**
+   * The target local name or psuedo name, for hash table lookup optimization.
+   *  @serial
+   */
+  String m_targetString;  // only calculate on head
+
+  /**
+   * Calculate the local name or psuedo name of the node that this pattern will test,
+   * for hash table lookup optimization.
+   *
+   * @see org.apache.xpath.compiler.PsuedoNames
+   */
+  public void calcTargetString()
+  {
+
+    int whatToShow = getWhatToShow();
+
+    switch (whatToShow)
+    {
+    case DTMFilter.SHOW_COMMENT :
+      m_targetString = PsuedoNames.PSEUDONAME_COMMENT;
+      break;
+    case DTMFilter.SHOW_TEXT :
+    case DTMFilter.SHOW_CDATA_SECTION :
+    case (DTMFilter.SHOW_TEXT | DTMFilter.SHOW_CDATA_SECTION) :
+      m_targetString = PsuedoNames.PSEUDONAME_TEXT;
+      break;
+    case DTMFilter.SHOW_ALL :
+      m_targetString = PsuedoNames.PSEUDONAME_ANY;
+      break;
+    case DTMFilter.SHOW_DOCUMENT :
+    case DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT :
+      m_targetString = PsuedoNames.PSEUDONAME_ROOT;
+      break;
+    case DTMFilter.SHOW_ELEMENT :
+      if (this.WILD == m_name)
+        m_targetString = PsuedoNames.PSEUDONAME_ANY;
+      else
+        m_targetString = m_name;
+      break;
+    default :
+      m_targetString = PsuedoNames.PSEUDONAME_ANY;
+      break;
+    }
+  }
+
+  /**
+   * Get the local name or psuedo name of the node that this pattern will test,
+   * for hash table lookup optimization.
+   *
+   *
+   * @return local name or psuedo name of the node.
+   * @see org.apache.xpath.compiler.PsuedoNames
+   */
+  public String getTargetString()
+  {
+    return m_targetString;
+  }
+
+  /**
+   * Reference to nodetest and predicate for
+   * parent or ancestor.
+   * @serial
+   */
+  StepPattern m_relativePathPattern;
+
+  /**
+   * This function is used to fixup variables from QNames to stack frame
+   * indexes at stylesheet build time.
+   * @param vars List of QNames that correspond to variables.  This list
+   * should be searched backwards for the first qualified name that
+   * corresponds to the variable reference qname.  The position of the
+   * QName in the vector from the start of the vector will be its position
+   * in the stack frame (but variables above the globalsTop value will need
+   * to be offset to the current stack frame).
+   * @param globalsSize The number of variables in the global variable area.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+
+    super.fixupVariables(vars, globalsSize);
+
+    if (null != m_predicates)
+    {
+      for (int i = 0; i < m_predicates.length; i++)
+      {
+        m_predicates[i].fixupVariables(vars, globalsSize);
+      }
+    }
+
+    if (null != m_relativePathPattern)
+    {
+      m_relativePathPattern.fixupVariables(vars, globalsSize);
+    }
+  }
+
+  /**
+   * Set the reference to nodetest and predicate for
+   * parent or ancestor.
+   *
+   *
+   * @param expr The relative pattern expression.
+   */
+  public void setRelativePathPattern(StepPattern expr)
+  {
+
+    m_relativePathPattern = expr;
+    expr.exprSetParent(this);
+
+    calcScore();
+  }
+
+  /**
+   * Get the reference to nodetest and predicate for
+   * parent or ancestor.
+   *
+   *
+   * @return The relative pattern expression.
+   */
+  public StepPattern getRelativePathPattern()
+  {
+    return m_relativePathPattern;
+  }
+
+  //  /**
+  //   * Set the list of predicate expressions for this pattern step.
+  //   * @param predicates List of expression objects.
+  //   */
+  //  public void setPredicates(Expression[] predicates)
+  //  {
+  //    m_predicates = predicates;
+  //  }
+
+  /**
+   * Set the list of predicate expressions for this pattern step.
+   * @return List of expression objects.
+   */
+  public Expression[] getPredicates()
+  {
+    return m_predicates;
+  }
+
+  /**
+   * The list of predicate expressions for this pattern step.
+   *  @serial
+   */
+  Expression[] m_predicates;
+
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside
+   * the current subtree.
+   *
+   * NOTE: Ancestors tests with predicates are problematic, and will require
+   * special treatment.
+   *
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+  public boolean canTraverseOutsideSubtree()
+  {
+
+    int n = getPredicateCount();
+
+    for (int i = 0; i < n; i++)
+    {
+      if (getPredicate(i).canTraverseOutsideSubtree())
+        return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Get a predicate expression.
+   *
+   *
+   * @param i The index of the predicate.
+   *
+   * @return A predicate expression.
+   */
+  public Expression getPredicate(int i)
+  {
+    return m_predicates[i];
+  }
+
+  /**
+   * Get the number of predicates for this match pattern step.
+   *
+   *
+   * @return the number of predicates for this match pattern step.
+   */
+  public final int getPredicateCount()
+  {
+    return (null == m_predicates) ? 0 : m_predicates.length;
+  }
+
+  /**
+   * Set the predicates for this match pattern step.
+   *
+   *
+   * @param predicates An array of expressions that define predicates
+   *                   for this step.
+   */
+  public void setPredicates(Expression[] predicates)
+  {
+
+    m_predicates = predicates;
+    if(null != predicates)
+    {
+    	for(int i = 0; i < predicates.length; i++)
+    	{
+    		predicates[i].exprSetParent(this);
+    	}
+    }
+
+    calcScore();
+  }
+
+  /**
+   * Static calc of match score.
+   */
+  public void calcScore()
+  {
+
+    if ((getPredicateCount() > 0) || (null != m_relativePathPattern))
+    {
+      m_score = SCORE_OTHER;
+    }
+    else
+      super.calcScore();
+
+    if (null == m_targetString)
+      calcTargetString();
+  }
+
+  /**
+   * Execute this pattern step, including predicates.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   * @param currentNode The current node context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt, int currentNode)
+          throws javax.xml.transform.TransformerException
+  {
+
+    DTM dtm = xctxt.getDTM(currentNode);
+
+    if (dtm != null)
+    {
+      int expType = dtm.getExpandedTypeID(currentNode);
+
+      return execute(xctxt, currentNode, dtm, expType);
+    }
+
+    return NodeTest.SCORE_NONE;
+  }
+
+  /**
+   * Execute this pattern step, including predicates.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt)
+          throws javax.xml.transform.TransformerException
+  {
+    return execute(xctxt, xctxt.getCurrentNode());
+  }
+
+  /**
+   * Execute an expression in the XPath runtime context, and return the
+   * result of the expression.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param currentNode The currentNode.
+   * @param dtm The DTM of the current node.
+   * @param expType The expanded type ID of the current node.
+   *
+   * @return The result of the expression in the form of a <code>XObject</code>.
+   *
+   * @throws javax.xml.transform.TransformerException if a runtime exception
+   *         occurs.
+   */
+  public XObject execute(
+          XPathContext xctxt, int currentNode, DTM dtm, int expType)
+            throws javax.xml.transform.TransformerException
+  {
+
+    if (m_whatToShow == NodeTest.SHOW_BYFUNCTION)
+    {
+      if (null != m_relativePathPattern)
+      {
+        return m_relativePathPattern.execute(xctxt);
+      }
+      else
+        return NodeTest.SCORE_NONE;
+    }
+
+    XObject score;
+
+    score = super.execute(xctxt, currentNode, dtm, expType);
+
+    if (score == NodeTest.SCORE_NONE)
+      return NodeTest.SCORE_NONE;
+
+    if (getPredicateCount() != 0)
+    {
+      if (!executePredicates(xctxt, dtm, currentNode))
+        return NodeTest.SCORE_NONE;
+    }
+
+    if (null != m_relativePathPattern)
+      return m_relativePathPattern.executeRelativePathPattern(xctxt, dtm,
+              currentNode);
+
+    return score;
+  }
+
+  /**
+   * New Method to check whether the current node satisfies a position predicate
+   *
+   * @param xctxt The XPath runtime context.
+   * @param predPos Which predicate we're evaluating of foo[1][2][3].
+   * @param dtm The DTM of the current node.
+   * @param context The currentNode.
+   * @param pos The position being requested, i.e. the value returned by 
+   *            m_predicates[predPos].execute(xctxt).
+   *
+   * @return true of the position of the context matches pos, false otherwise.
+   */
+  private final boolean checkProximityPosition(XPathContext xctxt,
+          int predPos, DTM dtm, int context, int pos)
+  {
+
+    try
+    {
+      DTMAxisTraverser traverser =
+        dtm.getAxisTraverser(Axis.PRECEDINGSIBLING);
+
+      for (int child = traverser.first(context); DTM.NULL != child;
+              child = traverser.next(context, child))
+      {
+        try
+        {
+          xctxt.pushCurrentNode(child);
+
+          if (NodeTest.SCORE_NONE != super.execute(xctxt, child))
+          {
+            boolean pass = true;
+
+            try
+            {
+              xctxt.pushSubContextList(this);
+
+              for (int i = 0; i < predPos; i++)
+              {
+                xctxt.pushPredicatePos(i);
+                try
+                {
+                  XObject pred = m_predicates[i].execute(xctxt);
+                  
+                  try
+                  {
+                    if (XObject.CLASS_NUMBER == pred.getType())
+                    {
+                      throw new Error("Why: Should never have been called");
+                    }
+                    else if (!pred.boolWithSideEffects())
+                    {
+                      pass = false;
+    
+                      break;
+                    }
+                  }
+                  finally
+                  {
+                    pred.detach();
+                  }
+                }
+                finally
+                {
+                  xctxt.popPredicatePos();
+                }
+              }
+            }
+            finally
+            {
+              xctxt.popSubContextList();
+            }
+
+            if (pass)
+              pos--;
+
+            if (pos < 1)
+              return false;
+          }
+        }
+        finally
+        {
+          xctxt.popCurrentNode();
+        }
+      }
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: should keep throw sax exception...
+      throw new java.lang.RuntimeException(se.getMessage());
+    }
+
+    return (pos == 1);
+  }
+
+  /**
+   * Get the proximity position index of the current node based on this
+   * node test.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   * @param predPos Which predicate we're evaluating of foo[1][2][3].
+   * @param findLast If true, don't terminate when the context node is found.
+   *
+   * @return the proximity position index of the current node based on the
+   *         node test.
+   */
+  private final int getProximityPosition(XPathContext xctxt, int predPos, 
+                    boolean findLast)
+  {
+
+    int pos = 0;
+    int context = xctxt.getCurrentNode();
+    DTM dtm = xctxt.getDTM(context);
+    int parent = dtm.getParent(context);
+
+    try
+    {
+      DTMAxisTraverser traverser = dtm.getAxisTraverser(Axis.CHILD);
+
+      for (int child = traverser.first(parent); DTM.NULL != child;
+              child = traverser.next(parent, child))
+      {
+        try
+        {
+          xctxt.pushCurrentNode(child);
+
+          if (NodeTest.SCORE_NONE != super.execute(xctxt, child))
+          {
+            boolean pass = true;
+
+            try
+            {
+              xctxt.pushSubContextList(this);
+
+              for (int i = 0; i < predPos; i++)
+              {
+                xctxt.pushPredicatePos(i);
+                try
+                {
+                  XObject pred = m_predicates[i].execute(xctxt);
+  
+                  try
+                  {
+                    if (XObject.CLASS_NUMBER == pred.getType())
+                    {
+                      if ((pos + 1) != (int) pred.numWithSideEffects())
+                      {
+                        pass = false;
+    
+                        break;
+                      }
+                    }
+                    else if (!pred.boolWithSideEffects())
+                    {
+                      pass = false;
+    
+                      break;
+                    }
+                  }
+                  finally
+                  {
+                    pred.detach();
+                  }
+                }
+                finally
+                {
+                  xctxt.popPredicatePos();
+                }
+              }
+            }
+            finally
+            {
+              xctxt.popSubContextList();
+            }
+
+            if (pass)
+              pos++;
+
+            if (!findLast && child == context)
+            {
+              return pos;
+            }
+          }
+        }
+        finally
+        {
+          xctxt.popCurrentNode();
+        }
+      }
+    }
+    catch (javax.xml.transform.TransformerException se)
+    {
+
+      // TODO: should keep throw sax exception...
+      throw new java.lang.RuntimeException(se.getMessage());
+    }
+
+    return pos;
+  }
+
+  /**
+   * Get the proximity position index of the current node based on this
+   * node test.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the proximity position index of the current node based on the
+   *         node test.
+   */
+  public int getProximityPosition(XPathContext xctxt)
+  {
+    return getProximityPosition(xctxt, xctxt.getPredicatePos(), false);
+  }
+  
+  /**
+   * Get the count of the nodes that match the test, which is the proximity
+   * position of the last node that can pass this test in the sub context
+   * selection.  In XSLT 1-based indexing, this count is the index of the last
+   * node.
+   *
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return the count of the nodes that match the test.
+   */
+  public int getLastPos(XPathContext xctxt)
+  {
+    return getProximityPosition(xctxt, xctxt.getPredicatePos(), true);
+  }
+
+  /**
+   * Execute the match pattern step relative to another step.
+   *
+   *
+   * @param xctxt The XPath runtime context.
+   * @param dtm The DTM of the current node.
+   * @param currentNode The current node context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected final XObject executeRelativePathPattern(
+          XPathContext xctxt, DTM dtm, int currentNode)
+            throws javax.xml.transform.TransformerException
+  {
+
+    XObject score = NodeTest.SCORE_NONE;
+    int context = currentNode;
+    DTMAxisTraverser traverser;
+
+    traverser = dtm.getAxisTraverser(m_axis);
+
+    for (int relative = traverser.first(context); DTM.NULL != relative;
+            relative = traverser.next(context, relative))
+    {
+      try
+      {
+        xctxt.pushCurrentNode(relative);
+
+        score = execute(xctxt);
+
+        if (score != NodeTest.SCORE_NONE)
+          break;
+      }
+      finally
+      {
+        xctxt.popCurrentNode();
+      }
+    }
+
+    return score;
+  }
+
+  /**
+   * Execute the predicates on this step to determine if the current node 
+   * should be filtered or accepted.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param dtm The DTM of the current node.
+   * @param currentNode The current node context.
+   *
+   * @return true if the node should be accepted, false otherwise.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  protected final boolean executePredicates(
+          XPathContext xctxt, DTM dtm, int currentNode)
+            throws javax.xml.transform.TransformerException
+  {
+
+    boolean result = true;
+    boolean positionAlreadySeen = false;
+    int n = getPredicateCount();
+
+    try
+    {
+      xctxt.pushSubContextList(this);
+
+      for (int i = 0; i < n; i++)
+      {
+        xctxt.pushPredicatePos(i);
+
+        try
+        {
+          XObject pred = m_predicates[i].execute(xctxt);
+
+          try
+          {
+            if (XObject.CLASS_NUMBER == pred.getType())
+            {
+              int pos = (int) pred.num();
+  
+              if (positionAlreadySeen)
+              {
+                result = (pos == 1);
+  
+                break;
+              }
+              else
+              {
+                positionAlreadySeen = true;
+  
+                if (!checkProximityPosition(xctxt, i, dtm, currentNode, pos))
+                {
+                  result = false;
+  
+                  break;
+                }
+              }
+            
+            }
+            else if (!pred.boolWithSideEffects())
+            {
+              result = false;
+  
+              break;
+            }
+          }
+          finally
+          {
+            pred.detach();
+          }
+        }
+        finally
+        {
+          xctxt.popPredicatePos();
+        }
+      }
+    }
+    finally
+    {
+      xctxt.popSubContextList();
+    }
+
+    return result;
+  }
+
+  /**
+   * Get the string represenentation of this step for diagnostic purposes.
+   *
+   *
+   * @return A string representation of this step, built by reverse-engineering 
+   * the contained info.
+   */
+  public String toString()
+  {
+
+    StringBuffer buf = new StringBuffer();
+
+    for (StepPattern pat = this; pat != null; pat = pat.m_relativePathPattern)
+    {
+      if (pat != this)
+        buf.append("/");
+
+      buf.append(Axis.getNames(pat.m_axis));
+      buf.append("::");
+
+      if (0x000005000 == pat.m_whatToShow)
+      {
+        buf.append("doc()");
+      }
+      else if (DTMFilter.SHOW_BYFUNCTION == pat.m_whatToShow)
+      {
+        buf.append("function()");
+      }
+      else if (DTMFilter.SHOW_ALL == pat.m_whatToShow)
+      {
+        buf.append("node()");
+      }
+      else if (DTMFilter.SHOW_TEXT == pat.m_whatToShow)
+      {
+        buf.append("text()");
+      }
+      else if (DTMFilter.SHOW_PROCESSING_INSTRUCTION == pat.m_whatToShow)
+      {
+        buf.append("processing-instruction(");
+
+        if (null != pat.m_name)
+        {
+          buf.append(pat.m_name);
+        }
+
+        buf.append(")");
+      }
+      else if (DTMFilter.SHOW_COMMENT == pat.m_whatToShow)
+      {
+        buf.append("comment()");
+      }
+      else if (null != pat.m_name)
+      {
+        if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow)
+        {
+          buf.append("@");
+        }
+
+        if (null != pat.m_namespace)
+        {
+          buf.append("{");
+          buf.append(pat.m_namespace);
+          buf.append("}");
+        }
+
+        buf.append(pat.m_name);
+      }
+      else if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow)
+      {
+        buf.append("@");
+      }
+      else if ((DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT)
+               == pat.m_whatToShow)
+      {
+        buf.append("doc-root()");
+      }
+      else
+      {
+        buf.append("?" + Integer.toHexString(pat.m_whatToShow));
+      }
+
+      if (null != pat.m_predicates)
+      {
+        for (int i = 0; i < pat.m_predicates.length; i++)
+        {
+          buf.append("[");
+          buf.append(pat.m_predicates[i]);
+          buf.append("]");
+        }
+      }
+    }
+
+    return buf.toString();
+  }
+
+  /** Set to true to send diagnostics about pattern matches to the consol. */
+  private static final boolean DEBUG_MATCHES = false;
+
+  /**
+   * Get the match score of the given node.
+   *
+   * @param xctxt The XPath runtime context.
+   * @param context The node to be tested.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public double getMatchScore(XPathContext xctxt, int context)
+          throws javax.xml.transform.TransformerException
+  {
+
+    xctxt.pushCurrentNode(context);
+    xctxt.pushCurrentExpressionNode(context);
+
+    try
+    {
+      XObject score = execute(xctxt);
+
+      return score.num();
+    }
+    finally
+    {
+      xctxt.popCurrentNode();
+      xctxt.popCurrentExpressionNode();
+    }
+
+    // return XPath.MATCH_SCORE_NONE;
+  }
+
+  /**
+   * Set the axis that this step should follow. 
+   *
+   *
+   * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
+   */
+  public void setAxis(int axis)
+  {
+    m_axis = axis;
+  }
+
+  /**
+   * Get the axis that this step follows. 
+   *
+   *
+   * @return The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
+   */
+  public int getAxis()
+  {
+    return m_axis;
+  }
+  
+  class PredOwner implements ExpressionOwner
+  {
+  	int m_index;
+  	
+  	PredOwner(int index)
+  	{
+  		m_index = index;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_predicates[m_index];
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(StepPattern.this);
+    	m_predicates[m_index] = exp;
+    }
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	 	if(visitor.visitMatchPattern(owner, this))
+  	 	{
+  	 		callSubtreeVisitors(visitor);
+  	 	}
+  }
+
+  /**
+   * Call the visitors on the subtree.  Factored out from callVisitors 
+   * so it may be called by derived classes.
+   */
+  protected void callSubtreeVisitors(XPathVisitor visitor)
+  {
+    if (null != m_predicates)
+    {
+      int n = m_predicates.length;
+      for (int i = 0; i < n; i++)
+      {
+        ExpressionOwner predOwner = new PredOwner(i);
+        if (visitor.visitPredicate(predOwner, m_predicates[i]))
+        {
+          m_predicates[i].callVisitors(predOwner, visitor);
+        }
+      }
+    }
+    if (null != m_relativePathPattern)
+    {
+      m_relativePathPattern.callVisitors(this, visitor);
+    }
+  }
+
+
+  /**
+   * @see ExpressionOwner#getExpression()
+   */
+  public Expression getExpression()
+  {
+    return m_relativePathPattern;
+  }
+
+  /**
+   * @see ExpressionOwner#setExpression(Expression)
+   */
+  public void setExpression(Expression exp)
+  {
+    exp.exprSetParent(this);
+  	m_relativePathPattern = (StepPattern)exp;
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!super.deepEquals(expr))
+  		return false;
+  		
+  	StepPattern sp = (StepPattern)expr;
+  	
+    if (null != m_predicates)
+    {
+        int n = m_predicates.length;
+        if ((null == sp.m_predicates) || (sp.m_predicates.length != n))
+              return false;
+        for (int i = 0; i < n; i++)
+        {
+          if (!m_predicates[i].deepEquals(sp.m_predicates[i]))
+          	return false; 
+        }
+    }
+    else if (null != sp.m_predicates)
+    	return false;
+  		
+  	if(null != m_relativePathPattern)
+  	{
+  		if(!m_relativePathPattern.deepEquals(sp.m_relativePathPattern))
+  			return false;
+  	}
+  	else if(sp.m_relativePathPattern != null)
+  		return false;
+  		
+  	return true;
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/patterns/UnionPattern.java b/src/main/java/org/apache/xpath/patterns/UnionPattern.java
new file mode 100644
index 0000000..a06d095
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/UnionPattern.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: UnionPattern.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.patterns;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * This class represents a union pattern, which can have multiple individual 
+ * StepPattern patterns.
+ * @xsl.usage advanced
+ */
+public class UnionPattern extends Expression
+{
+    static final long serialVersionUID = -6670449967116905820L;
+
+  /** Array of the contained step patterns to be tested.
+   *  @serial  */
+  private StepPattern[] m_patterns;
+  
+  /**
+   * No arguments to process, so this does nothing.
+   */
+  public void fixupVariables(java.util.Vector vars, int globalsSize)
+  {
+    for (int i = 0; i < m_patterns.length; i++) 
+    {
+      m_patterns[i].fixupVariables(vars, globalsSize);
+    }
+  }
+
+  
+  /**
+   * Tell if this expression or it's subexpressions can traverse outside 
+   * the current subtree.
+   * 
+   * @return true if traversal outside the context node's subtree can occur.
+   */
+   public boolean canTraverseOutsideSubtree()
+   {
+     if(null != m_patterns)
+     {
+      int n = m_patterns.length;
+      for (int i = 0; i < n; i++) 
+      {
+        if(m_patterns[i].canTraverseOutsideSubtree())
+          return true;
+      }
+     }
+     return false;
+   }
+
+  /**
+   * Set the contained step patterns to be tested. 
+   *
+   *
+   * @param patterns the contained step patterns to be tested. 
+   */
+  public void setPatterns(StepPattern[] patterns)
+  {
+    m_patterns = patterns;
+    if(null != patterns)
+    {
+    	for(int i = 0; i < patterns.length; i++)
+    	{
+    		patterns[i].exprSetParent(this);
+    	}
+    }
+    
+  }
+
+  /**
+   * Get the contained step patterns to be tested. 
+   *
+   *
+   * @return an array of the contained step patterns to be tested. 
+   */
+  public StepPattern[] getPatterns()
+  {
+    return m_patterns;
+  }
+
+  /**
+   * Test a node to see if it matches any of the patterns in the union.
+   *
+   * @param xctxt XPath runtime context.
+   *
+   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
+   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {
+
+    XObject bestScore = null;
+    int n = m_patterns.length;
+
+    for (int i = 0; i < n; i++)
+    {
+      XObject score = m_patterns[i].execute(xctxt);
+
+      if (score != NodeTest.SCORE_NONE)
+      {
+        if (null == bestScore)
+          bestScore = score;
+        else if (score.num() > bestScore.num())
+          bestScore = score;
+      }
+    }
+
+    if (null == bestScore)
+    {
+      bestScore = NodeTest.SCORE_NONE;
+    }
+
+    return bestScore;
+  }
+  
+  class UnionPathPartOwner implements ExpressionOwner
+  {
+  	int m_index;
+  	
+  	UnionPathPartOwner(int index)
+  	{
+  		m_index = index;
+  	}
+  	
+    /**
+     * @see ExpressionOwner#getExpression()
+     */
+    public Expression getExpression()
+    {
+      return m_patterns[m_index];
+    }
+
+
+    /**
+     * @see ExpressionOwner#setExpression(Expression)
+     */
+    public void setExpression(Expression exp)
+    {
+    	exp.exprSetParent(UnionPattern.this);
+    	m_patterns[m_index] = (StepPattern)exp;
+    }
+  }
+  
+  /**
+   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
+   */
+  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
+  {
+  	visitor.visitUnionPattern(owner, this);
+  	if(null != m_patterns)
+  	{
+  		int n = m_patterns.length;
+  		for(int i = 0; i < n; i++)
+  		{
+  			m_patterns[i].callVisitors(new UnionPathPartOwner(i), visitor);
+  		}
+  	}
+  }
+  
+  /**
+   * @see Expression#deepEquals(Expression)
+   */
+  public boolean deepEquals(Expression expr)
+  {
+  	if(!isSameClass(expr))
+  		return false;
+  		
+  	UnionPattern up = (UnionPattern)expr;
+  		
+  	if(null != m_patterns)
+  	{
+  		int n = m_patterns.length;
+  		if((null == up.m_patterns) || (up.m_patterns.length != n))
+  			return false;
+  			
+  		for(int i = 0; i < n; i++)
+  		{
+  			if(!m_patterns[i].deepEquals(up.m_patterns[i]))
+  				return false;
+  		}
+  	}
+  	else if(up.m_patterns != null)
+  		return false;
+  		
+  	return true;
+  	
+  }
+
+
+}
diff --git a/src/main/java/org/apache/xpath/patterns/package.html b/src/main/java/org/apache/xpath/patterns/package.html
new file mode 100644
index 0000000..12db9e4
--- /dev/null
+++ b/src/main/java/org/apache/xpath/patterns/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath nodetest and XSLT pattern matching support.</title>
+  <body>
+    <p>Implementation of XPath nodeTest support, and XSLT pattern matching support.<p>
+ </body>
+</html>
+
+
diff --git a/src/main/java/org/apache/xpath/res/XPATHErrorResources.java b/src/main/java/org/apache/xpath/res/XPATHErrorResources.java
new file mode 100644
index 0000000..6c6120f
--- /dev/null
+++ b/src/main/java/org/apache/xpath/res/XPATHErrorResources.java
@@ -0,0 +1,999 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPATHErrorResources.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.res;
+
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Set up error messages.
+ * We build a two dimensional array of message keys and
+ * message strings. In order to add a new message here,
+ * you need to first add a Static string constant for the
+ * Key and update the contents array with Key, Value pair
+  * Also you need to  update the count of messages(MAX_CODE)or
+ * the count of warnings(MAX_WARNING) [ Information purpose only]
+ * @xsl.usage advanced
+ */
+public class XPATHErrorResources extends ListResourceBundle
+{
+
+/*
+ * General notes to translators:
+ *
+ * This file contains error and warning messages related to XPath Error
+ * Handling.
+ *
+ *  1) Xalan (or more properly, Xalan-interpretive) and XSLTC are names of
+ *     components.
+ *     XSLT is an acronym for "XML Stylesheet Language: Transformations".
+ *     XSLTC is an acronym for XSLT Compiler.
+ *
+ *  2) A stylesheet is a description of how to transform an input XML document
+ *     into a resultant XML document (or HTML document or text).  The
+ *     stylesheet itself is described in the form of an XML document.
+ *
+ *  3) A template is a component of a stylesheet that is used to match a
+ *     particular portion of an input document and specifies the form of the
+ *     corresponding portion of the output document.
+ *
+ *  4) An element is a mark-up tag in an XML document; an attribute is a
+ *     modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
+ *     "elem" is an element name, "attr" and "attr2" are attribute names with
+ *     the values "val" and "val2", respectively.
+ *
+ *  5) A namespace declaration is a special attribute that is used to associate
+ *     a prefix with a URI (the namespace).  The meanings of element names and
+ *     attribute names that use that prefix are defined with respect to that
+ *     namespace.
+ *
+ *  6) "Translet" is an invented term that describes the class file that
+ *     results from compiling an XML stylesheet into a Java class.
+ *
+ *  7) XPath is a specification that describes a notation for identifying
+ *     nodes in a tree-structured representation of an XML document.  An
+ *     instance of that notation is referred to as an XPath expression.
+ *
+ *  8) The context node is the node in the document with respect to which an
+ *     XPath expression is being evaluated.
+ *
+ *  9) An iterator is an object that traverses nodes in the tree, one at a time.
+ *
+ *  10) NCName is an XML term used to describe a name that does not contain a
+ *     colon (a "no-colon name").
+ *
+ *  11) QName is an XML term meaning "qualified name".
+ */
+
+  /* 
+   * static variables
+   */
+  public static final String ERROR0000 = "ERROR0000";
+  public static final String ER_CURRENT_NOT_ALLOWED_IN_MATCH = 
+	 "ER_CURRENT_NOT_ALLOWED_IN_MATCH";
+  public static final String ER_CURRENT_TAKES_NO_ARGS = 
+	 "ER_CURRENT_TAKES_NO_ARGS";
+  public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_HAS_NO_OWNERDOC = 
+	 "ER_CONTEXT_HAS_NO_OWNERDOC";
+  public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS = 
+	 "ER_LOCALNAME_HAS_TOO_MANY_ARGS";
+  public static final String ER_NAMESPACEURI_HAS_TOO_MANY_ARGS = 
+	 "ER_NAMESPACEURI_HAS_TOO_MANY_ARGS";
+  public static final String ER_NORMALIZESPACE_HAS_TOO_MANY_ARGS = 
+	 "ER_NORMALIZESPACE_HAS_TOO_MANY_ARGS";
+  public static final String ER_NUMBER_HAS_TOO_MANY_ARGS = 
+	 "ER_NUMBER_HAS_TOO_MANY_ARGS";
+  public static final String ER_NAME_HAS_TOO_MANY_ARGS = 
+	 "ER_NAME_HAS_TOO_MANY_ARGS";
+  public static final String ER_STRING_HAS_TOO_MANY_ARGS = 
+	 "ER_STRING_HAS_TOO_MANY_ARGS";
+  public static final String ER_STRINGLENGTH_HAS_TOO_MANY_ARGS = 
+	 "ER_STRINGLENGTH_HAS_TOO_MANY_ARGS";
+  public static final String ER_TRANSLATE_TAKES_3_ARGS = 
+	 "ER_TRANSLATE_TAKES_3_ARGS";
+  public static final String ER_UNPARSEDENTITYURI_TAKES_1_ARG = 
+	 "ER_UNPARSEDENTITYURI_TAKES_1_ARG";
+  public static final String ER_NAMESPACEAXIS_NOT_IMPLEMENTED = 
+	 "ER_NAMESPACEAXIS_NOT_IMPLEMENTED";
+  public static final String ER_UNKNOWN_AXIS = "ER_UNKNOWN_AXIS";
+  public static final String ER_UNKNOWN_MATCH_OPERATION = 
+	 "ER_UNKNOWN_MATCH_OPERATION";
+  public static final String ER_INCORRECT_ARG_LENGTH ="ER_INCORRECT_ARG_LENGTH";
+  public static final String ER_CANT_CONVERT_TO_NUMBER = 
+	 "ER_CANT_CONVERT_TO_NUMBER";
+  public static final String ER_CANT_CONVERT_XPATHRESULTTYPE_TO_NUMBER = 
+	   "ER_CANT_CONVERT_XPATHRESULTTYPE_TO_NUMBER";	 
+  public static final String ER_CANT_CONVERT_TO_NODELIST = 
+	 "ER_CANT_CONVERT_TO_NODELIST";
+  public static final String ER_CANT_CONVERT_TO_MUTABLENODELIST = 
+	 "ER_CANT_CONVERT_TO_MUTABLENODELIST";
+  public static final String ER_CANT_CONVERT_TO_TYPE ="ER_CANT_CONVERT_TO_TYPE";
+  public static final String ER_EXPECTED_MATCH_PATTERN = 
+	 "ER_EXPECTED_MATCH_PATTERN";
+  public static final String ER_COULDNOT_GET_VAR_NAMED = 
+	 "ER_COULDNOT_GET_VAR_NAMED";
+  public static final String ER_UNKNOWN_OPCODE = "ER_UNKNOWN_OPCODE";
+  public static final String ER_EXTRA_ILLEGAL_TOKENS ="ER_EXTRA_ILLEGAL_TOKENS";
+  public static final String ER_EXPECTED_DOUBLE_QUOTE = 
+	 "ER_EXPECTED_DOUBLE_QUOTE";
+  public static final String ER_EXPECTED_SINGLE_QUOTE = 
+	 "ER_EXPECTED_SINGLE_QUOTE";
+  public static final String ER_EMPTY_EXPRESSION = "ER_EMPTY_EXPRESSION";
+  public static final String ER_EXPECTED_BUT_FOUND = "ER_EXPECTED_BUT_FOUND";
+  public static final String ER_INCORRECT_PROGRAMMER_ASSERTION = 
+	 "ER_INCORRECT_PROGRAMMER_ASSERTION";
+  public static final String ER_BOOLEAN_ARG_NO_LONGER_OPTIONAL = 
+	 "ER_BOOLEAN_ARG_NO_LONGER_OPTIONAL";
+  public static final String ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG = 
+	 "ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG";
+  public static final String ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG = 
+	 "ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG";
+  public static final String ER_PREDICATE_ILLEGAL_SYNTAX = 
+	 "ER_PREDICATE_ILLEGAL_SYNTAX";
+  public static final String ER_ILLEGAL_AXIS_NAME = "ER_ILLEGAL_AXIS_NAME";
+  public static final String ER_UNKNOWN_NODETYPE = "ER_UNKNOWN_NODETYPE";
+  public static final String ER_PATTERN_LITERAL_NEEDS_BE_QUOTED = 
+	 "ER_PATTERN_LITERAL_NEEDS_BE_QUOTED";
+  public static final String ER_COULDNOT_BE_FORMATTED_TO_NUMBER = 
+	 "ER_COULDNOT_BE_FORMATTED_TO_NUMBER";
+  public static final String ER_COULDNOT_CREATE_XMLPROCESSORLIAISON = 
+	 "ER_COULDNOT_CREATE_XMLPROCESSORLIAISON";
+  public static final String ER_DIDNOT_FIND_XPATH_SELECT_EXP = 
+	 "ER_DIDNOT_FIND_XPATH_SELECT_EXP";
+  public static final String ER_COULDNOT_FIND_ENDOP_AFTER_OPLOCATIONPATH = 
+	 "ER_COULDNOT_FIND_ENDOP_AFTER_OPLOCATIONPATH";
+  public static final String ER_ERROR_OCCURED = "ER_ERROR_OCCURED";
+  public static final String ER_ILLEGAL_VARIABLE_REFERENCE = 
+	 "ER_ILLEGAL_VARIABLE_REFERENCE";
+  public static final String ER_AXES_NOT_ALLOWED = "ER_AXES_NOT_ALLOWED";
+  public static final String ER_KEY_HAS_TOO_MANY_ARGS = 
+	 "ER_KEY_HAS_TOO_MANY_ARGS";
+  public static final String ER_COUNT_TAKES_1_ARG = "ER_COUNT_TAKES_1_ARG";
+  public static final String ER_COULDNOT_FIND_FUNCTION = 
+	 "ER_COULDNOT_FIND_FUNCTION";
+  public static final String ER_UNSUPPORTED_ENCODING ="ER_UNSUPPORTED_ENCODING";
+  public static final String ER_PROBLEM_IN_DTM_NEXTSIBLING = 
+	 "ER_PROBLEM_IN_DTM_NEXTSIBLING";
+  public static final String ER_CANNOT_WRITE_TO_EMPTYNODELISTIMPL = 
+	 "ER_CANNOT_WRITE_TO_EMPTYNODELISTIMPL";
+  public static final String ER_SETDOMFACTORY_NOT_SUPPORTED = 
+	 "ER_SETDOMFACTORY_NOT_SUPPORTED";
+  public static final String ER_PREFIX_MUST_RESOLVE = "ER_PREFIX_MUST_RESOLVE";
+  public static final String ER_PARSE_NOT_SUPPORTED = "ER_PARSE_NOT_SUPPORTED";
+  public static final String ER_SAX_API_NOT_HANDLED = "ER_SAX_API_NOT_HANDLED";
+public static final String ER_IGNORABLE_WHITESPACE_NOT_HANDLED = 
+	 "ER_IGNORABLE_WHITESPACE_NOT_HANDLED";
+  public static final String ER_DTM_CANNOT_HANDLE_NODES = 
+	 "ER_DTM_CANNOT_HANDLE_NODES";
+  public static final String ER_XERCES_CANNOT_HANDLE_NODES = 
+	 "ER_XERCES_CANNOT_HANDLE_NODES";
+  public static final String ER_XERCES_PARSE_ERROR_DETAILS = 
+	 "ER_XERCES_PARSE_ERROR_DETAILS";
+  public static final String ER_XERCES_PARSE_ERROR = "ER_XERCES_PARSE_ERROR";
+  public static final String ER_INVALID_UTF16_SURROGATE = 
+	 "ER_INVALID_UTF16_SURROGATE";
+  public static final String ER_OIERROR = "ER_OIERROR";
+  public static final String ER_CANNOT_CREATE_URL = "ER_CANNOT_CREATE_URL";
+  public static final String ER_XPATH_READOBJECT = "ER_XPATH_READOBJECT";
+ public static final String ER_FUNCTION_TOKEN_NOT_FOUND = 
+	 "ER_FUNCTION_TOKEN_NOT_FOUND";
+  public static final String ER_CANNOT_DEAL_XPATH_TYPE = 
+	 "ER_CANNOT_DEAL_XPATH_TYPE";
+  public static final String ER_NODESET_NOT_MUTABLE = "ER_NODESET_NOT_MUTABLE";
+  public static final String ER_NODESETDTM_NOT_MUTABLE = 
+	 "ER_NODESETDTM_NOT_MUTABLE";
+   /**  Variable not resolvable:   */
+  public static final String ER_VAR_NOT_RESOLVABLE = "ER_VAR_NOT_RESOLVABLE";
+   /** Null error handler  */
+ public static final String ER_NULL_ERROR_HANDLER = "ER_NULL_ERROR_HANDLER";
+   /**  Programmer's assertion: unknown opcode  */
+  public static final String ER_PROG_ASSERT_UNKNOWN_OPCODE = 
+	 "ER_PROG_ASSERT_UNKNOWN_OPCODE";
+   /**  0 or 1   */
+  public static final String ER_ZERO_OR_ONE = "ER_ZERO_OR_ONE";
+   /**  rtf() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER = 
+	 "ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+   /**  asNodeIterator() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_ASNODEITERATOR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER = "ER_ASNODEITERATOR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+   /**  fsb() not supported for XStringForChars   */
+  public static final String ER_FSB_NOT_SUPPORTED_XSTRINGFORCHARS = 
+	 "ER_FSB_NOT_SUPPORTED_XSTRINGFORCHARS";
+   /**  Could not find variable with the name of   */
+ public static final String ER_COULD_NOT_FIND_VAR = "ER_COULD_NOT_FIND_VAR";
+   /**  XStringForChars can not take a string for an argument   */
+ public static final String ER_XSTRINGFORCHARS_CANNOT_TAKE_STRING = 
+	 "ER_XSTRINGFORCHARS_CANNOT_TAKE_STRING";
+   /**  The FastStringBuffer argument can not be null   */
+ public static final String ER_FASTSTRINGBUFFER_CANNOT_BE_NULL = 
+	 "ER_FASTSTRINGBUFFER_CANNOT_BE_NULL";
+   /**  2 or 3   */
+  public static final String ER_TWO_OR_THREE = "ER_TWO_OR_THREE";
+   /** Variable accessed before it is bound! */
+  public static final String ER_VARIABLE_ACCESSED_BEFORE_BIND = 
+	 "ER_VARIABLE_ACCESSED_BEFORE_BIND";
+   /** XStringForFSB can not take a string for an argument! */
+ public static final String ER_FSB_CANNOT_TAKE_STRING = 
+	 "ER_FSB_CANNOT_TAKE_STRING";
+   /** Error! Setting the root of a walker to null! */
+  public static final String ER_SETTING_WALKER_ROOT_TO_NULL = 
+	 "ER_SETTING_WALKER_ROOT_TO_NULL";
+   /** This NodeSetDTM can not iterate to a previous node! */
+  public static final String ER_NODESETDTM_CANNOT_ITERATE = 
+	 "ER_NODESETDTM_CANNOT_ITERATE";
+  /** This NodeSet can not iterate to a previous node! */
+ public static final String ER_NODESET_CANNOT_ITERATE = 
+	 "ER_NODESET_CANNOT_ITERATE";
+  /** This NodeSetDTM can not do indexing or counting functions! */
+  public static final String ER_NODESETDTM_CANNOT_INDEX = 
+	 "ER_NODESETDTM_CANNOT_INDEX";
+  /** This NodeSet can not do indexing or counting functions! */
+  public static final String ER_NODESET_CANNOT_INDEX = 
+	 "ER_NODESET_CANNOT_INDEX";
+  /** Can not call setShouldCacheNodes after nextNode has been called! */
+  public static final String ER_CANNOT_CALL_SETSHOULDCACHENODE = 
+	 "ER_CANNOT_CALL_SETSHOULDCACHENODE";
+  /** {0} only allows {1} arguments */
+ public static final String ER_ONLY_ALLOWS = "ER_ONLY_ALLOWS";
+  /** Programmer's assertion in getNextStepPos: unknown stepType: {0} */
+  public static final String ER_UNKNOWN_STEP = "ER_UNKNOWN_STEP";
+  /** Problem with RelativeLocationPath */
+  public static final String ER_EXPECTED_REL_LOC_PATH = 
+	 "ER_EXPECTED_REL_LOC_PATH";
+  /** Problem with LocationPath */
+  public static final String ER_EXPECTED_LOC_PATH = "ER_EXPECTED_LOC_PATH";
+  public static final String ER_EXPECTED_LOC_PATH_AT_END_EXPR =
+                                        "ER_EXPECTED_LOC_PATH_AT_END_EXPR";
+  /** Problem with Step */
+  public static final String ER_EXPECTED_LOC_STEP = "ER_EXPECTED_LOC_STEP";
+  /** Problem with NodeTest */
+  public static final String ER_EXPECTED_NODE_TEST = "ER_EXPECTED_NODE_TEST";
+  /** Expected step pattern */
+  public static final String ER_EXPECTED_STEP_PATTERN = 
+	"ER_EXPECTED_STEP_PATTERN";
+  /** Expected relative path pattern */
+  public static final String ER_EXPECTED_REL_PATH_PATTERN = 
+	 "ER_EXPECTED_REL_PATH_PATTERN";
+  /** ER_CANT_CONVERT_XPATHRESULTTYPE_TO_BOOLEAN          */
+  public static final String ER_CANT_CONVERT_TO_BOOLEAN = 
+	 "ER_CANT_CONVERT_TO_BOOLEAN";
+  /** Field ER_CANT_CONVERT_TO_SINGLENODE       */
+  public static final String ER_CANT_CONVERT_TO_SINGLENODE = 
+	 "ER_CANT_CONVERT_TO_SINGLENODE";
+  /** Field ER_CANT_GET_SNAPSHOT_LENGTH         */
+  public static final String ER_CANT_GET_SNAPSHOT_LENGTH = 
+	 "ER_CANT_GET_SNAPSHOT_LENGTH";
+  /** Field ER_NON_ITERATOR_TYPE                */
+  public static final String ER_NON_ITERATOR_TYPE = "ER_NON_ITERATOR_TYPE";
+  /** Field ER_DOC_MUTATED                      */
+  public static final String ER_DOC_MUTATED = "ER_DOC_MUTATED";
+  public static final String ER_INVALID_XPATH_TYPE = "ER_INVALID_XPATH_TYPE";
+  public static final String ER_EMPTY_XPATH_RESULT = "ER_EMPTY_XPATH_RESULT";
+  public static final String ER_INCOMPATIBLE_TYPES = "ER_INCOMPATIBLE_TYPES";
+  public static final String ER_NULL_RESOLVER = "ER_NULL_RESOLVER";
+  public static final String ER_CANT_CONVERT_TO_STRING = 
+	 "ER_CANT_CONVERT_TO_STRING";
+  public static final String ER_NON_SNAPSHOT_TYPE = "ER_NON_SNAPSHOT_TYPE";
+  public static final String ER_WRONG_DOCUMENT = "ER_WRONG_DOCUMENT";
+  /* Note to translators:  The XPath expression cannot be evaluated with respect
+   * to this type of node.
+   */
+  /** Field ER_WRONG_NODETYPE                    */
+  public static final String ER_WRONG_NODETYPE = "ER_WRONG_NODETYPE";
+  public static final String ER_XPATH_ERROR = "ER_XPATH_ERROR";
+
+  //BEGIN: Keys needed for exception messages of  JAXP 1.3 XPath API implementation
+  public static final String ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED = "ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED";
+  public static final String ER_RESOLVE_VARIABLE_RETURNS_NULL = "ER_RESOLVE_VARIABLE_RETURNS_NULL";
+  public static final String ER_UNSUPPORTED_RETURN_TYPE = "ER_UNSUPPORTED_RETURN_TYPE";
+  public static final String ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL = "ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL";
+  public static final String ER_ARG_CANNOT_BE_NULL = "ER_ARG_CANNOT_BE_NULL";
+
+  public static final String ER_OBJECT_MODEL_NULL = "ER_OBJECT_MODEL_NULL";
+  public static final String ER_OBJECT_MODEL_EMPTY = "ER_OBJECT_MODEL_EMPTY";
+  public static final String ER_FEATURE_NAME_NULL = "ER_FEATURE_NAME_NULL";
+  public static final String ER_FEATURE_UNKNOWN = "ER_FEATURE_UNKNOWN";
+  public static final String ER_GETTING_NULL_FEATURE = "ER_GETTING_NULL_FEATURE";
+  public static final String ER_GETTING_UNKNOWN_FEATURE = "ER_GETTING_UNKNOWN_FEATURE";
+  public static final String ER_NULL_XPATH_FUNCTION_RESOLVER = "ER_NULL_XPATH_FUNCTION_RESOLVER";
+  public static final String ER_NULL_XPATH_VARIABLE_RESOLVER = "ER_NULL_XPATH_VARIABLE_RESOLVER";
+  //END: Keys needed for exception messages of  JAXP 1.3 XPath API implementation 
+
+  public static final String WG_LOCALE_NAME_NOT_HANDLED = 
+	 "WG_LOCALE_NAME_NOT_HANDLED";
+  public static final String WG_PROPERTY_NOT_SUPPORTED = 
+	 "WG_PROPERTY_NOT_SUPPORTED";
+  public static final String WG_DONT_DO_ANYTHING_WITH_NS = 
+	 "WG_DONT_DO_ANYTHING_WITH_NS";
+  public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION";
+  public static final String WG_QUO_NO_LONGER_DEFINED = 
+	 "WG_QUO_NO_LONGER_DEFINED";
+  public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = 
+	 "WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST";
+  public static final String WG_FUNCTION_TOKEN_NOT_FOUND = 
+	 "WG_FUNCTION_TOKEN_NOT_FOUND";
+  public static final String WG_COULDNOT_FIND_FUNCTION = 
+	 "WG_COULDNOT_FIND_FUNCTION";
+  public static final String WG_CANNOT_MAKE_URL_FROM ="WG_CANNOT_MAKE_URL_FROM";
+  public static final String WG_EXPAND_ENTITIES_NOT_SUPPORTED = 
+	 "WG_EXPAND_ENTITIES_NOT_SUPPORTED";
+  public static final String WG_ILLEGAL_VARIABLE_REFERENCE = 
+	 "WG_ILLEGAL_VARIABLE_REFERENCE";
+  public static final String WG_UNSUPPORTED_ENCODING ="WG_UNSUPPORTED_ENCODING";
+
+  /**  detach() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_DETACH_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER =
+	 "ER_DETACH_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+  /**  num() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_NUM_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER =
+	 "ER_NUM_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+  /**  xstr() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_XSTR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER =
+	 "ER_XSTR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+  /**  str() not supported by XRTreeFragSelectWrapper   */
+  public static final String ER_STR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER =
+	 "ER_STR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER";
+
+  // Error messages...
+
+
+  /**
+   * Get the association list.
+   *
+   * @return The association list.
+   */
+  public Object[][] getContents()
+  {
+    return new Object[][]{
+
+  { "ERROR0000" , "{0}" },
+
+  { ER_CURRENT_NOT_ALLOWED_IN_MATCH, "The current() function is not allowed in a match pattern!" },
+
+  { ER_CURRENT_TAKES_NO_ARGS, "The current() function does not accept arguments!" },
+
+  { ER_DOCUMENT_REPLACED,
+      "document() function implementation has been replaced by org.apache.xalan.xslt.FuncDocument!"},
+
+  { ER_CONTEXT_HAS_NO_OWNERDOC,
+      "context does not have an owner document!"},
+
+  { ER_LOCALNAME_HAS_TOO_MANY_ARGS,
+      "local-name() has too many arguments."},
+
+  { ER_NAMESPACEURI_HAS_TOO_MANY_ARGS,
+      "namespace-uri() has too many arguments."},
+
+  { ER_NORMALIZESPACE_HAS_TOO_MANY_ARGS,
+      "normalize-space() has too many arguments."},
+
+  { ER_NUMBER_HAS_TOO_MANY_ARGS,
+      "number() has too many arguments."},
+
+  { ER_NAME_HAS_TOO_MANY_ARGS,
+     "name() has too many arguments."},
+
+  { ER_STRING_HAS_TOO_MANY_ARGS,
+      "string() has too many arguments."},
+
+  { ER_STRINGLENGTH_HAS_TOO_MANY_ARGS,
+      "string-length() has too many arguments."},
+
+  { ER_TRANSLATE_TAKES_3_ARGS,
+      "The translate() function takes three arguments!"},
+
+  { ER_UNPARSEDENTITYURI_TAKES_1_ARG,
+      "The unparsed-entity-uri function should take one argument!"},
+
+  { ER_NAMESPACEAXIS_NOT_IMPLEMENTED,
+      "namespace axis not implemented yet!"},
+
+  { ER_UNKNOWN_AXIS,
+     "unknown axis: {0}"},
+
+  { ER_UNKNOWN_MATCH_OPERATION,
+     "unknown match operation!"},
+
+  { ER_INCORRECT_ARG_LENGTH,
+      "Arg length of processing-instruction() node test is incorrect!"},
+
+  { ER_CANT_CONVERT_TO_NUMBER,
+      "Can not convert {0} to a number"},
+
+  { ER_CANT_CONVERT_TO_NODELIST,
+      "Can not convert {0} to a NodeList!"},
+
+  { ER_CANT_CONVERT_TO_MUTABLENODELIST,
+      "Can not convert {0} to a NodeSetDTM!"},
+
+  { ER_CANT_CONVERT_TO_TYPE,
+      "Can not convert {0} to a type#{1}"},
+
+  { ER_EXPECTED_MATCH_PATTERN,
+      "Expected match pattern in getMatchScore!"},
+
+  { ER_COULDNOT_GET_VAR_NAMED,
+      "Could not get variable named {0}"},
+
+  { ER_UNKNOWN_OPCODE,
+     "ERROR! Unknown op code: {0}"},
+
+  { ER_EXTRA_ILLEGAL_TOKENS,
+     "Extra illegal tokens: {0}"},
+
+  { ER_EXPECTED_DOUBLE_QUOTE,
+      "misquoted literal... expected double quote!"},
+
+  { ER_EXPECTED_SINGLE_QUOTE,
+      "misquoted literal... expected single quote!"},
+
+  { ER_EMPTY_EXPRESSION,
+     "Empty expression!"},
+
+  { ER_EXPECTED_BUT_FOUND,
+     "Expected {0}, but found: {1}"},
+
+  { ER_INCORRECT_PROGRAMMER_ASSERTION,
+      "Programmer assertion is incorrect! - {0}"},
+
+  { ER_BOOLEAN_ARG_NO_LONGER_OPTIONAL,
+      "boolean(...) argument is no longer optional with 19990709 XPath draft."},
+
+  { ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG,
+      "Found ',' but no preceding argument!"},
+
+  { ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG,
+      "Found ',' but no following argument!"},
+
+  { ER_PREDICATE_ILLEGAL_SYNTAX,
+      "'..[predicate]' or '.[predicate]' is illegal syntax.  Use 'self::node()[predicate]' instead."},
+
+  { ER_ILLEGAL_AXIS_NAME,
+     "illegal axis name: {0}"},
+
+  { ER_UNKNOWN_NODETYPE,
+     "Unknown nodetype: {0}"},
+
+  { ER_PATTERN_LITERAL_NEEDS_BE_QUOTED,
+      "Pattern literal ({0}) needs to be quoted!"},
+
+  { ER_COULDNOT_BE_FORMATTED_TO_NUMBER,
+      "{0} could not be formatted to a number!"},
+
+  { ER_COULDNOT_CREATE_XMLPROCESSORLIAISON,
+      "Could not create XML TransformerFactory Liaison: {0}"},
+
+  { ER_DIDNOT_FIND_XPATH_SELECT_EXP,
+      "Error! Did not find xpath select expression (-select)."},
+
+  { ER_COULDNOT_FIND_ENDOP_AFTER_OPLOCATIONPATH,
+      "ERROR! Could not find ENDOP after OP_LOCATIONPATH"},
+
+  { ER_ERROR_OCCURED,
+     "Error occured!"},
+
+  { ER_ILLEGAL_VARIABLE_REFERENCE,
+      "VariableReference given for variable out of context or without definition!  Name = {0}"},
+
+  { ER_AXES_NOT_ALLOWED,
+      "Only child:: and attribute:: axes are allowed in match patterns!  Offending axes = {0}"},
+
+  { ER_KEY_HAS_TOO_MANY_ARGS,
+      "key() has an incorrect number of arguments."},
+
+  { ER_COUNT_TAKES_1_ARG,
+      "The count function should take one argument!"},
+
+  { ER_COULDNOT_FIND_FUNCTION,
+     "Could not find function: {0}"},
+
+  { ER_UNSUPPORTED_ENCODING,
+     "Unsupported encoding: {0}"},
+
+  { ER_PROBLEM_IN_DTM_NEXTSIBLING,
+      "Problem occured in DTM in getNextSibling... trying to recover"},
+
+  { ER_CANNOT_WRITE_TO_EMPTYNODELISTIMPL,
+      "Programmer error: EmptyNodeList can not be written to."},
+
+  { ER_SETDOMFACTORY_NOT_SUPPORTED,
+      "setDOMFactory is not supported by XPathContext!"},
+
+  { ER_PREFIX_MUST_RESOLVE,
+      "Prefix must resolve to a namespace: {0}"},
+
+  { ER_PARSE_NOT_SUPPORTED,
+      "parse (InputSource source) not supported in XPathContext! Can not open {0}"},
+
+  { ER_SAX_API_NOT_HANDLED,
+      "SAX API characters(char ch[]... not handled by the DTM!"},
+
+  { ER_IGNORABLE_WHITESPACE_NOT_HANDLED,
+      "ignorableWhitespace(char ch[]... not handled by the DTM!"},
+
+  { ER_DTM_CANNOT_HANDLE_NODES,
+      "DTMLiaison can not handle nodes of type {0}"},
+
+  { ER_XERCES_CANNOT_HANDLE_NODES,
+      "DOM2Helper can not handle nodes of type {0}"},
+
+  { ER_XERCES_PARSE_ERROR_DETAILS,
+      "DOM2Helper.parse error: SystemID - {0} line - {1}"},
+
+  { ER_XERCES_PARSE_ERROR,
+     "DOM2Helper.parse error"},
+
+  { ER_INVALID_UTF16_SURROGATE,
+      "Invalid UTF-16 surrogate detected: {0} ?"},
+
+  { ER_OIERROR,
+     "IO error"},
+
+  { ER_CANNOT_CREATE_URL,
+     "Cannot create url for: {0}"},
+
+  { ER_XPATH_READOBJECT,
+     "In XPath.readObject: {0}"},
+
+  { ER_FUNCTION_TOKEN_NOT_FOUND,
+      "function token not found."},
+
+  { ER_CANNOT_DEAL_XPATH_TYPE,
+       "Can not deal with XPath type: {0}"},
+
+  { ER_NODESET_NOT_MUTABLE,
+       "This NodeSet is not mutable"},
+
+  { ER_NODESETDTM_NOT_MUTABLE,
+       "This NodeSetDTM is not mutable"},
+
+  { ER_VAR_NOT_RESOLVABLE,
+        "Variable not resolvable: {0}"},
+
+  { ER_NULL_ERROR_HANDLER,
+        "Null error handler"},
+
+  { ER_PROG_ASSERT_UNKNOWN_OPCODE,
+       "Programmer''s assertion: unknown opcode: {0}"},
+
+  { ER_ZERO_OR_ONE,
+       "0 or 1"},
+
+  { ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+       "rtf() not supported by XRTreeFragSelectWrapper"},
+
+  { ER_RTF_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+       "asNodeIterator() not supported by XRTreeFragSelectWrapper"},
+       
+	/**  detach() not supported by XRTreeFragSelectWrapper   */
+   { ER_DETACH_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+		"detach() not supported by XRTreeFragSelectWrapper"},
+		
+	/**  num() not supported by XRTreeFragSelectWrapper   */
+   { ER_NUM_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+		"num() not supported by XRTreeFragSelectWrapper"},
+		
+	/**  xstr() not supported by XRTreeFragSelectWrapper   */
+   { ER_XSTR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+		"xstr() not supported by XRTreeFragSelectWrapper"},
+		
+	/**  str() not supported by XRTreeFragSelectWrapper   */
+   { ER_STR_NOT_SUPPORTED_XRTREEFRAGSELECTWRAPPER,
+		"str() not supported by XRTreeFragSelectWrapper"},
+
+  { ER_FSB_NOT_SUPPORTED_XSTRINGFORCHARS,
+       "fsb() not supported for XStringForChars"},
+
+  { ER_COULD_NOT_FIND_VAR,
+      "Could not find variable with the name of {0}"},
+
+  { ER_XSTRINGFORCHARS_CANNOT_TAKE_STRING,
+      "XStringForChars can not take a string for an argument"},
+
+  { ER_FASTSTRINGBUFFER_CANNOT_BE_NULL,
+      "The FastStringBuffer argument can not be null"},
+
+  { ER_TWO_OR_THREE,
+       "2 or 3"},
+
+  { ER_VARIABLE_ACCESSED_BEFORE_BIND,
+       "Variable accessed before it is bound!"},
+
+  { ER_FSB_CANNOT_TAKE_STRING,
+       "XStringForFSB can not take a string for an argument!"},
+
+  { ER_SETTING_WALKER_ROOT_TO_NULL,
+       "\n !!!! Error! Setting the root of a walker to null!!!"},
+
+  { ER_NODESETDTM_CANNOT_ITERATE,
+       "This NodeSetDTM can not iterate to a previous node!"},
+
+  { ER_NODESET_CANNOT_ITERATE,
+       "This NodeSet can not iterate to a previous node!"},
+
+  { ER_NODESETDTM_CANNOT_INDEX,
+       "This NodeSetDTM can not do indexing or counting functions!"},
+
+  { ER_NODESET_CANNOT_INDEX,
+       "This NodeSet can not do indexing or counting functions!"},
+
+  { ER_CANNOT_CALL_SETSHOULDCACHENODE,
+       "Can not call setShouldCacheNodes after nextNode has been called!"},
+
+  { ER_ONLY_ALLOWS,
+       "{0} only allows {1} arguments"},
+
+  { ER_UNKNOWN_STEP,
+       "Programmer''s assertion in getNextStepPos: unknown stepType: {0}"},
+
+  //Note to translators:  A relative location path is a form of XPath expression.
+  // The message indicates that such an expression was expected following the
+  // characters '/' or '//', but was not found.
+  { ER_EXPECTED_REL_LOC_PATH,
+      "A relative location path was expected following the '/' or '//' token."},
+
+  // Note to translators:  A location path is a form of XPath expression.
+  // The message indicates that syntactically such an expression was expected,but
+  // the characters specified by the substitution text were encountered instead.
+  { ER_EXPECTED_LOC_PATH,
+       "A location path was expected, but the following token was encountered\u003a  {0}"},
+
+  // Note to translators:  A location path is a form of XPath expression.
+  // The message indicates that syntactically such a subexpression was expected,
+  // but no more characters were found in the expression.
+  { ER_EXPECTED_LOC_PATH_AT_END_EXPR,
+       "A location path was expected, but the end of the XPath expression was found instead."},
+
+  // Note to translators:  A location step is part of an XPath expression.
+  // The message indicates that syntactically such an expression was expected
+  // following the specified characters.
+  { ER_EXPECTED_LOC_STEP,
+       "A location step was expected following the '/' or '//' token."},
+
+  // Note to translators:  A node test is part of an XPath expression that is
+  // used to test for particular kinds of nodes.  In this case, a node test that
+  // consists of an NCName followed by a colon and an asterisk or that consists
+  // of a QName was expected, but was not found.
+  { ER_EXPECTED_NODE_TEST,
+       "A node test that matches either NCName:* or QName was expected."},
+
+  // Note to translators:  A step pattern is part of an XPath expression.
+  // The message indicates that syntactically such an expression was expected,
+  // but the specified character was found in the expression instead.
+  { ER_EXPECTED_STEP_PATTERN,
+       "A step pattern was expected, but '/' was encountered."},
+
+  // Note to translators: A relative path pattern is part of an XPath expression.
+  // The message indicates that syntactically such an expression was expected,
+  // but was not found.
+  { ER_EXPECTED_REL_PATH_PATTERN,
+       "A relative path pattern was expected."},
+
+  // Note to translators:  The substitution text is the name of a data type.  The
+  // message indicates that a value of a particular type could not be converted
+  // to a value of type boolean.
+  { ER_CANT_CONVERT_TO_BOOLEAN,
+       "The XPathResult of XPath expression ''{0}'' has an XPathResultType of {1} which cannot be converted to a boolean."},
+
+  // Note to translators: Do not translate ANY_UNORDERED_NODE_TYPE and 
+  // FIRST_ORDERED_NODE_TYPE.
+  { ER_CANT_CONVERT_TO_SINGLENODE,
+       "The XPathResult of XPath expression ''{0}'' has an XPathResultType of {1} which cannot be converted to a single node. The method getSingleNodeValue applies only to types ANY_UNORDERED_NODE_TYPE and FIRST_ORDERED_NODE_TYPE."},
+
+  // Note to translators: Do not translate UNORDERED_NODE_SNAPSHOT_TYPE and
+  // ORDERED_NODE_SNAPSHOT_TYPE.
+  { ER_CANT_GET_SNAPSHOT_LENGTH,
+       "The method getSnapshotLength cannot be called on the XPathResult of XPath expression ''{0}'' because its XPathResultType is {1}. This method applies only to types UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE."},
+
+  { ER_NON_ITERATOR_TYPE,
+       "The method iterateNext cannot be called on the XPathResult of XPath expression ''{0}'' because its XPathResultType is {1}. This method applies only to types UNORDERED_NODE_ITERATOR_TYPE and ORDERED_NODE_ITERATOR_TYPE."},
+
+  // Note to translators: This message indicates that the document being operated
+  // upon changed, so the iterator object that was being used to traverse the
+  // document has now become invalid.
+  { ER_DOC_MUTATED,
+       "Document mutated since result was returned. Iterator is invalid."},
+
+  { ER_INVALID_XPATH_TYPE,
+       "Invalid XPath type argument: {0}"},
+
+  { ER_EMPTY_XPATH_RESULT,
+       "Empty XPath result object"},
+
+  { ER_INCOMPATIBLE_TYPES,
+       "The XPathResult of XPath expression ''{0}'' has an XPathResultType of {1} which cannot be coerced into the specified XPathResultType of {2}."},
+
+  { ER_NULL_RESOLVER,
+       "Unable to resolve prefix with null prefix resolver."},
+
+  // Note to translators:  The substitution text is the name of a data type.  The
+  // message indicates that a value of a particular type could not be converted
+  // to a value of type string.
+  { ER_CANT_CONVERT_TO_STRING,
+       "The XPathResult of XPath expression ''{0}'' has an XPathResultType of {1} which cannot be converted to a string."},
+
+  // Note to translators: Do not translate snapshotItem,
+  // UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE.
+  { ER_NON_SNAPSHOT_TYPE,
+       "The method snapshotItem cannot be called on the XPathResult of XPath expression ''{0}'' because its XPathResultType is {1}. This method applies only to types UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE."},
+
+  // Note to translators:  XPathEvaluator is a Java interface name.  An
+  // XPathEvaluator is created with respect to a particular XML document, and in
+  // this case the expression represented by this object was being evaluated with
+  // respect to a context node from a different document.
+  { ER_WRONG_DOCUMENT,
+       "Context node does not belong to the document that is bound to this XPathEvaluator."},
+
+  // Note to translators:  The XPath expression cannot be evaluated with respect
+  // to this type of node.
+  { ER_WRONG_NODETYPE,
+       "The context node type is not supported."},
+
+  { ER_XPATH_ERROR,
+       "Unknown error in XPath."},
+
+  { ER_CANT_CONVERT_XPATHRESULTTYPE_TO_NUMBER,
+	"The XPathResult of XPath expression ''{0}'' has an XPathResultType of {1} which cannot be converted to a number"},       
+
+  //BEGIN:  Definitions of error keys used  in exception messages of  JAXP 1.3 XPath API implementation
+
+  /** Field ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED                       */
+
+  { ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,
+       "Extension function: ''{0}'' can not be invoked when the XMLConstants.FEATURE_SECURE_PROCESSING feature is set to true."},
+
+  /** Field ER_RESOLVE_VARIABLE_RETURNS_NULL                       */
+
+  { ER_RESOLVE_VARIABLE_RETURNS_NULL,
+       "resolveVariable for variable {0} returning null"},
+
+  /** Field ER_UNSUPPORTED_RETURN_TYPE                       */
+
+  { ER_UNSUPPORTED_RETURN_TYPE,
+       "UnSupported Return Type : {0}"},
+
+  /** Field ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL                       */
+
+  { ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
+       "Source and/or Return Type can not be null"},
+
+  /** Field ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL                       */
+
+  { ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
+       "Source and/or Return Type can not be null"},
+
+  /** Field ER_ARG_CANNOT_BE_NULL                       */
+
+  { ER_ARG_CANNOT_BE_NULL,
+       "{0} argument can not be null"},
+
+  /** Field ER_OBJECT_MODEL_NULL                       */
+
+  { ER_OBJECT_MODEL_NULL,
+       "{0}#isObjectModelSupported( String objectModel ) cannot be called with objectModel == null"},
+
+  /** Field ER_OBJECT_MODEL_EMPTY                       */
+
+  { ER_OBJECT_MODEL_EMPTY,
+       "{0}#isObjectModelSupported( String objectModel ) cannot be called with objectModel == \"\""},
+
+  /** Field ER_OBJECT_MODEL_EMPTY                       */
+
+  { ER_FEATURE_NAME_NULL,
+       "Trying to set a feature with a null name: {0}#setFeature( null, {1})"},
+
+  /** Field ER_FEATURE_UNKNOWN                       */
+
+  { ER_FEATURE_UNKNOWN,
+       "Trying to set the unknown feature \"{0}\":{1}#setFeature({0},{2})"},
+
+  /** Field ER_GETTING_NULL_FEATURE                       */
+
+  { ER_GETTING_NULL_FEATURE,
+       "Trying to get a feature with a null name: {0}#getFeature(null)"},
+
+  /** Field ER_GETTING_NULL_FEATURE                       */
+
+  { ER_GETTING_UNKNOWN_FEATURE,
+       "Trying to get the unknown feature \"{0}\":{1}#getFeature({0})"},
+
+  /** Field ER_NULL_XPATH_FUNCTION_RESOLVER                       */
+
+  { ER_NULL_XPATH_FUNCTION_RESOLVER,
+       "Attempting to set a null XPathFunctionResolver:{0}#setXPathFunctionResolver(null)"},
+
+  /** Field ER_NULL_XPATH_VARIABLE_RESOLVER                       */
+
+  { ER_NULL_XPATH_VARIABLE_RESOLVER,
+       "Attempting to set a null XPathVariableResolver:{0}#setXPathVariableResolver(null)"},
+
+  //END:  Definitions of error keys used  in exception messages of  JAXP 1.3 XPath API implementation
+
+  // Warnings...
+
+  { WG_LOCALE_NAME_NOT_HANDLED,
+      "locale name in the format-number function not yet handled!"},
+
+  { WG_PROPERTY_NOT_SUPPORTED,
+      "XSL Property not supported: {0}"},
+
+  { WG_DONT_DO_ANYTHING_WITH_NS,
+      "Do not currently do anything with namespace {0} in property: {1}"},
+
+  { WG_SECURITY_EXCEPTION,
+      "SecurityException when trying to access XSL system property: {0}"},
+
+  { WG_QUO_NO_LONGER_DEFINED,
+      "Old syntax: quo(...) is no longer defined in XPath."},
+
+  { WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST,
+      "XPath needs a derived object to implement nodeTest!"},
+
+  { WG_FUNCTION_TOKEN_NOT_FOUND,
+      "function token not found."},
+
+  { WG_COULDNOT_FIND_FUNCTION,
+      "Could not find function: {0}"},
+
+  { WG_CANNOT_MAKE_URL_FROM,
+      "Can not make URL from: {0}"},
+
+  { WG_EXPAND_ENTITIES_NOT_SUPPORTED,
+      "-E option not supported for DTM parser"},
+
+  { WG_ILLEGAL_VARIABLE_REFERENCE,
+      "VariableReference given for variable out of context or without definition!  Name = {0}"},
+
+  { WG_UNSUPPORTED_ENCODING,
+     "Unsupported encoding: {0}"},
+
+
+
+  // Other miscellaneous text used inside the code...
+  { "ui_language", "en"},
+  { "help_language", "en"},
+  { "language", "en"},
+  { "BAD_CODE", "Parameter to createMessage was out of bounds"},
+  { "FORMAT_FAILED", "Exception thrown during messageFormat call"},
+  { "version", ">>>>>>> Xalan Version "},
+  { "version2", "<<<<<<<"},
+  { "yes", "yes"},
+  { "line", "Line #"},
+  { "column", "Column #"},
+  { "xsldone", "XSLProcessor: done"},
+  { "xpath_option", "xpath options: "},
+  { "optionIN", "   [-in inputXMLURL]"},
+  { "optionSelect", "   [-select xpath expression]"},
+  { "optionMatch", "   [-match match pattern (for match diagnostics)]"},
+  { "optionAnyExpr", "Or just an xpath expression will do a diagnostic dump"},
+  { "noParsermsg1", "XSL Process was not successful."},
+  { "noParsermsg2", "** Could not find parser **"},
+  { "noParsermsg3", "Please check your classpath."},
+  { "noParsermsg4", "If you don't have IBM's XML Parser for Java, you can download it from"},
+  { "noParsermsg5", "IBM's AlphaWorks: http://www.alphaworks.ibm.com/formula/xml"},
+  { "gtone", ">1" },
+  { "zero", "0" },
+  { "one", "1" },
+  { "two" , "2" },
+  { "three", "3" }
+
+  };
+  }
+
+
+  // ================= INFRASTRUCTURE ======================
+
+  /** Field BAD_CODE          */
+  public static final String BAD_CODE = "BAD_CODE";
+
+  /** Field FORMAT_FAILED          */
+  public static final String FORMAT_FAILED = "FORMAT_FAILED";
+
+  /** Field ERROR_RESOURCES          */
+  public static final String ERROR_RESOURCES =
+    "org.apache.xpath.res.XPATHErrorResources";
+
+  /** Field ERROR_STRING          */
+  public static final String ERROR_STRING = "#error";
+
+  /** Field ERROR_HEADER          */
+  public static final String ERROR_HEADER = "Error: ";
+
+  /** Field WARNING_HEADER          */
+  public static final String WARNING_HEADER = "Warning: ";
+
+  /** Field XSL_HEADER          */
+  public static final String XSL_HEADER = "XSL ";
+
+  /** Field XML_HEADER          */
+  public static final String XML_HEADER = "XML ";
+
+  /** Field QUERY_HEADER          */
+  public static final String QUERY_HEADER = "PATTERN ";
+
+
+  /**
+   * Return a named ResourceBundle for a particular locale.  This method mimics the behavior
+   * of ResourceBundle.getBundle().
+   *
+   * @param className Name of local-specific subclass.
+   * @return the ResourceBundle
+   * @throws MissingResourceException
+   */
+  public static final XPATHErrorResources loadResourceBundle(String className)
+          throws MissingResourceException
+  {
+
+    Locale locale = Locale.getDefault();
+    String suffix = getResourceSuffix(locale);
+
+    try
+    {
+
+      // first try with the given locale
+      return (XPATHErrorResources) ResourceBundle.getBundle(className
+              + suffix, locale);
+    }
+    catch (MissingResourceException e)
+    {
+      try  // try to fall back to en_US if we can't load
+      {
+
+        // Since we can't find the localized property file,
+        // fall back to en_US.
+        return (XPATHErrorResources) ResourceBundle.getBundle(className,
+                new Locale("en", "US"));
+      }
+      catch (MissingResourceException e2)
+      {
+
+        // Now we are really in trouble.
+        // very bad, definitely very bad...not going to get very far
+        throw new MissingResourceException(
+          "Could not load any resource bundles.", className, "");
+      }
+    }
+  }
+
+  /**
+   * Return the resource file suffic for the indicated locale
+   * For most locales, this will be based the language code.  However
+   * for Chinese, we do distinguish between Taiwan and PRC
+   *
+   * @param locale the locale
+   * @return an String suffix which canbe appended to a resource name
+   */
+  private static final String getResourceSuffix(Locale locale)
+  {
+
+    String suffix = "_" + locale.getLanguage();
+    String country = locale.getCountry();
+
+    if (country.equals("TW"))
+      suffix += "_" + country;
+
+    return suffix;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/res/XPATHMessages.java b/src/main/java/org/apache/xpath/res/XPATHMessages.java
new file mode 100644
index 0000000..7fb6135
--- /dev/null
+++ b/src/main/java/org/apache/xpath/res/XPATHMessages.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XPATHMessages.java 468655 2006-10-28 07:12:06Z minchau $
+ */
+package org.apache.xpath.res;
+
+import java.util.ListResourceBundle;
+
+import org.apache.xml.res.XMLMessages;
+
+/**
+ * A utility class for issuing XPath error messages.
+ * @xsl.usage internal
+ */
+public class XPATHMessages extends XMLMessages
+{
+  /** The language specific resource object for XPath messages.  */
+  private static ListResourceBundle XPATHBundle = new XPATHErrorResources();
+
+  /** The class name of the XPath error message string table.     */
+  private static final String XPATH_ERROR_RESOURCES =
+    "org.apache.xpath.res.XPATHErrorResources";
+  
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param msgKey    The key for the message text.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted message string.
+   */
+  public static final String createXPATHMessage(String msgKey, Object args[])  //throws Exception 
+  {
+      // BEGIN android-changed
+      //     don't localize exception messages
+      return createXPATHMsg(XPATHBundle, msgKey, args);
+      // END android-changed
+  }
+
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param msgKey The key for the message text.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted warning string.
+   */
+  public static final String createXPATHWarning(String msgKey, Object args[])  //throws Exception
+  {
+      // BEGIN android-changed
+      //     don't localize exception messages
+      return createXPATHMsg(XPATHBundle, msgKey, args);
+      // END android-changed
+  }
+
+  /**
+   * Creates a message from the specified key and replacement
+   * arguments, localized to the given locale.
+   *
+   * @param fResourceBundle The resource bundle to use.
+   * @param msgKey  The message key to use.
+   * @param args      The arguments to be used as replacement text
+   *                  in the message created.
+   *
+   * @return The formatted message string.
+   */
+  public static final String createXPATHMsg(ListResourceBundle fResourceBundle,
+                                            String msgKey, Object args[])  //throws Exception
+  {
+
+    String fmsg = null;
+    boolean throwex = false;
+    String msg = null;
+
+    if (msgKey != null)
+      msg = fResourceBundle.getString(msgKey); 
+
+    if (msg == null)
+    {
+      msg = fResourceBundle.getString(XPATHErrorResources.BAD_CODE);
+      throwex = true;
+    }
+
+    if (args != null)
+    {
+      try
+      {
+
+        // Do this to keep format from crying.
+        // This is better than making a bunch of conditional
+        // code all over the place.
+        int n = args.length;
+
+        for (int i = 0; i < n; i++)
+        {
+          if (null == args[i])
+            args[i] = "";
+        }
+
+        fmsg = java.text.MessageFormat.format(msg, args);
+      }
+      catch (Exception e)
+      {
+        fmsg = fResourceBundle.getString(XPATHErrorResources.FORMAT_FAILED);
+        fmsg += " " + msg;
+      }
+    }
+    else
+      fmsg = msg;
+
+    if (throwex)
+    {
+      throw new RuntimeException(fmsg);
+    }
+
+    return fmsg;
+  }
+
+}
diff --git a/src/main/java/org/apache/xpath/res/package.html b/src/main/java/org/apache/xpath/res/package.html
new file mode 100644
index 0000000..ad04feb
--- /dev/null
+++ b/src/main/java/org/apache/xpath/res/package.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- $Id: package.html 468655 2006-10-28 07:12:06Z minchau $ -->
+<html>
+  <title>XPath resources.</title>
+  <body>
+    <p>Contains strings for XPath support that require internationalization.<p>
+ </body>
+</html>
+
+
