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..9414875
--- /dev/null
+++ b/src/main/java/org/apache/xml/serializer/ToHTMLStream.java
@@ -0,0 +1,2352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 libcore.base.EmptyArray;
+
+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 = EmptyArray.CHAR;
+
+        /** 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>
+
+
