You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2024/07/27 13:13:30 UTC

(xalan-java) branch xalan-j_xslt3.0 updated: committing implementation of XSLT tunnel parameters, along with few conformance test cases. also doing little bit of other codebase refactoring.

This is an automated email from the ASF dual-hosted git repository.

mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git


The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
     new 50925d9f6 committing implementation of XSLT tunnel parameters, along with few conformance test cases. also doing little bit of other codebase refactoring.
50925d9f6 is described below

commit 50925d9f6ad98bad44d050dd53fb691954a5c335
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Jul 27 18:43:17 2024 +0530

    committing implementation of XSLT tunnel parameters, along with few conformance test cases. also doing little bit of other codebase refactoring.
---
 src/org/apache/xalan/processor/XSLTSchema.java     |   15 +-
 .../apache/xalan/templates/ElemApplyTemplates.java |   65 +-
 .../apache/xalan/templates/ElemCallTemplate.java   |   53 +-
 src/org/apache/xalan/templates/ElemParam.java      |   56 +
 .../xalan/templates/ElemTemplateElement.java       |   41 +-
 src/org/apache/xalan/templates/ElemWithParam.java  |   47 +-
 .../xslt/util/XslTransformEvaluationHelper.java    |   15 +
 src/org/apache/xpath/compiler/XPathParser.java     | 1688 +++++++++-----------
 src/org/apache/xpath/objects/XObject.java          |   37 +-
 src/org/apache/xpath/operations/StrConcat.java     |   31 +-
 tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java   |    3 +-
 .../xalan/xslt3/XslTunnelParameterTests.java       |  103 ++
 tests/xsl_tunnel_parameter/gold/test1.out          |    4 +
 tests/xsl_tunnel_parameter/gold/test2.out          |    4 +
 tests/xsl_tunnel_parameter/gold/test3.out          |    8 +
 tests/xsl_tunnel_parameter/gold/test4.out          |    8 +
 tests/xsl_tunnel_parameter/gold/test5.out          |    4 +
 tests/xsl_tunnel_parameter/test1.xsl               |   57 +
 tests/xsl_tunnel_parameter/test2.xsl               |   57 +
 tests/xsl_tunnel_parameter/test3.xml               |    5 +
 tests/xsl_tunnel_parameter/test3.xsl               |   59 +
 tests/xsl_tunnel_parameter/test4.xml               |    5 +
 tests/xsl_tunnel_parameter/test4.xsl               |   59 +
 tests/xsl_tunnel_parameter/test5.xsl               |   54 +
 24 files changed, 1452 insertions(+), 1026 deletions(-)

diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index bdc48489d..19b262c54 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -259,6 +259,11 @@ public class XSLTSchema extends XSLTElementDef
     // xsl:variable, xsl:param, xsl:with-param, xsl:template, xsl:function 
     XSLTAttributeDef asAttrOpt = new XSLTAttributeDef(null, "as",
                                        XSLTAttributeDef.T_STRING, false, false, XSLTAttributeDef.ERROR);
+    
+    // Optional.
+    // xsl:param, xsl:with-param 
+    XSLTAttributeDef tunnelAttrOpt = new XSLTAttributeDef(null, "tunnel",
+                                           XSLTAttributeDef.T_STRING, false, false, XSLTAttributeDef.ERROR);
 
     // Optional.
     // Default: "node()"
@@ -479,8 +484,8 @@ public class XSLTSchema extends XSLTElementDef
                                     "with-param", null /*alias */,
                                     templateElements /* elements */,  // %template;>
                                     new XSLTAttributeDef[]{ nameAttrRequired,
-                                                            selectAttrOpt, asAttrOpt }, new ProcessorTemplateElem(),
-                                                                             ElemWithParam.class /* class object */, 19, true);
+                                                            selectAttrOpt, asAttrOpt, tunnelAttrOpt }, new ProcessorTemplateElem(),
+                                                            ElemWithParam.class /* class object */, 19, true);
     XSLTElementDef xslApplyTemplates = new XSLTElementDef(this,
                                          Constants.S_XSLNAMESPACEURL,
                                          "apply-templates", null /*alias */,
@@ -624,9 +629,9 @@ public class XSLTSchema extends XSLTElementDef
                                 null /*alias */,
                                 templateElements /* elements */,  // %template;>
                                 new XSLTAttributeDef[]{ nameAttrRequired,
-                                                        selectAttrOpt, asAttrOpt }, 
-                                       new ProcessorTemplateElem(),
-                                ElemParam.class /* class object */, 19, true);
+                                                        selectAttrOpt, asAttrOpt, tunnelAttrOpt }, 
+                                                        new ProcessorTemplateElem(),
+                                                        ElemParam.class /* class object */, 19, true);
     XSLTElementDef xslText =
       new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "text",
                          null /*alias */,
diff --git a/src/org/apache/xalan/templates/ElemApplyTemplates.java b/src/org/apache/xalan/templates/ElemApplyTemplates.java
index 6c99c4dc4..e289ca009 100644
--- a/src/org/apache/xalan/templates/ElemApplyTemplates.java
+++ b/src/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -20,6 +20,7 @@
  */
 package org.apache.xalan.templates;
 
+import java.util.List;
 import java.util.Vector;
 
 import javax.xml.transform.SourceLocator;
@@ -260,6 +261,8 @@ public class ElemApplyTemplates extends ElemCallTemplate
         argsFrame = vars.link(nParams);
         vars.setStackFrame(thisframe);
         
+        int maxParamStackFrameIndex = -1;
+        
         for (int i = 0; i < nParams; i++) 
         {
           ElemWithParam ewp = m_paramElems[i];
@@ -278,8 +281,39 @@ public class ElemApplyTemplates extends ElemCallTemplate
           if (transformer.getDebug())
             transformer.getTraceManager().fireTraceEndEvent(ewp);
           
+          String tunnelStrVal = ewp.getTunnel();
+          obj.setTunnel(tunnelStrVal);
+          QName qName = ewp.getName();
+          obj.setQName(qName);
+          
           vars.setLocalVariable(i, obj, argsFrame);
+          maxParamStackFrameIndex = i;
+        }
+        
+        for (int idx = 0; idx < MAX_PARAM_LIMIT; idx++) {
+        	XObject obj = vars.getLocalVariable(idx, thisframe);
+        	if (obj != null) {
+        		String tunnelValStr = obj.getTunnel();
+        		if ((obj.getTunnel() != null) && XslTransformEvaluationHelper.isTunnelAttributeYes(tunnelValStr)) {
+        			vars.setLocalVariable(++maxParamStackFrameIndex, obj, argsFrame);
+        		}
+        	}
+        	else {
+        		break; 
+        	}
+        }
+
+        ElemTemplateElement parentElem = getParentElem();
+        while (!(parentElem instanceof ElemTemplate)) {
+        	parentElem = parentElem.getParentElem(); 
+        }
+
+        List<XObject> tunnelParamObjList = parentElem.getTunnelParamObjList();
+        for (int idx = 0; idx < tunnelParamObjList.size(); idx++) {
+        	XObject var = tunnelParamObjList.get(idx);
+        	vars.setLocalVariable(++maxParamStackFrameIndex, var, argsFrame);
         }
+        
         vars.setStackFrame(argsFrame);
       }
       
@@ -343,15 +377,14 @@ public class ElemApplyTemplates extends ElemCallTemplate
         if (check)
 	        guard.checkForInfiniteLoop();
 
-        int currentFrameBottom;  // See comment with unlink, below
+        int currentFrameBottom;
         if(template.m_frameSize > 0)
         {
           xctxt.pushRTFContext();
-          currentFrameBottom = vars.getStackFrame();  // See comment with unlink, below
+          currentFrameBottom = vars.getStackFrame();
           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)
+          
+          if (template.m_inArgsSize > 0)
           {
             int paramIndex = 0;
             for (ElemTemplateElement elem = template.getFirstChildElem(); 
@@ -365,22 +398,26 @@ public class ElemApplyTemplates extends ElemCallTemplate
                 for (i = 0; i < nParams; i++) 
                 {
                   ElemWithParam ewp = m_paramElems[i];
-                  if(ewp.m_qnameID == ep.m_qnameID)
+                  if (ewp.m_qnameID == ep.m_qnameID)                  
                   {
-                    XObject obj = vars.getLocalVariable(i, argsFrame);
-                    vars.setLocalVariable(paramIndex, obj);
-                    break;
+                      XObject obj = vars.getLocalVariable(i, argsFrame);
+                      vars.setLocalVariable(paramIndex, obj);
+                      break;
                   }
                 }
-                if(i == nParams)
-                  vars.setLocalVariable(paramIndex, null);
+                
+                // The below code before commenting has been causing, issues 
+                // implementing XSLT tunnel parameters. Commenting this seems 
+                // to be working fine for non-tunnel parameter use cases as 
+                // well. Pls review.
+                /*if (i == nParams) {
+                  vars.setLocalVariable(paramIndex, null);*/                
               }
               else
                 break;
               paramIndex++;
-            }
-            
-          }
+            }                        
+          }                    
         }
         else {
            currentFrameBottom = 0;
diff --git a/src/org/apache/xalan/templates/ElemCallTemplate.java b/src/org/apache/xalan/templates/ElemCallTemplate.java
index 16b23bdf0..e5960be80 100644
--- a/src/org/apache/xalan/templates/ElemCallTemplate.java
+++ b/src/org/apache/xalan/templates/ElemCallTemplate.java
@@ -20,12 +20,15 @@
  */
 package org.apache.xalan.templates;
 
+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.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xml.utils.QName;
 import org.apache.xpath.VariableStack;
 import org.apache.xpath.XPathContext;
@@ -33,14 +36,8 @@ import org.apache.xpath.objects.XObject;
 import org.w3c.dom.DOMException;
 
 /**
- * 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>
+ * Implementation of XSLT xsl:call-template element.
+ * 
  * @xsl.usage advanced
  */
 public class ElemCallTemplate extends ElemForEach
@@ -83,6 +80,11 @@ public class ElemCallTemplate extends ElemForEach
    * @serial
    */
   private ElemTemplate m_template = null;
+  
+  /**
+   * Used to implement XSLT tunnel parameters.
+   */
+  protected final int MAX_PARAM_LIMIT = 100; 
 
   /**
    * Get an int constant identifying the type of element.
@@ -217,6 +219,8 @@ public class ElemCallTemplate extends ElemForEach
           vars.setStackFrame(thisframe);
           int size = m_paramElems.length;
           
+          int maxParamStackFrameIndex = -1;
+          
           for (int i = 0; i < size; i++) 
           {
             ElemWithParam ewp = m_paramElems[i];
@@ -226,14 +230,45 @@ public class ElemCallTemplate extends ElemForEach
                 transformer.getTraceManager().fireTraceEvent(ewp);
               XObject obj = ewp.getValue(transformer, currentNode);
               if (transformer.getDebug())
-                transformer.getTraceManager().fireTraceEndEvent(ewp);
+                transformer.getTraceManager().fireTraceEndEvent(ewp);                            
+              
+              String tunnelStrVal = ewp.getTunnel();
+              obj.setTunnel(tunnelStrVal);
+              QName qName = ewp.getName();
+              obj.setQName(qName);
               
               // 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);
+              maxParamStackFrameIndex = ewp.m_index; 
             }
           }
+          
+          for (int idx = 0; idx < MAX_PARAM_LIMIT; idx++) {
+             XObject obj = vars.getLocalVariable(idx, thisframe);
+             if (obj != null) {
+            	String tunnelValStr = obj.getTunnel();            	
+            	if ((obj.getTunnel() != null) && XslTransformEvaluationHelper.isTunnelAttributeYes(tunnelValStr)) {
+            	   vars.setLocalVariable(++maxParamStackFrameIndex, obj, nextFrame);
+            	}
+             }
+             else {
+            	break; 
+             }
+          }
+          
+          ElemTemplateElement parentElem = getParentElem();
+          while (!(parentElem instanceof ElemTemplate)) {
+        	 parentElem = parentElem.getParentElem(); 
+          }
+          
+          List<XObject> tunnelParamObjList = parentElem.getTunnelParamObjList();
+          for (int idx = 0; idx < tunnelParamObjList.size(); idx++) {
+        	 XObject var = tunnelParamObjList.get(idx);
+        	 vars.setLocalVariable(++maxParamStackFrameIndex, var, nextFrame);
+          }
+          
           vars.setStackFrame(nextFrame);
         }
       }
diff --git a/src/org/apache/xalan/templates/ElemParam.java b/src/org/apache/xalan/templates/ElemParam.java
index 57469df17..75a26bbed 100644
--- a/src/org/apache/xalan/templates/ElemParam.java
+++ b/src/org/apache/xalan/templates/ElemParam.java
@@ -20,10 +20,15 @@
  */
 package org.apache.xalan.templates;
 
+import java.util.Arrays;
+import java.util.List;
+
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.utils.QName;
 import org.apache.xpath.VariableStack;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.composite.SequenceTypeSupport;
@@ -48,6 +53,26 @@ public class ElemParam extends ElemVariable
    *
    */
   public ElemParam(){}
+  
+  /**
+   * The value of the "tunnel" attribute.
+   */
+  private String m_tunnelAttr;
+  
+  /**
+   * Set the "tunnel" attribute.
+   */
+  public void setTunnel(String val) {
+	 m_tunnelAttr = val;
+  }
+  
+  /**
+   * Get the "tunnel" attribute.
+   */
+  public String getTunnel()
+  {
+     return m_tunnelAttr;
+  }
 
   /**
    * Get an int constant identifying the type of element.
@@ -116,6 +141,24 @@ public class ElemParam extends ElemVariable
     XPathContext xctx = transformer.getXPathContext();
     
     SourceLocator srcLocator = xctx.getSAXLocator();
+    
+    if (m_tunnelAttr != null && !isValidTunnelParamValue(m_tunnelAttr)) {
+       throw new TransformerException("XTTE0590 : Allowed values for xsl:param's tunnel "
+        		                                              + "attribute are : yes, true, 1, no, false, 0. The "
+        		                                              + "supplied value is " + m_tunnelAttr + ".", srcLocator); 
+    }
+    
+    if (vars.isLocalSet(m_index)) {
+       XObject var = vars.getLocalVariable(xctx, m_index);
+       String tunnelValStr = var.getTunnel();
+ 	   QName tunnelParamQName = var.getQName(); 	  
+ 	   if (m_qname.equals(tunnelParamQName) && !XslTransformEvaluationHelper.isTunnelAttributeYes(m_tunnelAttr) && 
+ 			                                               XslTransformEvaluationHelper.isTunnelAttributeYes(tunnelValStr)) {
+ 		  vars.setLocalVariable(m_index, null);
+ 		  ElemTemplateElement elemTemplateElement = getParentElem();
+ 		  elemTemplateElement.setTunnelParamObj(var);
+ 	   }
+    }
             
     if (!vars.isLocalSet(m_index) || (getParentElem() instanceof ElemIterate)) {
         int sourceNode = transformer.getXPathContext().getCurrentNode();
@@ -162,4 +205,17 @@ public class ElemParam extends ElemVariable
       transformer.getTraceManager().fireTraceEndEvent(this);
   }
   
+  /**
+   * Check whether a string value is a valid, XSLT tunnel attribute value.
+   */
+  private boolean isValidTunnelParamValue(String val) {
+	 boolean result = false;
+	 
+	 String[] allowedValuesStr = new String [] {"yes", "true", "1", "no", "false", "0"};
+	 List<String> strList = Arrays.asList(allowedValuesStr);
+	 result = strList.contains(val);
+	 
+	 return result;
+  }
+  
 }
diff --git a/src/org/apache/xalan/templates/ElemTemplateElement.java b/src/org/apache/xalan/templates/ElemTemplateElement.java
index c8a80531a..c45902d95 100644
--- a/src/org/apache/xalan/templates/ElemTemplateElement.java
+++ b/src/org/apache/xalan/templates/ElemTemplateElement.java
@@ -73,15 +73,24 @@ public class ElemTemplateElement extends UnImplNode
 {
    static final long serialVersionUID = 4440018597841834447L;
     
-   // This class field supports, implementation of xsl:for-each-group's grouping key. 
-   // An instance of this class, stores this value for a specific xsl:for-each-group element 
-   // within the XSLT stylesheet.
-   private Object fGroupingKey = null;
+   /**
+    * This field supports implementation of, xsl:for-each-group's grouping key. 
+    * An instance of this class, stores this value for a specific xsl:for-each-group  
+    * element within an XSL stylesheet.
+    */
+   private Object m_groupingKey = null;
     
-   // This class field supports, implementation of xsl:for-each-group's current-group contents. 
-   // An instance of this class, stores this value for a specific xsl:for-each-group element 
-   // within the XSLT stylesheet.
-   private List<Integer> fGroupNodesDtmHandles;
+   /**
+    * This field supports implementation of, xsl:for-each-group's current-group contents. 
+    * An instance of this class, stores this value for a specific xsl:for-each-group 
+    * element within an XSL stylesheet. 
+    */
+   private List<Integer> m_groupNodesDtmHandles;
+   
+   /**
+    * This field supports implementation of, XSLT tunnel parameters.
+    */
+   private List<XObject> m_tunnelParamObjList = new ArrayList<XObject>();
 
   /**
    * Construct a template element instance.
@@ -1677,19 +1686,19 @@ public class ElemTemplateElement extends UnImplNode
   }
 
   public Object getGroupingKey() {
-      return fGroupingKey;
+      return m_groupingKey;
   }
 
   public void setGroupingKey(Object groupingKey) {
-      this.fGroupingKey = groupingKey;
+      this.m_groupingKey = groupingKey;
   }
 
   public List<Integer> getGroupNodesDtmHandles() {
-      return fGroupNodesDtmHandles;
+      return m_groupNodesDtmHandles;
   }
 
   public void setGroupNodesDtmHandles(List<Integer> groupNodesDtmHandles) {
-      this.fGroupNodesDtmHandles = groupNodesDtmHandles;
+      this.m_groupNodesDtmHandles = groupNodesDtmHandles;
   }
   
   /**
@@ -1796,4 +1805,12 @@ public class ElemTemplateElement extends UnImplNode
      }
   }
 
+  public void setTunnelParamObj(XObject var) {
+	 m_tunnelParamObjList.add(var);	
+  }
+  
+  public List<XObject> getTunnelParamObjList() {
+	 return m_tunnelParamObjList; 
+  }
+
 }
diff --git a/src/org/apache/xalan/templates/ElemWithParam.java b/src/org/apache/xalan/templates/ElemWithParam.java
index fd54bde08..3ab02f7be 100644
--- a/src/org/apache/xalan/templates/ElemWithParam.java
+++ b/src/org/apache/xalan/templates/ElemWithParam.java
@@ -20,6 +20,9 @@
  */
 package org.apache.xalan.templates;
 
+import java.util.Arrays;
+import java.util.List;
+
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
@@ -148,6 +151,26 @@ public class ElemWithParam extends ElemTemplateElement
   {
      return m_asAttr;
   }
+  
+  /**
+   * The value of the "tunnel" attribute.
+   */
+  private String m_tunnelAttr;
+  
+  /**
+   * Set the "tunnel" attribute.
+   */
+  public void setTunnel(String val) {	 
+	 m_tunnelAttr = val;
+  }
+  
+  /**
+   * Get the "tunnel" attribute.
+   */
+  public String getTunnel()
+  {
+     return m_tunnelAttr;
+  }
 
   /**
    * Get an integer representation of the element type.
@@ -219,14 +242,19 @@ public class ElemWithParam extends ElemTemplateElement
    *
    * @throws TransformerException
    */
-  public XObject getValue(TransformerImpl transformer, int sourceNode)
-          throws TransformerException
+  public XObject getValue(TransformerImpl transformer, int sourceNode) throws TransformerException
   {
 
     XObject var;
     XPathContext xctxt = transformer.getXPathContext();
     
     SourceLocator srcLocator = xctxt.getSAXLocator();
+    
+    if (m_tunnelAttr != null && !isValidTunnelParamValue(m_tunnelAttr)) {
+       throw new TransformerException("XTTE0590 : Allowed values for xsl:with-param's tunnel "
+       		                                           + "attribute are : yes, true, 1, no, false, 0. The "
+       		                                           + "supplied value is " + m_tunnelAttr + ".", srcLocator); 
+    }
 
     xctxt.pushCurrentNode(sourceNode);
 
@@ -319,6 +347,17 @@ public class ElemWithParam extends ElemTemplateElement
     }
     return super.appendChild(elem);
   }
-
-
+  
+  /**
+   * Check whether a string value is a valid, XSLT tunnel attribute value.
+   */
+  private boolean isValidTunnelParamValue(String val) {
+	 boolean result = false;
+	 
+	 String[] allowedValuesStr = new String [] {"yes", "true", "1", "no", "false", "0"};
+	 List<String> strList = Arrays.asList(allowedValuesStr);
+	 result = strList.contains(val);
+	 
+	 return result;
+  }
 }
diff --git a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
index bfb6fa566..6e38f5766 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
@@ -524,5 +524,20 @@ public class XslTransformEvaluationHelper {
        
        return sum;
     }
+    
+    /**
+     * This method checks whether, an XSL xsl:with-param/xsl:param 
+     * tunnel attribute's value is true (i.e, having string 
+     * values "yes", "true", or "1").
+     */
+    public static boolean isTunnelAttributeYes(String val) {
+       boolean result = false;
+       
+       if (val != null) {
+    	  result = (val.equals("yes") || val.equals("true") || val.equals("1"));
+       }
+       
+       return result;
+    }
 
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 30d34829e..29a3ab966 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -116,8 +116,8 @@ public class XPathParser
   protected final static int FILTER_MATCH_PRIMARY    = 1;
   protected final static int FILTER_MATCH_PREDICATES = 2;
   
-  /*
-   * While parsing certain XPath 3.1 expressions, we use this constant string 
+  /**
+   * With XPath parse of certain expressions, we use this constant string 
    * array to make parse decisions. The elements of this array are certain 
    * XPath language key words and symbols that need this support.
    */
@@ -129,10 +129,12 @@ public class XPathParser
                                                       "let", ":=", "-", "||", "=>", "instance", 
                                                       "of", "as" };
   
-  // If an XPath expression is () (i.e, representing an xdm empty sequence),
-  // we translate that within this XPath parser implementation, to an XPath
-  // range "to" expression using this class field (this equivalently produces
-  // an xdm empty sequence).
+  /**
+   * When an XPath expression is () (i.e, representing an xdm empty sequence),
+   * we translate that within this XPath parser implementation, to an XPath
+   * range "to" expression using this class field (this equivalently produces
+   * an xdm empty sequence).
+   */
   public static final String XPATH_EXPR_STR_EMPTY_SEQUENCE = "1 to 0";
   
   private static final List<String> XPATH_OP_ARR_TOKENS_LIST = Arrays.asList(XPATH_OP_ARR);
@@ -253,7 +255,7 @@ public class XPathParser
    * @param isSequenceTypeXPathExpr When this method is called, with this parameter
    *                                set to boolean value 'true', then an XPath parser object 
    *                                instance, instantiated from this class shall parse the XPath
-   *                                expression string assuming that it represents an XPath 3.1
+   *                                expression string assuming that it represents an XPath
    *                                sequence type expression (for e.g, as a value of "as" 
    *                                attribute of xsl:variable instruction). 
    *
@@ -280,16 +282,7 @@ public class XPathParser
 
     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();
@@ -313,7 +306,7 @@ public class XPathParser
         }
 
         error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
-              new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
+              new Object[]{ extraTokens });
       }
 
     } 
@@ -321,13 +314,10 @@ public class XPathParser
     {
 	  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, false);
+		 initXPath(compiler, "/..",  namespaceContext, false);
 	  }
 	  else
-		throw e;
+		 throw e;
     }
 
     compiler.shrink();
@@ -378,7 +368,7 @@ public class XPathParser
       }
 
       error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
-            new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
+            new Object[]{ extraTokens });
     }
 
     m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
@@ -781,6 +771,7 @@ public class XPathParser
       
       if (tokenIs('(') && (prevToken.equals("(") || prevToken.equals(","))) {
      	 // XPath parse of literal sequence
+    	  
      	 StringBuffer strBuff = new StringBuffer();
      	 strBuff.append(m_token);    	 
      	 consumeExpected('(');
@@ -805,6 +796,7 @@ public class XPathParser
       }
       else if (tokenIs('[') && (prevToken.equals("(") || prevToken.equals(","))) {
      	 // XPath parse of literal array
+    	  
      	 StringBuffer strBuff = new StringBuffer();
      	 strBuff.append(m_token);    	 
      	 consumeExpected('[');
@@ -921,7 +913,7 @@ public class XPathParser
   }
   
   /**
-   * This method helps to implement, XPath 3.1 sequence type expressions.
+   * XPath parse of sequence type expressions.
    */
   private void setSequenceTypeOccurenceIndicator(XPathSequenceTypeExpr xpathSequenceTypeExpr, 
                                                                                    boolean isInlineFunction) throws TransformerException {
@@ -971,7 +963,7 @@ public class XPathParser
    }
    
    /**
-    * This method helps to implement, XPath 3.1 sequence type expressions.
+    * This method supports XPath parse of sequence type expressions.
     */
    private SequenceTypeKindTest constructSequenceTypeKindTestForXDMNodes(XPathSequenceTypeExpr 
                                                                                      xpathSequenceTypeExpr, 
@@ -1185,7 +1177,7 @@ public class XPathParser
     	  id = m_functionTable.getFunctionId(key);
     	}
       }
-      tok = ((Integer) id).intValue();
+      tok = ((Integer)id).intValue();
     }
     catch (NullPointerException npe)
     {
@@ -1280,9 +1272,11 @@ public class XPathParser
 	      }
 	  }
 	  else if (m_isXPathExprBeginParse && isLiteralSequenceOrArrayBegin()) {
-    	  // We consider XPath parse of sequence and array, in similar 
-    	  // way. These are different lexically only, by virtue of 
-    	  // sequence/array expression's delimiter characters.
+    	  /**
+		   * We consider XPath parse of sequence and array, in similar 
+    	   * way. These are lexically different only by virtue of sequence/array 
+    	   * expression's left-most and right-most delimiter characters.
+		   */
     	  
     	  boolean isSequenceConstructor = false;    	  
     	  if (tokenIs("(")) {
@@ -1491,7 +1485,7 @@ public class XPathParser
           }
       }      
       else if (m_isXPathExprBeginParse && tokenIs("map")) {
-    	  // An XPath parse of 'map' expression
+    	  // XPath parse of map expression
     	  
     	  int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
     	  
@@ -2193,10 +2187,11 @@ public class XPathParser
     
     if (tokenIs('(')) {
       if ("=".equals(getTokenRelative(-2))) {
-    	  // Previous token is, '='.    	  
-    	  // XPath 3.1 parse for RHS of general comparison operators, =, !=. 
+    	  // Previous token is, '='.
+    	  
+    	  // XPath parse for RHS of general comparison operators, =, !=. 
     	  // RHS of these operators that're handled here, have syntax of 
-    	  // type (a,b,c), i.e a literal sequence.
+    	  // type (a,b,c ...), i.e a literal sequence.
     	  
     	  TokenQueueScanPosition prevTokQueueScanPosition = new TokenQueueScanPosition(
                                                                                    m_queueMark, m_tokenChar, m_token);
@@ -2301,15 +2296,7 @@ public class XPathParser
         }
         else 
         {
-           // Support for XPath 3.1 simple map operator '!'.
-        	
-           // An XPath expression SEQ!Expr evaluates an expression Expr once for every 
-           // item in the sequence obtained by evaluating SEQ. An XPath language operator "!" 
-           // may be applied to any sequence, irrespective of types of its items. An evaluation 
-           // for XPath operator '!', may also result in mixed sequence of XPath nodes, atomic 
-           // values, and function items.
-        	
-           // Ref : https://www.w3.org/TR/xpath-31/#id-map-operator
+           // XPath parse of simple map operator '!'        	           
             
            nextToken();
            insertOp(addPos, 2, OpCodes.OP_SIMPLE_MAP_OPERATOR);
@@ -2336,7 +2323,7 @@ public class XPathParser
       }
       else if (tokenIs("eq"))
       {
-        // Support for XPath 3.1 value comparison operator "eq"
+        // XPath parse of value comparison operator "eq"
           
         nextToken();
         insertOp(addPos, 2, OpCodes.OP_VC_EQUALS);
@@ -2350,7 +2337,7 @@ public class XPathParser
       }
       else if (tokenIs("ne"))
       {
-        // Support for XPath 3.1 value comparison operator "ne"
+        // XPath parse of value comparison operator "ne"
           
         nextToken();
         insertOp(addPos, 2, OpCodes.OP_VC_NOT_EQUALS);
@@ -2404,10 +2391,10 @@ public class XPathParser
     
     if (tokenIs('(')) {
         if (isXPathGeneralRelationalComparisonWithSequence()) {
-        	// XPath 3.1 parse for RHS of general comparison relational 
+        	// XPath parse for RHS of general comparison relational 
         	// operators <, <=, >, >=.        	
-       	    // RHS for these operators that're handled here, have syntax 
-        	// of type (a,b,c), i.e a literal sequence.
+       	    // RHS for these XPath operators that're handled here, have 
+        	// syntax of type (a,b,c), i.e a literal sequence.
         	
         	TokenQueueScanPosition prevTokQueueScanPosition = new 
         			                                     TokenQueueScanPosition(m_queueMark, m_tokenChar, m_token);
@@ -2505,7 +2492,7 @@ public class XPathParser
         }
         else if (tokenIs('<'))
         {
-          // Support for XPath 3.1 node comparison operator "<<"
+          // XPath parse of node comparison operator "<<"
           
           nextToken();
           insertOp(addPos, 2, OpCodes.OP_NC_PRECEDE); 
@@ -2533,7 +2520,7 @@ public class XPathParser
         }
         else if (tokenIs('>'))
         {
-          // Support for XPath 3.1 node comparison operator ">>"
+          // XPath parse of node comparison operator ">>"
           
           nextToken();
           insertOp(addPos, 2, OpCodes.OP_NC_FOLLOWS);
@@ -2552,13 +2539,7 @@ public class XPathParser
       }
       else if (tokenIs("to"))
       {
-          // Support for XPath 3.1 range expression (i.e, an XPath operator "to").
-    	  
-    	  // An XPath language range expressions are used to construct a 
-    	  // sequence of consecutive integers. For e.g, an XPath language range expression
-    	  // "1 to 10" shall return following XPath result sequence (1, 2, 3, 4, 5, 6, 7, 8, 9, 10). 
-    	  
-    	  // Ref: https://www.w3.org/TR/xpath-31/#construct_seq    	  
+          // XPath parse of range "to" expression    	     	  
           
           nextToken();
           
@@ -2573,10 +2554,7 @@ public class XPathParser
       }
       else if (tokenIs("||"))
       {
-          // Support for XPath 3.1 string concatenation operator "||".
-    	  
-    	  // An XPath language string concatenation operator "||" may be used as an
-    	  // alternative means, for XPath string concatenation function 'concat'.
+          // XPath parse of string concatenation operator "||"    	  
           
           nextToken();
           
@@ -2591,7 +2569,7 @@ public class XPathParser
       }
       else if (tokenIs("=>"))
       {
-          // Support for XPath 3.1 arrow operator "=>"
+          // XPath parse of arrow operator "=>"
     	  
           consumeExpected("=>");
 
@@ -2610,7 +2588,7 @@ public class XPathParser
       }
       else if (tokenIs("lt"))
       {
-          // Support for XPath 3.1 value comparison operator "lt"
+          // XPath parse of value comparison operator "lt"
           
           nextToken();
         
@@ -2625,7 +2603,7 @@ public class XPathParser
       }
       else if (tokenIs("gt"))
       {
-          // Support for XPath 3.1 value comparison operator "gt"
+          // XPath parse of value comparison operator "gt"
           
           nextToken();
         
@@ -2640,7 +2618,7 @@ public class XPathParser
       }
       else if (tokenIs("le"))
       {
-          // Support for XPath 3.1 value comparison operator "le"
+          // XPath parse of value comparison operator "le"
           
           nextToken();
         
@@ -2655,7 +2633,7 @@ public class XPathParser
       }
       else if (tokenIs("ge"))
       {
-          // Support for XPath 3.1 value comparison operator "ge"
+          // XPath parse of value comparison operator "ge"
           
           nextToken();
         
@@ -2670,7 +2648,7 @@ public class XPathParser
       }
       else if (tokenIs("is"))
       {
-          // Support for XPath 3.1 node comparison operator "is"
+          // XPath parse of node comparison operator "is"
           
           nextToken();
         
@@ -2684,13 +2662,7 @@ public class XPathParser
           addPos += 2;
       }
       else if (tokenIs("instance") && lookahead("of", 1)) {
-          // Support for XPath 3.1 "instance of" expression.
-    	  
-    	  // An XPath language, "instance of" operator requires two operands. An 
-    	  // XPath evaluation for "instance of" expression returns value 'true',
-    	  // if the value of its first operand is of the type of its second operand.
-    	  
-    	  // Ref : https://www.w3.org/TR/xpath-31/#id-instance-of
+          // XPath parse of "instance of" expression    	  
           
           consumeExpected("instance");
           consumeExpected("of");
@@ -2705,12 +2677,7 @@ public class XPathParser
           addPos += 2;
       }      
       else if (tokenIs("cast") && lookahead("as", 1)) {
-          // Support for XPath 3.1 "cast as" expression.
-    	  
-    	  // An XPath expression "cast as" converts an input value, 
-    	  // to another value of a specific datatype.
-    	  
-    	  // Ref : https://www.w3.org/TR/xpath-31/#id-cast
+          // XPath parse of "cast as" expression    	  
           
           consumeExpected("cast");
           consumeExpected("as");
@@ -2726,12 +2693,7 @@ public class XPathParser
           addPos += 2;
       }
       else if (tokenIs("castable") && lookahead("as", 1)) {
-          // Support for XPath 3.1 "castable as" expression.
-    	  
-    	  // An XPath expression "castable as" tests (i.e, returns true, or false) 
-    	  // whether a given value is castable into another datatype.
-    	  
-    	  // Ref : https://www.w3.org/TR/xpath-31/#id-castable
+          // XPath parse of "castable as" expression    	  
           
           consumeExpected("castable");
           consumeExpected("as");
@@ -2753,7 +2715,7 @@ public class XPathParser
 
   /**
    * Check whether, there is XPath parse of general relational comparison using
-   * operators <,<=,>,>=.
+   * operators <, <=, >, >=.
    */
   private boolean isXPathGeneralRelationalComparisonWithSequence() {
 	  return ("<".equals(getTokenRelative(-2)) || 
@@ -3194,14 +3156,8 @@ public class XPathParser
       matchFound = true;
     }
     else if ((m_tokenChar == '$') && (lookahead('(', 2))) {
-       // Support for XPath 3.1 'dynamic function call' expression.
-    	
-       // For example, if an XPath inline function expression is bound
-       // to an XSLT variable as follows : <xsl:variable name="sqr" select="function($val) { $val * $val }"/>,
-       // then an XPath expression $sqr(5) shall return a value 25. For this example, 
-       // an XPath expression $sqr(5) is referred to as dynamic function call.
-    	
-       // Ref : https://www.w3.org/TR/xpath-31/#id-dynamic-function-invocation
+       // XPath parse of dynamic function call, & map and array
+       // information lookup using function call syntax.
                      
        appendOp(2, OpCodes.OP_DYNAMIC_FUNCTION_CALL);
        
@@ -3297,9 +3253,7 @@ public class XPathParser
       matchFound = true;
     }
     else if (tokenIs("function") && lookahead('(', 1)) {
-      // Support for XPath 3.1 "inline function" expression
-    	
-      // Ref : https://www.w3.org/TR/xpath-31/#id-inline-func
+      // XPath parse of inline function expression    	
       
       appendOp(2, OpCodes.OP_INLINE_FUNCTION);
       
@@ -3439,8 +3393,8 @@ public class XPathParser
     appendOp(2, OpCodes.OP_ARGUMENT);
     
     if (tokenIs('(')) {
-    	// XPath literal sequence as, function argument.
-    	// XPath 3.1 spec : 3.4.1 Constructing Sequences    	
+    	// XPath literal sequence as, function argument
+    	
     	TokenQueueScanPosition prevTokQueueScanPosition = new TokenQueueScanPosition(
     			                                                           m_queueMark, m_tokenChar, m_token);
     	if (lookahead(')', 1)) {
@@ -3502,8 +3456,8 @@ public class XPathParser
     	}
     }
     else if (tokenIs('[')) {
-    	// XPath literal square array as, function argument.
-    	// XPath 3.1 spec : 3.11.2.1 Array Constructors    	
+    	// XPath literal square array as, function argument
+    	
     	consumeExpected('[');    		
 
     	List<String> arrConstructorXPathParts = new ArrayList<String>();
@@ -3523,8 +3477,8 @@ public class XPathParser
     			                               m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);	       
     }
     else if (tokenIs("array") && lookahead('{', 1)) {
-    	// XPath literal curly array as, function argument.
-    	// XPath 3.1 spec : 3.11.2.1 Array Constructors    	
+    	// XPath literal curly array as, function argument
+    	
     	consumeExpected("array");
     	consumeExpected('{');
 
@@ -3551,8 +3505,8 @@ public class XPathParser
     else if (lookahead(':', 1)) {
     	TokenQueueScanPosition prevTokQueueScanPosition = new TokenQueueScanPosition(
                                                                                  m_queueMark, m_tokenChar, m_token);
-    	// Parse named function reference, for built-in functions
-    	// Ref : XPath 3.1 spec, "3.1.6 Named Function References"
+    	// XPath parse of named function reference, for built-in functions
+
     	if (tokenIs(FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI) || tokenIs(FunctionTable.XPATH_BUILT_IN_MATH_FUNCS_NS_URI) ||
     		tokenIs(FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI) || tokenIs(FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI)) {
     		String funcNamespaceUri = m_token;
@@ -3589,8 +3543,8 @@ public class XPathParser
     	}
     }
     else if (!m_token.contains(":") && m_token.contains("#") && isFuncArityWellFormedForNamedFuncRef(m_token)) {
-    	// Parse named function reference, for built-in functions
-    	// Ref : XPath 3.1 spec, "3.1.6 Named Function References"
+    	// XPath parse of named function reference, for built-in functions
+
     	TokenQueueScanPosition prevTokQueueScanPosition = new TokenQueueScanPosition(
                                                                                   m_queueMark, m_tokenChar, m_token);
     	String funcName = m_token.substring(0, m_token.indexOf('#'));
@@ -3632,160 +3586,6 @@ public class XPathParser
     
   }
 
-  /**
-   * This method is used to parse any of the following XPath literals : 
-   * 'sequence constructor', 'square array constructor', 'curly array 
-   * constructor'.
-   * 
-   * A valid pair of <lParen, rParen> characters, determine whether the
-   * token queue from current position incrementally shall be interpreted as
-   * one of the following XPath literals : 'sequence constructor', 'square array 
-   * constructor', or 'curly array constructor'.
-   * 
-   * @xpathExprPartList : String array, that'll be populated with xpath expression
-   *                      strings of the sequence/array items in order.
-   * @lParen            : This shall be one of following : '(', '[', '{'.
-   * @rParen            : This shall be one of following : ')', ']', '}'.                        
-   */
-  private void parseSequenceOrArrayConstructorFuncArg(List<String> xpathExprPartList, char lParen, 
-		                                                               char rParen) throws TransformerException {	  
-	  String xpathExpr = "";	  
-	  boolean fl1 = true;
-	  
-	  while (!tokenIs(rParen)) {
-		  if (!(tokenIs(',') || tokenIs(rParen))) {
-			  xpathExpr += m_token;
-			  nextToken();
-			  if (tokenIs(rParen) && !isStrHasBalancedParentheses(lParen + xpathExpr, lParen, rParen)) {
-				  if (lookahead(null, 1)) {
-					  xpathExprPartList.add(xpathExpr);
-					  break;
-				  }
-				  else if (lookahead(',', 1)) {
-					  xpathExprPartList.add(xpathExpr);
-					  xpathExpr = "";
-					  break;
-				  }
-				  else if (!xpathExpr.contains(lParen+"") && tokenIs(rParen)) {
-					  xpathExprPartList.add(xpathExpr);
-					  xpathExpr = "";
-					  break;
-				  }
-				  else {
-					  xpathExpr += m_token;
-				  }
-				  nextToken();
-				  if (tokenIs(rParen)) {
-					  if (isStrHasBalancedParentheses(lParen + xpathExpr + rParen, lParen, rParen) 
-							                                                    && !lookahead(rParen, 1)) {
-						  xpathExpr = (lParen + xpathExpr + m_token); 
-						  nextToken();
-						  fl1 = false;
-					  }
-				  }
-				  else {
-					  xpathExpr += m_token;
-					  nextToken();
-				  }
-			  }
-			  else if (fl1){		       	    
-				  if (tokenIs(',')) {
-					  xpathExprPartList.add(xpathExpr);
-					  xpathExpr = "";
-					  consumeExpected(',');
-				  }
-				  continue;
-			  }
-			  else {
-				  fl1 = true;
-				  xpathExpr += m_token;
-				  nextToken();
-				  break;
-			  }
-		  }
-		  else if (tokenIs(',')) {
-			  xpathExprPartList.add(xpathExpr);
-			  xpathExpr = "";
-			  consumeExpected(',');
-		  }
-	  } 
-  }
-
-  /**
-   * This method is used to parse, an XPath literal 'map' as 
-   * function argument.
-   */
-  private void mapFuncArg() throws TransformerException {	  
-
-	  int opPos1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
-	  
-	  nextToken();
-	  
-	  insertOp(opPos1, 2, OpCodes.OP_MAP_CONSTRUCTOR_EXPR);
-
-	  m_xpathMapConstructor = new XPathMapConstructor();
-	  
-	  Map<String, String> nativeMapObj = new HashMap<String, String>();                    
-
-	  consumeExpected('{');
-
-	  while (!tokenIs('}')) {        	 
-		  String mapEntryKeyXPathExprStr = m_token;
-		  nextToken();
-		  consumeExpected(':');
-		  String mapEntryValueXPathExprStr = null;
-		  if (tokenIs("map")) {
-			  // There's likely an XPath map constructor here, 
-			  // within this map. 	        		
-			  mapEntryValueXPathExprStr = getMapConstructorStrValue();
-		  }
-		  else if (tokenIs('[')) {
-			  // There's likely an XPath square array constructor here, 
-			  // within this map. 	        		
-			  mapEntryValueXPathExprStr = getXPathArrayConstructorStrValue(true); 
-		  }
-		  else if (tokenIs("array") && lookahead('{', 1)) {
-			  // There's likely an XPath curly array constructor here, 
-			  // within this map. 	        		
-			  mapEntryValueXPathExprStr = getXPathArrayConstructorStrValue(false); 
-		  }
-		  else {
-			  // The map's key value here is a simple value (i.e, not an array, or 
-			  // map).
-			  mapEntryValueXPathExprStr = m_token;
-			  while (!(tokenIs(',') || tokenIs('}'))) {
-				  nextToken();
-				  if (!(tokenIs(',') || tokenIs('}'))) {
-					  mapEntryValueXPathExprStr += m_token;
-				  }
-			  }
-		  }
-		  nativeMapObj.put(mapEntryKeyXPathExprStr, mapEntryValueXPathExprStr);
-		  if (tokenIs(',')) {
-			  consumeExpected(','); 
-		  }
-		  else if (tokenIs(']')) {
-			  consumeExpected(']');
-			  if (tokenIs(',')) {
-				  consumeExpected(','); 
-			  }
-			  else if (tokenIs('}')) {
-				  consumeExpected('}');
-				  break;
-			  }
-		  }
-		  else if (tokenIs('}')) {
-			  consumeExpected('}');
-			  break;
-		  }
-	  }
-
-	  m_xpathMapConstructor.setNativeMap(nativeMapObj);
-	  
-	  m_ops.setOp(opPos1 + OpMap.MAPINDEX_LENGTH,
-			                            m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos1);
-  }
-
   /**
    *
    * FunctionCall    ::=    FunctionName '(' ( Argument ( ',' Argument)*)? ')'
@@ -4840,700 +4640,7 @@ public class XPathParser
     m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
       m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
 
-    return trailingSlashConsumed;
-  }
-  
-  /**
-   * Parse XPath 'sequence type' expressions.
-   */
-  protected XPathSequenceTypeExpr SequenceTypeExpr(boolean isInlineFunction) 
-                                                                          throws javax.xml.transform.TransformerException {
-      int opPos = 0;
-      
-      if (!isInlineFunction) {
-         opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);                  
-         insertOp(opPos, 2, OpCodes.OP_SEQUENCE_TYPE_EXPR);
-      }
-      
-      XPathSequenceTypeExpr xpathSequenceTypeExpr = new XPathSequenceTypeExpr();
-      
-      SequenceTypeKindTest sequenceTypeKindTest = null;
-      
-      if (tokenIs("empty-sequence") && lookahead('(', 1) && lookahead(')', 2)) {
-         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.EMPTY_SEQUENCE);
-         consumeExpected("empty-sequence");
-         consumeExpected('(');
-         consumeExpected(')');
-      }      
-      else if (tokenIs("element")) {
-          sequenceTypeKindTest = constructSequenceTypeKindTestForXDMNodes(xpathSequenceTypeExpr, 
-                                                                                        SequenceTypeSupport.ELEMENT_KIND, isInlineFunction);          
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);          
-      }
-      else if (tokenIs("attribute")) {
-          sequenceTypeKindTest = constructSequenceTypeKindTestForXDMNodes(xpathSequenceTypeExpr, 
-                                                                                        SequenceTypeSupport.ATTRIBUTE_KIND, isInlineFunction);          
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
-      }
-      else if (tokenIs("text")) {
-          sequenceTypeKindTest = new SequenceTypeKindTest();
-          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.TEXT_KIND);          
-          nextToken();
-          consumeExpected('(');
-          consumeExpected(')');
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
-          if (m_token != null) {
-             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction); 
-          }          
-      }
-      else if (tokenIs("namespace-node")) {
-          sequenceTypeKindTest = new SequenceTypeKindTest();
-          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NAMESPACE_NODE_KIND);          
-          nextToken();
-          consumeExpected('(');
-          consumeExpected(')');
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
-          if (m_token != null) {
-             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction); 
-          }
-      }
-      else if (tokenIs("node")) { 
-          sequenceTypeKindTest = new SequenceTypeKindTest();
-          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NODE_KIND);          
-          nextToken();
-          consumeExpected('(');
-          consumeExpected(')');
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
-          if (m_token != null) {
-             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);  
-          }
-      }
-      else if (tokenIs("item")) {
-          sequenceTypeKindTest = new SequenceTypeKindTest();
-          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.ITEM_KIND);          
-          nextToken();
-          consumeExpected('(');
-          consumeExpected(')');
-          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
-          if (m_token != null) {
-             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);  
-          }
-      }
-      else if (tokenIs("function")) {
-    	  parseFunctionItemSequenceType(xpathSequenceTypeExpr);
-      }
-      else if (tokenIs("map")) {
-    	  parseXdmMapSequenceType(xpathSequenceTypeExpr);    	  
-      }
-      else if (tokenIs("array")) {
-          parseXdmArraySequenceType(xpathSequenceTypeExpr);
-      }
-      else if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
-          parseXdmBuiltInXmlSchemaSequenceType(isInlineFunction, xpathSequenceTypeExpr);         
-      }
-      else {
-          throw new javax.xml.transform.TransformerException("XPST0051 The sequence type '" + m_token + "' is not "
-                                                                                   + "recognized, within the provided sequence type expression."); 
-      }
-      
-      if (!isInlineFunction) {
-         m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
-                                                m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
-      }
-      
-      return xpathSequenceTypeExpr;
-  }
-
-  /**
-   * Parse XPath built-in XML Schema sequence type expressions.
-   */
-  private void parseXdmBuiltInXmlSchemaSequenceType(boolean isInlineFunction, XPathSequenceTypeExpr xpathSequenceTypeExpr)
-		                                                         throws TransformerException {	  
-	  
-	  consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-	  consumeExpected(':');
-	  
-	  switch (m_token) {
-	     case Keywords.FUNC_BOOLEAN_STRING :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.BOOLEAN);
-	        break;
-	     case Keywords.XS_STRING :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.STRING);
-	        break; 
-	     case Keywords.XS_NORMALIZED_STRING :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
-	         break;
-	     case Keywords.XS_TOKEN :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_TOKEN);
-	         break;
-	     case Keywords.XS_DECIMAL :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
-	        break; 
-	     case Keywords.XS_FLOAT :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_FLOAT);
-	        break; 
-	     case Keywords.XS_DOUBLE :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
-	        break;
-	     case Keywords.XS_INTEGER :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INTEGER);
-	        break;
-	     case Keywords.XS_NON_POSITIVE_INTEGER :
-		    xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
-		    break;
-	     case Keywords.XS_NEGATIVE_INTEGER :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
-			break;
-	     case Keywords.XS_NON_NEGATIVE_INTEGER :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
-			break;
-	     case Keywords.XS_POSITIVE_INTEGER :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
-			break;
-	     case Keywords.XS_LONG :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_LONG);
-	        break; 
-	     case Keywords.XS_INT :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INT);
-	        break;
-	     case Keywords.XS_SHORT :
-		    xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_SHORT);
-		    break;
-	     case Keywords.XS_BYTE :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_BYTE);
-			break;
-	     case Keywords.XS_UNSIGNED_LONG :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
-			break;
-	     case Keywords.XS_UNSIGNED_INT :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
-			break;
-	     case Keywords.XS_UNSIGNED_SHORT :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
-			break;
-	     case Keywords.XS_UNSIGNED_BYTE :
-			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
-			break;
-	     case Keywords.XS_DATE :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DATE);
-	        break;
-	     case Keywords.XS_DATETIME :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DATETIME);
-	        break;
-	     case Keywords.XS_DURATION :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DURATION);
-	        break;
-	     case Keywords.XS_YEAR_MONTH_DURATION :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
-	        break;
-	     case Keywords.XS_DAY_TIME_DURATION :
-	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
-	        break;
-	     case Keywords.XS_TIME :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_TIME);
-	         break;
-	     case Keywords.XS_ANY_URI :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
-	         break;
-	     case Keywords.XS_QNAME :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_QNAME);
-	         break;
-	     case Keywords.XS_ANY_ATOMIC_TYPE :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
-	         break;
-	     case Keywords.XS_UNTYPED_ATOMIC :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
-	         break;
-	     case Keywords.XS_UNTYPED :
-	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
-	         break;
-	     default :
-	        throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
-	                                                                                   + "recognized, within the provided sequence type expression.");        
-	  }
-	  
-	  nextToken();
-	  
-	  if ((m_token != null) && (xpathSequenceTypeExpr.getSequenceType() > 0)) {
-	     setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);
-	  }
-  }
-
-  /**
-   * Parse XPath 'array' sequence type expressions.
-   */
-  private void parseXdmArraySequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
-	  
-	  SequenceTypeArrayTest sequenceTypeArrayTest = null;
-	  
-	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
-		  // handles ArrayTest of variety AnyArrayTest
-		  sequenceTypeArrayTest = new SequenceTypeArrayTest();
-		  sequenceTypeArrayTest.setIsAnyArrayTest(true);
-		  nextToken();
-		  consumeExpected('(');
-	      consumeExpected('*');
-	      consumeExpected(')');
-	      xpathSequenceTypeExpr.setSequenceTypeArrayTest(sequenceTypeArrayTest);
-	  }
-	  else {
-		  // handles ArrayTest of variety TypedArrayTest
-		  sequenceTypeArrayTest = new SequenceTypeArrayTest();
-		  nextToken();
-		  consumeExpected('(');
-		  
-		  SequenceTypeData arrayItemSequenceType = new SequenceTypeData();
-		  while ((m_token != null) && !tokenIs(')')) {
-			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
-			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-			    consumeExpected(':');
-			    
-			    switch (m_token) {
-		            case Keywords.FUNC_BOOLEAN_STRING :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.BOOLEAN);
-		                break;
-		            case Keywords.XS_STRING :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.STRING);
-		                break; 
-		            case Keywords.XS_NORMALIZED_STRING :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
-		                break;
-		            case Keywords.XS_TOKEN :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_TOKEN);
-		                break;
-		            case Keywords.XS_DECIMAL :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
-		                break; 
-		            case Keywords.XS_FLOAT :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_FLOAT);
-		                break; 
-		            case Keywords.XS_DOUBLE :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
-		                break;
-		            case Keywords.XS_INTEGER :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_INTEGER);
-		                break;
-		            case Keywords.XS_NON_POSITIVE_INTEGER :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NEGATIVE_INTEGER :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NON_NEGATIVE_INTEGER :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_POSITIVE_INTEGER :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_LONG :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_LONG);
-		                break; 
-		            case Keywords.XS_INT :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_INT);
-		                break;
-		            case Keywords.XS_SHORT :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_SHORT);
-		                break;
-		            case Keywords.XS_BYTE :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_BYTE);
-		                break;
-		            case Keywords.XS_UNSIGNED_LONG :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
-		                break;
-		            case Keywords.XS_UNSIGNED_INT :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
-		                break;
-		            case Keywords.XS_UNSIGNED_SHORT :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
-		                break;
-		            case Keywords.XS_UNSIGNED_BYTE :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
-		                break;
-		            case Keywords.XS_DATE :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DATE);
-		                break;
-		            case Keywords.XS_DATETIME :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DATETIME);
-		                break;
-		            case Keywords.XS_DURATION :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DURATION);
-		                break;
-		            case Keywords.XS_YEAR_MONTH_DURATION :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
-		                break;
-		            case Keywords.XS_DAY_TIME_DURATION :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
-		                break;
-		            case Keywords.XS_TIME :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_TIME);
-		                break;
-		            case Keywords.XS_ANY_URI :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
-		                break;
-		            case Keywords.XS_QNAME :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_QNAME);
-		                break;
-		            case Keywords.XS_ANY_ATOMIC_TYPE :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
-		                break;
-		            case Keywords.XS_UNTYPED_ATOMIC :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
-		                break;
-		            case Keywords.XS_UNTYPED :
-		            	arrayItemSequenceType.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
-		                break;
-		            default :
-		               throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
-	                                                                                          + "recognized, within the provided sequence type expression.");        
-	           }
-			 
-			   nextToken();
-		     }
-		 }
-		  
-		 consumeExpected(')');
-		  
-		 sequenceTypeArrayTest.setArrayItemTypeInfo(arrayItemSequenceType);  	    	  
-		 xpathSequenceTypeExpr.setSequenceTypeArrayTest(sequenceTypeArrayTest); 
-	  }
-  }
-
-  /**
-   * Parse XPath 'map' sequence type expressions.
-   */
-  private void parseXdmMapSequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
-	  
-	  SequenceTypeMapTest sequenceTypeMapTest = null;
-	  
-	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
-		  // handles MapTest of variety AnyMapTest
-		  sequenceTypeMapTest = new SequenceTypeMapTest();
-		  sequenceTypeMapTest.setIsAnyMapTest(true);
-		  nextToken();
-		  consumeExpected('(');
-	      consumeExpected('*');
-	      consumeExpected(')');
-	      xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
-	  }
-	  else {
-		  // handles MapTest of variety TypedMapTest
-		  sequenceTypeMapTest = new SequenceTypeMapTest();
-		  nextToken();
-		  consumeExpected('(');
-		  
-		  SequenceTypeData keySequenceTypeData = new SequenceTypeData();    		  
-		  SequenceTypeData valueSequenceTypeData = new SequenceTypeData();
-		  
-		  while ((m_token != null) && !tokenIs(',')) {
-			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
-			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-			    consumeExpected(':');
-			    
-			    switch (m_token) {
-		            case Keywords.FUNC_BOOLEAN_STRING :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.BOOLEAN);
-		                break;
-		            case Keywords.XS_STRING :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.STRING);
-		                break; 
-		            case Keywords.XS_NORMALIZED_STRING :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
-		                break;
-		            case Keywords.XS_TOKEN :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TOKEN);
-		                break;
-		            case Keywords.XS_DECIMAL :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
-		                break; 
-		            case Keywords.XS_FLOAT :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_FLOAT);
-		                break; 
-		            case Keywords.XS_DOUBLE :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
-		                break;
-		            case Keywords.XS_INTEGER :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INTEGER);
-		                break;
-		            case Keywords.XS_NON_POSITIVE_INTEGER :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NEGATIVE_INTEGER :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NON_NEGATIVE_INTEGER :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_POSITIVE_INTEGER :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_LONG :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_LONG);
-		                break; 
-		            case Keywords.XS_INT :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INT);
-		                break;
-		            case Keywords.XS_SHORT :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_SHORT);
-		                break;
-		            case Keywords.XS_BYTE :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_BYTE);
-		                break;
-		            case Keywords.XS_UNSIGNED_LONG :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
-		                break;
-		            case Keywords.XS_UNSIGNED_INT :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
-		                break;
-		            case Keywords.XS_UNSIGNED_SHORT :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
-		                break;
-		            case Keywords.XS_UNSIGNED_BYTE :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
-		                break;
-		            case Keywords.XS_DATE :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATE);
-		                break;
-		            case Keywords.XS_DATETIME :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATETIME);
-		                break;
-		            case Keywords.XS_DURATION :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DURATION);
-		                break;
-		            case Keywords.XS_YEAR_MONTH_DURATION :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
-		                break;
-		            case Keywords.XS_DAY_TIME_DURATION :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
-		                break;
-		            case Keywords.XS_TIME :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TIME);
-		                break;
-		            case Keywords.XS_ANY_URI :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
-		                break;
-		            case Keywords.XS_QNAME :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_QNAME);
-		                break;
-		            case Keywords.XS_ANY_ATOMIC_TYPE :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
-		                break;
-		            case Keywords.XS_UNTYPED_ATOMIC :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
-		                break;
-		            case Keywords.XS_UNTYPED :
-		            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
-		                break;
-		            default :
-		                throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
-	                                                                                          + "recognized, within the provided sequence type expression.");        
-	         }
-			 
-			 nextToken();
-		   }
-		}
-		  
-		consumeExpected(',');
-		  
-		while ((m_token != null) && !tokenIs(')')) {
-			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
-			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-			    consumeExpected(':');
-			    
-			    switch (m_token) {
-		            case Keywords.FUNC_BOOLEAN_STRING :
-		                valueSequenceTypeData.setSequenceType(SequenceTypeSupport.BOOLEAN);
-		                break;
-		            case Keywords.XS_STRING :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.STRING);
-		                break; 
-		            case Keywords.XS_NORMALIZED_STRING :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
-		                break;
-		            case Keywords.XS_TOKEN :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TOKEN);
-		                break;
-		            case Keywords.XS_DECIMAL :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
-		                break; 
-		            case Keywords.XS_FLOAT :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_FLOAT);
-		                break; 
-		            case Keywords.XS_DOUBLE :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
-		                break;
-		            case Keywords.XS_INTEGER :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INTEGER);
-		                break;
-		            case Keywords.XS_NON_POSITIVE_INTEGER :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NEGATIVE_INTEGER :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_NON_NEGATIVE_INTEGER :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
-		                break;
-		            case Keywords.XS_POSITIVE_INTEGER :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
-		                break;
-		            case Keywords.XS_LONG :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_LONG);
-		                break; 
-		            case Keywords.XS_INT :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INT);
-		                break;
-		            case Keywords.XS_SHORT :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_SHORT);
-		                break;
-		            case Keywords.XS_BYTE :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_BYTE);
-		                break;
-		            case Keywords.XS_UNSIGNED_LONG :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
-		                break;
-		            case Keywords.XS_UNSIGNED_INT :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
-		                break;
-		            case Keywords.XS_UNSIGNED_SHORT :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
-		                break;
-		            case Keywords.XS_UNSIGNED_BYTE :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
-		                break;
-		            case Keywords.XS_DATE :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATE);
-		                break;
-		            case Keywords.XS_DATETIME :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATETIME);
-		                break;
-		            case Keywords.XS_DURATION :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DURATION);
-		                break;
-		            case Keywords.XS_YEAR_MONTH_DURATION :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
-		                break;
-		            case Keywords.XS_DAY_TIME_DURATION :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
-		                break;
-		            case Keywords.XS_TIME :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TIME);
-		                break;
-		            case Keywords.XS_ANY_URI :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
-		                break;
-		            case Keywords.XS_QNAME :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_QNAME);
-		                break;
-		            case Keywords.XS_ANY_ATOMIC_TYPE :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
-		                break;
-		            case Keywords.XS_UNTYPED_ATOMIC :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
-		                break;
-		            case Keywords.XS_UNTYPED :
-		            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
-		                break;
-		            default :
-		                throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
-	                                                                                          + "recognized, within the provided sequence type expression.");        
-	         }    	             	         
-	         
-	         nextToken();     	         
-	         consumeExpected(')');
-		   }     			      		   
-		}
-		
-		sequenceTypeMapTest.setKeySequenceTypeData(keySequenceTypeData);
-		sequenceTypeMapTest.setValueSequenceTypeData(valueSequenceTypeData);
-		  
-		xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
-	 }
-  }
-
-  /**
-   * Parse XPath 'function item' sequence type expressions.
-   */
-  private void parseFunctionItemSequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
-	
-	  SequenceTypeFunctionTest sequenceTypeFunctionTest = null;
-	  
-	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
-		  // handles FunctionTest of variety AnyFunctionTest
-		  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
-		  sequenceTypeFunctionTest.setIsAnyFunctionTest(true);
-		  nextToken();
-		  consumeExpected('(');
-	      consumeExpected('*');
-	      consumeExpected(')');
-	      xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
-	  }
-	  else {
-		  // handles FunctionTest of variety TypedFunctionTest
-		  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
-		  nextToken();
-		  consumeExpected('(');
-		  List<String> typedFunctionTestPrefixList = new ArrayList<String>();    		  
-		  if (!lookahead(')', 1)) {
-			 // There's at-least one parameter definition, for TypedFunctionTest
-			 String typedFunctionTestPrefixPart = "";
-			 while (m_token != null) {
-				if (!(tokenIs(',') || tokenIs(')'))) {
-				   typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
-				   nextToken();
-				}
-				else if (tokenIs(',')) {
-				   if (!isStrHasBalancedParentheses(typedFunctionTestPrefixPart, '(', ')')) {
-				      typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
-				      nextToken();
-				   }
-				   else {
-					  typedFunctionTestPrefixList.add(typedFunctionTestPrefixPart);
-					  typedFunctionTestPrefixPart = "";
-					  if (tokenIs(')')) {
-						 break;  
-					  }
-					  else {
-					     nextToken();
-					  }
-				   }
-				}
-				else if (tokenIs(')')) {
-				   if (lookahead(',', 1) || lookahead(')', 1) || lookahead('*', 1) || 
-						                    lookahead('+', 1) || lookahead('?', 1)) {
-					  typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
-					  nextToken(); 
-				   }
-				   else {
-					  typedFunctionTestPrefixList.add(typedFunctionTestPrefixPart);
-	 				  typedFunctionTestPrefixPart = "";
-	 				  if (tokenIs(')')) {
-					     break;  
-				      }
-				      else {
-				         nextToken();
-				      }
-				   }
-				}
-			 }
-		  }
-		  
-		  sequenceTypeFunctionTest.setTypedFunctionTestPrefixList(typedFunctionTestPrefixList);
-		  
-		  consumeExpected(')');
-		  consumeExpected("as");
-		  
-		  String typedFunctionTestReturnType = "";
-		  while (m_token != null) {
-			 typedFunctionTestReturnType = typedFunctionTestReturnType + m_token;
-			 nextToken();
-		  }
-		  
-		  if (!"".equals(typedFunctionTestReturnType)) {
-			 sequenceTypeFunctionTest.setTypedFunctionTestReturnType(typedFunctionTestReturnType);  
-		  }
-		  
-		  xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
-	  }	  
+     return trailingSlashConsumed;
    }
   
    public String getArrowOpRemainingXPathExprStr() {
@@ -5541,16 +4648,677 @@ public class XPathParser
    }
    
    /**
-    * Sometimes, during an XPath expression parse, the current parse
+    * This method is used to parse any of the following XPath literals : 
+    * 'sequence constructor', 'square array constructor', 'curly array 
+    * constructor'.
+    * 
+    * A valid pair of <lParen, rParen> characters, determine whether the
+    * token queue from current position incrementally shall be interpreted as
+    * one of the following XPath literals : 'sequence constructor', 'square array 
+    * constructor', or 'curly array constructor'.
+    * 
+    * @param       xpathExprPartList    String array, that'll be populated with xpath expression
+    *                                   strings of the sequence/array items in order.
+    * @param       lParen               This shall be one of following : '(', '[', '{'.
+    * @param       rParen               This shall be one of following : ')', ']', '}'.                        
+    */
+   private void parseSequenceOrArrayConstructorFuncArg(List<String> xpathExprPartList, char lParen, 
+ 		                                                                               char rParen) throws TransformerException {	  
+ 	  String xpathExpr = "";	  
+ 	  boolean fl1 = true;
+ 	  
+ 	  while (!tokenIs(rParen)) {
+ 		  if (!(tokenIs(',') || tokenIs(rParen))) {
+ 			  xpathExpr += m_token;
+ 			  nextToken();
+ 			  if (tokenIs(rParen) && !isStrHasBalancedParentheses(lParen + xpathExpr, lParen, rParen)) {
+ 				  if (lookahead(null, 1)) {
+ 					  xpathExprPartList.add(xpathExpr);
+ 					  break;
+ 				  }
+ 				  else if (lookahead(',', 1)) {
+ 					  xpathExprPartList.add(xpathExpr);
+ 					  xpathExpr = "";
+ 					  break;
+ 				  }
+ 				  else if (!xpathExpr.contains(lParen+"") && tokenIs(rParen)) {
+ 					  xpathExprPartList.add(xpathExpr);
+ 					  xpathExpr = "";
+ 					  break;
+ 				  }
+ 				  else {
+ 					  xpathExpr += m_token;
+ 				  }
+ 				  nextToken();
+ 				  if (tokenIs(rParen)) {
+ 					  if (isStrHasBalancedParentheses(lParen + xpathExpr + rParen, lParen, rParen) 
+ 							                                                    && !lookahead(rParen, 1)) {
+ 						  xpathExpr = (lParen + xpathExpr + m_token); 
+ 						  nextToken();
+ 						  fl1 = false;
+ 					  }
+ 				  }
+ 				  else {
+ 					  xpathExpr += m_token;
+ 					  nextToken();
+ 				  }
+ 			  }
+ 			  else if (fl1){		       	    
+ 				  if (tokenIs(',')) {
+ 					  xpathExprPartList.add(xpathExpr);
+ 					  xpathExpr = "";
+ 					  consumeExpected(',');
+ 				  }
+ 				  continue;
+ 			  }
+ 			  else {
+ 				  fl1 = true;
+ 				  xpathExpr += m_token;
+ 				  nextToken();
+ 				  break;
+ 			  }
+ 		  }
+ 		  else if (tokenIs(',')) {
+ 			  xpathExprPartList.add(xpathExpr);
+ 			  xpathExpr = "";
+ 			  consumeExpected(',');
+ 		  }
+ 	  } 
+   }
+   
+   /**
+    * XPath parse of literal map as function argument.
+    */
+   private void mapFuncArg() throws TransformerException {	  
+
+ 	  int opPos1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+ 	  
+ 	  nextToken();
+ 	  
+ 	  insertOp(opPos1, 2, OpCodes.OP_MAP_CONSTRUCTOR_EXPR);
+
+ 	  m_xpathMapConstructor = new XPathMapConstructor();
+ 	  
+ 	  Map<String, String> nativeMapObj = new HashMap<String, String>();                    
+
+ 	  consumeExpected('{');
+
+ 	  while (!tokenIs('}')) {        	 
+ 		  String mapEntryKeyXPathExprStr = m_token;
+ 		  nextToken();
+ 		  consumeExpected(':');
+ 		  String mapEntryValueXPathExprStr = null;
+ 		  if (tokenIs("map")) {
+ 			  // There's likely an XPath map constructor here, 
+ 			  // within this map. 	        		
+ 			  mapEntryValueXPathExprStr = getMapConstructorStrValue();
+ 		  }
+ 		  else if (tokenIs('[')) {
+ 			  // There's likely an XPath square array constructor here, 
+ 			  // within this map. 	        		
+ 			  mapEntryValueXPathExprStr = getXPathArrayConstructorStrValue(true); 
+ 		  }
+ 		  else if (tokenIs("array") && lookahead('{', 1)) {
+ 			  // There's likely an XPath curly array constructor here, 
+ 			  // within this map. 	        		
+ 			  mapEntryValueXPathExprStr = getXPathArrayConstructorStrValue(false); 
+ 		  }
+ 		  else {
+ 			  // The map's key value here is a simple value (i.e, not an array, or 
+ 			  // map).
+ 			  mapEntryValueXPathExprStr = m_token;
+ 			  while (!(tokenIs(',') || tokenIs('}'))) {
+ 				  nextToken();
+ 				  if (!(tokenIs(',') || tokenIs('}'))) {
+ 					  mapEntryValueXPathExprStr += m_token;
+ 				  }
+ 			  }
+ 		  }
+ 		  nativeMapObj.put(mapEntryKeyXPathExprStr, mapEntryValueXPathExprStr);
+ 		  if (tokenIs(',')) {
+ 			  consumeExpected(','); 
+ 		  }
+ 		  else if (tokenIs(']')) {
+ 			  consumeExpected(']');
+ 			  if (tokenIs(',')) {
+ 				  consumeExpected(','); 
+ 			  }
+ 			  else if (tokenIs('}')) {
+ 				  consumeExpected('}');
+ 				  break;
+ 			  }
+ 		  }
+ 		  else if (tokenIs('}')) {
+ 			  consumeExpected('}');
+ 			  break;
+ 		  }
+ 	  }
+
+ 	  m_xpathMapConstructor.setNativeMap(nativeMapObj);
+ 	  
+ 	  m_ops.setOp(opPos1 + OpMap.MAPINDEX_LENGTH,
+ 			                            m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos1);
+   }
+   
+   /**
+    * XPath parse of sequence type expressions.
+    */
+   private XPathSequenceTypeExpr SequenceTypeExpr(boolean isInlineFunction) 
+ 		                                                                 throws javax.xml.transform.TransformerException {
+       int opPos = 0;
+       
+       if (!isInlineFunction) {
+          opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);                  
+          insertOp(opPos, 2, OpCodes.OP_SEQUENCE_TYPE_EXPR);
+       }
+       
+       XPathSequenceTypeExpr xpathSequenceTypeExpr = new XPathSequenceTypeExpr();
+       
+       SequenceTypeKindTest sequenceTypeKindTest = null;
+       
+       if (tokenIs("empty-sequence") && lookahead('(', 1) && lookahead(')', 2)) {
+           xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.EMPTY_SEQUENCE);
+           consumeExpected("empty-sequence");
+           consumeExpected('(');
+           consumeExpected(')');
+       }      
+       else if (tokenIs("element")) {
+           sequenceTypeKindTest = constructSequenceTypeKindTestForXDMNodes(xpathSequenceTypeExpr, 
+                                                                                         SequenceTypeSupport.ELEMENT_KIND, isInlineFunction);          
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);          
+       }
+       else if (tokenIs("attribute")) {
+           sequenceTypeKindTest = constructSequenceTypeKindTestForXDMNodes(xpathSequenceTypeExpr, 
+                                                                                         SequenceTypeSupport.ATTRIBUTE_KIND, isInlineFunction);          
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+       }
+       else if (tokenIs("text")) {
+           sequenceTypeKindTest = new SequenceTypeKindTest();
+           sequenceTypeKindTest.setKindVal(SequenceTypeSupport.TEXT_KIND);          
+           nextToken();
+           consumeExpected('(');
+           consumeExpected(')');
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+           if (m_token != null) {
+              setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction); 
+           }          
+       }
+       else if (tokenIs("namespace-node")) {
+           sequenceTypeKindTest = new SequenceTypeKindTest();
+           sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NAMESPACE_NODE_KIND);          
+           nextToken();
+           consumeExpected('(');
+           consumeExpected(')');
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+           if (m_token != null) {
+              setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction); 
+           }
+       }
+       else if (tokenIs("node")) { 
+           sequenceTypeKindTest = new SequenceTypeKindTest();
+           sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NODE_KIND);          
+           nextToken();
+           consumeExpected('(');
+           consumeExpected(')');
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+           if (m_token != null) {
+              setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);  
+           }
+       }
+       else if (tokenIs("item")) {
+           sequenceTypeKindTest = new SequenceTypeKindTest();
+           sequenceTypeKindTest.setKindVal(SequenceTypeSupport.ITEM_KIND);          
+           nextToken();
+           consumeExpected('(');
+           consumeExpected(')');
+           xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+           if (m_token != null) {
+              setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);  
+           }
+       }
+       else if (tokenIs("function")) {
+     	   parseFunctionItemSequenceType(xpathSequenceTypeExpr);
+       }
+       else if (tokenIs("map")) {
+     	   parseXdmMapSequenceType(xpathSequenceTypeExpr);    	  
+       }
+       else if (tokenIs("array")) {
+           parseXdmArraySequenceType(xpathSequenceTypeExpr);
+       }
+       else if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+           parseXdmBuiltInXmlSchemaSequenceType(isInlineFunction, xpathSequenceTypeExpr);         
+       }
+       else {
+           throw new javax.xml.transform.TransformerException("XPST0051 The sequence type '" + m_token + "' is not "
+                                                                                    + "recognized, within the provided sequence type expression."); 
+       }
+       
+       if (!isInlineFunction) {
+          m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+                                                 m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+       }
+       
+       return xpathSequenceTypeExpr;
+   }
+   
+   /**
+    * XPath parse of built-in XML Schema sequence type expressions.
+    */
+   private void parseXdmBuiltInXmlSchemaSequenceType(boolean isInlineFunction, XPathSequenceTypeExpr xpathSequenceTypeExpr)
+ 		                                                                      throws TransformerException {	  
+ 	  
+ 	  consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ 	  consumeExpected(':');
+ 	  
+ 	  switch (m_token) {
+ 	     case Keywords.FUNC_BOOLEAN_STRING :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.BOOLEAN);
+ 	        break;
+ 	     case Keywords.XS_STRING :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.STRING);
+ 	        break; 
+ 	     case Keywords.XS_NORMALIZED_STRING :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
+ 	         break;
+ 	     case Keywords.XS_TOKEN :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_TOKEN);
+ 	         break;
+ 	     case Keywords.XS_DECIMAL :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
+ 	        break; 
+ 	     case Keywords.XS_FLOAT :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_FLOAT);
+ 	        break; 
+ 	     case Keywords.XS_DOUBLE :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
+ 	        break;
+ 	     case Keywords.XS_INTEGER :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INTEGER);
+ 	        break;
+ 	     case Keywords.XS_NON_POSITIVE_INTEGER :
+ 		    xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
+ 		    break;
+ 	     case Keywords.XS_NEGATIVE_INTEGER :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
+ 			break;
+ 	     case Keywords.XS_NON_NEGATIVE_INTEGER :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
+ 			break;
+ 	     case Keywords.XS_POSITIVE_INTEGER :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
+ 			break;
+ 	     case Keywords.XS_LONG :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_LONG);
+ 	        break; 
+ 	     case Keywords.XS_INT :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INT);
+ 	        break;
+ 	     case Keywords.XS_SHORT :
+ 		    xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_SHORT);
+ 		    break;
+ 	     case Keywords.XS_BYTE :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_BYTE);
+ 			break;
+ 	     case Keywords.XS_UNSIGNED_LONG :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
+ 			break;
+ 	     case Keywords.XS_UNSIGNED_INT :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
+ 			break;
+ 	     case Keywords.XS_UNSIGNED_SHORT :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
+ 			break;
+ 	     case Keywords.XS_UNSIGNED_BYTE :
+ 			xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
+ 			break;
+ 	     case Keywords.XS_DATE :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DATE);
+ 	        break;
+ 	     case Keywords.XS_DATETIME :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DATETIME);
+ 	        break;
+ 	     case Keywords.XS_DURATION :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DURATION);
+ 	        break;
+ 	     case Keywords.XS_YEAR_MONTH_DURATION :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
+ 	        break;
+ 	     case Keywords.XS_DAY_TIME_DURATION :
+ 	        xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
+ 	        break;
+ 	     case Keywords.XS_TIME :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_TIME);
+ 	         break;
+ 	     case Keywords.XS_ANY_URI :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
+ 	         break;
+ 	     case Keywords.XS_QNAME :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_QNAME);
+ 	         break;
+ 	     case Keywords.XS_ANY_ATOMIC_TYPE :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
+ 	         break;
+ 	     case Keywords.XS_UNTYPED_ATOMIC :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
+ 	         break;
+ 	     case Keywords.XS_UNTYPED :
+ 	         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
+ 	         break;
+ 	     default :
+ 	        throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
+ 	                                                                                   + "recognized, within the provided sequence type expression.");        
+ 	  }
+ 	  
+ 	  nextToken();
+ 	  
+ 	  if ((m_token != null) && (xpathSequenceTypeExpr.getSequenceType() > 0)) {
+ 	     setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr, isInlineFunction);
+ 	  }
+   }
+   
+   /**
+    * XPath parse of function item sequence type expressions.
+    */
+   private void parseFunctionItemSequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
+ 	
+ 	  SequenceTypeFunctionTest sequenceTypeFunctionTest = null;
+ 	  
+ 	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
+ 		  // sequence type FunctionTest of variety AnyFunctionTest
+ 		  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
+ 		  sequenceTypeFunctionTest.setIsAnyFunctionTest(true);
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 	      consumeExpected('*');
+ 	      consumeExpected(')');
+ 	      xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
+ 	  }
+ 	  else {
+ 		  // sequence type FunctionTest of variety TypedFunctionTest
+ 		  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 		  List<String> typedFunctionTestPrefixList = new ArrayList<String>();    		  
+ 		  if (!lookahead(')', 1)) {
+ 			 // There's at-least one parameter definition, for TypedFunctionTest
+ 			 String typedFunctionTestPrefixPart = "";
+ 			 while (m_token != null) {
+ 				if (!(tokenIs(',') || tokenIs(')'))) {
+ 				   typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
+ 				   nextToken();
+ 				}
+ 				else if (tokenIs(',')) {
+ 				   if (!isStrHasBalancedParentheses(typedFunctionTestPrefixPart, '(', ')')) {
+ 				      typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
+ 				      nextToken();
+ 				   }
+ 				   else {
+ 					  typedFunctionTestPrefixList.add(typedFunctionTestPrefixPart);
+ 					  typedFunctionTestPrefixPart = "";
+ 					  if (tokenIs(')')) {
+ 						 break;  
+ 					  }
+ 					  else {
+ 					     nextToken();
+ 					  }
+ 				   }
+ 				}
+ 				else if (tokenIs(')')) {
+ 				   if (lookahead(',', 1) || lookahead(')', 1) || lookahead('*', 1) || 
+ 						                    lookahead('+', 1) || lookahead('?', 1)) {
+ 					  typedFunctionTestPrefixPart = typedFunctionTestPrefixPart + m_token;
+ 					  nextToken(); 
+ 				   }
+ 				   else {
+ 					  typedFunctionTestPrefixList.add(typedFunctionTestPrefixPart);
+ 	 				  typedFunctionTestPrefixPart = "";
+ 	 				  if (tokenIs(')')) {
+ 					     break;  
+ 				      }
+ 				      else {
+ 				         nextToken();
+ 				      }
+ 				   }
+ 				}
+ 			 }
+ 		  }
+ 		  
+ 		  sequenceTypeFunctionTest.setTypedFunctionTestPrefixList(typedFunctionTestPrefixList);
+ 		  
+ 		  consumeExpected(')');
+ 		  consumeExpected("as");
+ 		  
+ 		  String typedFunctionTestReturnType = "";
+ 		  while (m_token != null) {
+ 			 typedFunctionTestReturnType = typedFunctionTestReturnType + m_token;
+ 			 nextToken();
+ 		  }
+ 		  
+ 		  if (!"".equals(typedFunctionTestReturnType)) {
+ 			 sequenceTypeFunctionTest.setTypedFunctionTestReturnType(typedFunctionTestReturnType);  
+ 		  }
+ 		  
+ 		  xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
+ 	  }	  
+    }
+
+   /**
+    * XPath parse of map sequence type expressions.
+    */
+   private void parseXdmMapSequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
+ 	  
+ 	  SequenceTypeMapTest sequenceTypeMapTest = null;
+ 	  
+ 	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
+ 		  // sequence type MapTest with variety AnyMapTest
+ 		  sequenceTypeMapTest = new SequenceTypeMapTest();
+ 		  sequenceTypeMapTest.setIsAnyMapTest(true);
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 	      consumeExpected('*');
+ 	      consumeExpected(')');
+ 	      xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
+ 	  }
+ 	  else {
+ 		  // sequence type MapTest with variety TypedMapTest
+ 		  sequenceTypeMapTest = new SequenceTypeMapTest();
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 		  
+ 		  SequenceTypeData keySequenceTypeData = new SequenceTypeData();    		  
+ 		  SequenceTypeData valueSequenceTypeData = new SequenceTypeData();
+ 		  
+ 		  while ((m_token != null) && !tokenIs(',')) {
+ 			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+ 			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ 			    consumeExpected(':');
+ 			    
+ 			    populateSequenceTypeData(keySequenceTypeData);
+ 			 
+ 			    nextToken();
+ 		     }
+ 		  }
+ 		  
+ 		  consumeExpected(',');
+ 		  
+ 		  while ((m_token != null) && !tokenIs(')')) {
+ 			  if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+ 				  consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ 				  consumeExpected(':');
+
+ 				  populateSequenceTypeData(valueSequenceTypeData);    	             	         
+
+ 				  nextToken();     	         
+ 				  consumeExpected(')');
+ 			  }     			      		   
+ 		  }
+ 		
+ 		  sequenceTypeMapTest.setKeySequenceTypeData(keySequenceTypeData);
+ 		  sequenceTypeMapTest.setValueSequenceTypeData(valueSequenceTypeData);
+ 		  
+ 		  xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
+ 	   }
+   }
+   
+   /**
+    * XPath parse of array sequence type expressions.
+    */
+   private void parseXdmArraySequenceType(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
+ 	  
+ 	  SequenceTypeArrayTest sequenceTypeArrayTest = null;
+ 	  
+ 	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
+ 		  // sequence type ArrayTest with variety AnyArrayTest
+ 		  sequenceTypeArrayTest = new SequenceTypeArrayTest();
+ 		  sequenceTypeArrayTest.setIsAnyArrayTest(true);
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 	      consumeExpected('*');
+ 	      consumeExpected(')');
+ 	      xpathSequenceTypeExpr.setSequenceTypeArrayTest(sequenceTypeArrayTest);
+ 	  }
+ 	  else {
+ 		  // sequence type ArrayTest with variety TypedArrayTest
+ 		  sequenceTypeArrayTest = new SequenceTypeArrayTest();
+ 		  nextToken();
+ 		  consumeExpected('(');
+ 		  
+ 		  SequenceTypeData arrayItemSequenceType = new SequenceTypeData();
+ 		  while ((m_token != null) && !tokenIs(')')) {
+ 			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+ 			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ 			    consumeExpected(':');
+ 			    
+ 			    populateSequenceTypeData(arrayItemSequenceType);
+ 			 
+ 			    nextToken();
+ 		     }
+ 		  }
+ 		  
+ 		  consumeExpected(')');
+ 		  
+ 		  sequenceTypeArrayTest.setArrayItemTypeInfo(arrayItemSequenceType);  	    	  
+ 		  xpathSequenceTypeExpr.setSequenceTypeArrayTest(sequenceTypeArrayTest); 
+ 	  }
+   }
+
+   /**
+    * This method is used by XPath parse of map and array sequence 
+    * type expressions.
+    */
+   private void populateSequenceTypeData(SequenceTypeData seqTypeData) throws TransformerException {
+ 	  
+ 	switch (m_token) {
+ 	    case Keywords.FUNC_BOOLEAN_STRING :
+ 	        seqTypeData.setSequenceType(SequenceTypeSupport.BOOLEAN);
+ 	        break;
+ 	    case Keywords.XS_STRING :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.STRING);
+ 	        break; 
+ 	    case Keywords.XS_NORMALIZED_STRING :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
+ 	        break;
+ 	    case Keywords.XS_TOKEN :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_TOKEN);
+ 	        break;
+ 	    case Keywords.XS_DECIMAL :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
+ 	        break; 
+ 	    case Keywords.XS_FLOAT :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_FLOAT);
+ 	        break; 
+ 	    case Keywords.XS_DOUBLE :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
+ 	        break;
+ 	    case Keywords.XS_INTEGER :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_INTEGER);
+ 	        break;
+ 	    case Keywords.XS_NON_POSITIVE_INTEGER :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_NON_POSITIVE_INTEGER);
+ 	        break;
+ 	    case Keywords.XS_NEGATIVE_INTEGER :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_NEGATIVE_INTEGER);
+ 	        break;
+ 	    case Keywords.XS_NON_NEGATIVE_INTEGER :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_NON_NEGATIVE_INTEGER);
+ 	        break;
+ 	    case Keywords.XS_POSITIVE_INTEGER :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_POSITIVE_INTEGER);
+ 	        break;
+ 	    case Keywords.XS_LONG :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_LONG);
+ 	        break; 
+ 	    case Keywords.XS_INT :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_INT);
+ 	        break;
+ 	    case Keywords.XS_SHORT :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_SHORT);
+ 	        break;
+ 	    case Keywords.XS_BYTE :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_BYTE);
+ 	        break;
+ 	    case Keywords.XS_UNSIGNED_LONG :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_LONG);
+ 	        break;
+ 	    case Keywords.XS_UNSIGNED_INT :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_INT);
+ 	        break;
+ 	    case Keywords.XS_UNSIGNED_SHORT :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_SHORT);
+ 	        break;
+ 	    case Keywords.XS_UNSIGNED_BYTE :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNSIGNED_BYTE);
+ 	        break;
+ 	    case Keywords.XS_DATE :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DATE);
+ 	        break;
+ 	    case Keywords.XS_DATETIME :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DATETIME);
+ 	        break;
+ 	    case Keywords.XS_DURATION :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DURATION);
+ 	        break;
+ 	    case Keywords.XS_YEAR_MONTH_DURATION :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
+ 	        break;
+ 	    case Keywords.XS_DAY_TIME_DURATION :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
+ 	        break;
+ 	    case Keywords.XS_TIME :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_TIME);
+ 	        break;
+ 	    case Keywords.XS_ANY_URI :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
+ 	        break;
+ 	    case Keywords.XS_QNAME :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_QNAME);
+ 	        break;
+ 	    case Keywords.XS_ANY_ATOMIC_TYPE :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
+ 	        break;
+ 	    case Keywords.XS_UNTYPED_ATOMIC :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
+ 	        break;
+ 	    case Keywords.XS_UNTYPED :
+ 	    	seqTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
+ 	        break;
+ 	    default :
+ 	        throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
+ 	                                                                              + "recognized, within the provided sequence type expression.");        
+        }
+   }
+   
+   /**
+    * At various times during an XPath expression parse, the current parse
     * attempt having occurred upto a point in token queue, needs to be 
     * discarded and another parse choice has to be explored.
     * 
-    * This class, saves information about a previous XPath parse 
-    * position.
+    * An object of this class, saves information about a specific XPath 
+    * parse position.
     * 
     * Mukul Gandhi <mu...@apache.org>
     */
-   class TokenQueueScanPosition {
+   private class TokenQueueScanPosition {
 	   
 	  private int queueMark;
 	  
diff --git a/src/org/apache/xpath/objects/XObject.java b/src/org/apache/xpath/objects/XObject.java
index 1dd225740..002eb7d96 100644
--- a/src/org/apache/xpath/objects/XObject.java
+++ b/src/org/apache/xpath/objects/XObject.java
@@ -29,6 +29,7 @@ import org.apache.xalan.res.XSLMessages;
 import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 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.Expression;
 import org.apache.xpath.ExpressionNode;
@@ -73,10 +74,24 @@ public class XObject extends Expression implements Serializable, Cloneable
   static final long serialVersionUID = -821887098985662951L;
 
   /**
-   * The java object which this object wraps.
-   *  @serial  
+   * The java object which this object wraps. 
    */
-  protected Object m_obj;  // This may be NULL!!!
+  protected Object m_obj;
+  
+  /**
+   * Stores XSLT parameter tunnel attribute's value.
+   * This shall be null, if this XObject instance 
+   * doesn't represent tunnel parameter's value.
+   */
+  private String m_tunnelStrVal;
+
+  /**
+   * Stores XSLT parameter's name, if the parameter
+   * has an attribute 'tunnel.
+   * This shall be null, if this XObject instance 
+   * doesn't represent tunnel parameter's value.
+   */
+  private QName m_QName;
 
   /**
    * Create an XObject.
@@ -1554,4 +1569,20 @@ public class XObject extends Expression implements Serializable, Cloneable
   	return true;
   }
 
+  public void setTunnel(String tunnelStrVal) {
+	 m_tunnelStrVal = tunnelStrVal;	
+  }
+  
+  public String getTunnel() {
+	 return m_tunnelStrVal;  
+  }
+
+  public void setQName(QName qName) {
+	 m_QName = qName;	
+  }
+  
+  public QName getQName() {
+	 return m_QName; 
+  }
+
 }
diff --git a/src/org/apache/xpath/operations/StrConcat.java b/src/org/apache/xpath/operations/StrConcat.java
index 2927df6d1..3adcdb32a 100644
--- a/src/org/apache/xpath/operations/StrConcat.java
+++ b/src/org/apache/xpath/operations/StrConcat.java
@@ -25,10 +25,6 @@ import org.apache.xpath.objects.XString;
 /**
  * The XPath 3.1 string concatenation "||" operation.
  * 
- * An XPath string concatenation "||" expression, may be used to concatenate 
- * two string values. With XPath 3.1 language, an XPath expression $a || $b 
- * is equivalent to fn:concat($a, $b).
- * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
@@ -50,26 +46,25 @@ public class StrConcat extends Operation
    */
     public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
         
-      XObject result = null;
-      
-      XObject left = m_left.execute(xctxt);
-      
-      XObject right = m_right.execute(xctxt);
-      
-      result = new XString(XslTransformEvaluationHelper.getStrVal(left) + 
-                                                             XslTransformEvaluationHelper.getStrVal(right));
-      
-      return result;
+    	XObject result = null;
+
+    	XObject left = m_left.execute(xctxt);
+
+    	XObject right = m_right.execute(xctxt);
+
+    	result = new XString(XslTransformEvaluationHelper.getStrVal(left) + 
+    			                                       XslTransformEvaluationHelper.getStrVal(right));
+
+    	return result;
     }
     
     /**
      * Apply the operation to two operands, and return the result.
      */
     public XObject operate(XObject left, XObject right) {
-        XObject result =  new XString(XslTransformEvaluationHelper.getStrVal(left) + 
-                                                             XslTransformEvaluationHelper.getStrVal(right));
-        
-        return result;
+    	XObject result =  new XString(XslTransformEvaluationHelper.getStrVal(left) + 
+    			                                                XslTransformEvaluationHelper.getStrVal(right));        
+    	return result;
     }
 
 }
diff --git a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
index d077e84a4..3383168c6 100644
--- a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
@@ -81,7 +81,8 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnParseJsonTests.class, FnJsonDocTests.class, FnJsonToXmlTests.class,
                 FnXmlToJsonTests.class, FnAnalyzeStringTests.class, XPathMapOtherTests.class,
                 JiraIssuesTests.class, XPathNamedFunctionReferenceTests.class, FnApplyTests.class,
-                XPathGeneralComparisonOpTests.class, FnMapFindTests.class, XPathNumericArithmeticTests.class })
+                XPathGeneralComparisonOpTests.class, FnMapFindTests.class, XPathNumericArithmeticTests.class,
+                XslTunnelParameterTests.class })
 public class Xsl3TestSuite1 {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslTunnelParameterTests.java b/tests/org/apache/xalan/xslt3/XslTunnelParameterTests.java
new file mode 100644
index 000000000..aec097fee
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/XslTunnelParameterTests.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.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XSLConstants;
+import org.apache.xalan.util.XSLTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSL test cases to test tunnel parameters.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XslTunnelParameterTests extends XSLTransformTestsUtil {
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+    		                                                                                              + "xsl_tunnel_parameter/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + 
+    		                                                                                              "xsl_tunnel_parameter/gold/";      
+
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslTunnelParameterTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTunnelParameterTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslTunnelParameterTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
+                               
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTunnelParameterTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);      
+    }
+    
+    @Test
+    public void xslTunnelParameterTest5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/xsl_tunnel_parameter/gold/test1.out b/tests/xsl_tunnel_parameter/gold/test1.out
new file mode 100644
index 000000000..98aaa3666
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/gold/test1.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info1>hello world</info1>
+  <info2>*** hello world ***</info2>
+</result>
diff --git a/tests/xsl_tunnel_parameter/gold/test2.out b/tests/xsl_tunnel_parameter/gold/test2.out
new file mode 100644
index 000000000..dae8af089
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/gold/test2.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info1>hello </info1>
+  <info2>*** hello world ***</info2>
+</result>
diff --git a/tests/xsl_tunnel_parameter/gold/test3.out b/tests/xsl_tunnel_parameter/gold/test3.out
new file mode 100644
index 000000000..497f4fd39
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/gold/test3.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info1>{a} hello world</info1>
+  <info2>*** hello world ***</info2>
+  <info1>{b} hello world</info1>
+  <info2>*** hello world ***</info2>
+  <info1>{c} hello world</info1>
+  <info2>*** hello world ***</info2>
+</result>
diff --git a/tests/xsl_tunnel_parameter/gold/test4.out b/tests/xsl_tunnel_parameter/gold/test4.out
new file mode 100644
index 000000000..738d48060
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/gold/test4.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info1>{a} hello </info1>
+  <info2>*** hello world ***</info2>
+  <info1>{b} hello </info1>
+  <info2>*** hello world ***</info2>
+  <info1>{c} hello </info1>
+  <info2>*** hello world ***</info2>
+</result>
diff --git a/tests/xsl_tunnel_parameter/gold/test5.out b/tests/xsl_tunnel_parameter/gold/test5.out
new file mode 100644
index 000000000..9a56005de
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/gold/test5.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info1>{L} hello</info1>
+  <info2>*** hello ***</info2>
+</result>
diff --git a/tests/xsl_tunnel_parameter/test1.xsl b/tests/xsl_tunnel_parameter/test1.xsl
new file mode 100644
index 000000000..5c99016f3
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test1.xsl
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				                
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSL stylesheet test case to test tunnel parameters. -->                			
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/">
+	  <result>
+	     <xsl:call-template name="A1">
+		   <xsl:with-param name="str1" select="'hello'"/>
+	       <xsl:with-param name="str2" select="'world'" tunnel="yes"/>		   
+		 </xsl:call-template>
+	  </result>
+   </xsl:template>
+   
+   <xsl:template name="A1">
+      <xsl:param name="str1"/>
+	  <xsl:param name="str2" tunnel="yes"/>
+	  <info1>
+	     <xsl:value-of select="$str1 || ' ' || $str2"/>
+	  </info1>
+	  <info2>
+	    <xsl:call-template name="P1">
+		   <xsl:with-param name="str1" select="$str1"/>		   
+		</xsl:call-template>
+	  </info2>
+   </xsl:template>
+   
+   <xsl:template name="P1">
+      <xsl:param name="str1"/>
+	  <xsl:param name="str2" tunnel="yes"/>
+	  <xsl:value-of select="'*** ' || $str1 || ' ' || $str2 || ' ***'"/>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_tunnel_parameter/test2.xsl b/tests/xsl_tunnel_parameter/test2.xsl
new file mode 100644
index 000000000..a9181060b
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test2.xsl
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				                
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSL stylesheet test case to test tunnel parameters. -->                			
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/">
+	  <result>
+	     <xsl:call-template name="A1">
+		   <xsl:with-param name="str1" select="'hello'"/>
+	       <xsl:with-param name="str2" select="'world'" tunnel="yes"/>		   
+		 </xsl:call-template>
+	  </result>
+   </xsl:template>
+   
+   <xsl:template name="A1">
+      <xsl:param name="str1"/>
+	  <xsl:param name="str2"/>
+	  <info1>
+	     <xsl:value-of select="$str1 || ' ' || $str2"/>
+	  </info1>
+	  <info2>
+	    <xsl:call-template name="P1">
+		   <xsl:with-param name="str1" select="$str1"/>		   
+		</xsl:call-template>
+	  </info2>
+   </xsl:template>
+   
+   <xsl:template name="P1">
+      <xsl:param name="str1"/>
+	  <xsl:param name="str2" tunnel="yes"/>
+	  <xsl:value-of select="'*** ' || $str1 || ' ' || $str2 || ' ***'"/>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_tunnel_parameter/test3.xml b/tests/xsl_tunnel_parameter/test3.xml
new file mode 100644
index 000000000..3ee4906f0
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test3.xml
@@ -0,0 +1,5 @@
+<info>
+  <a/>
+  <b/>
+  <c/>
+</info>
diff --git a/tests/xsl_tunnel_parameter/test3.xsl b/tests/xsl_tunnel_parameter/test3.xsl
new file mode 100644
index 000000000..6ebaceae4
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test3.xsl
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				                
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- use with test3.xml -->
+   
+   <!-- An XSL stylesheet test case to test tunnel parameters. -->                			
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/info">
+	  <result>
+	     <xsl:apply-templates select="*">
+		    <xsl:with-param name="str1" select="'hello'"/>
+			<xsl:with-param name="str2" select="'world'" tunnel="yes"/>
+		 </xsl:apply-templates>
+	  </result>
+   </xsl:template>
+   
+   <xsl:template match="*">
+     <xsl:param name="str1"/>
+	 <xsl:param name="str2" tunnel="yes"/>
+	 <info1>
+	   <xsl:value-of select="'{' || name() || '}' || ' ' || $str1 || ' ' || $str2"/>
+	 </info1>
+	 <info2>
+	    <xsl:call-template name="P1">
+		  <xsl:with-param name="str1" select="$str1"/>		   
+		</xsl:call-template>
+	 </info2>
+   </xsl:template>
+   
+   <xsl:template name="P1">
+     <xsl:param name="str1"/>
+	 <xsl:param name="str2" tunnel="yes"/>
+	 <xsl:value-of select="'*** ' || $str1 || ' ' || $str2 || ' ***'"/>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_tunnel_parameter/test4.xml b/tests/xsl_tunnel_parameter/test4.xml
new file mode 100644
index 000000000..725034fc6
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test4.xml
@@ -0,0 +1,5 @@
+<info>
+  <L>
+    <M/>
+  </L>
+</info>
diff --git a/tests/xsl_tunnel_parameter/test4.xsl b/tests/xsl_tunnel_parameter/test4.xsl
new file mode 100644
index 000000000..a48449b20
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test4.xsl
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				                
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- use with test3.xml -->
+   
+   <!-- An XSL stylesheet test case to test tunnel parameters. -->               			
+
+   <xsl:output method="xml" indent="yes"/>   
+
+   <xsl:template match="/info">
+	  <result>
+	     <xsl:apply-templates select="*">
+		    <xsl:with-param name="str1" select="'hello'"/>
+			<xsl:with-param name="str2" select="'world'" tunnel="yes"/>
+		 </xsl:apply-templates>
+	  </result>
+   </xsl:template>
+   
+   <xsl:template match="*">
+     <xsl:param name="str1"/>
+	 <xsl:param name="str2"/>
+	 <info1>
+	   <xsl:value-of select="'{' || name() || '}' || ' ' || $str1 || ' ' || $str2"/>
+	 </info1>
+	 <info2>
+	    <xsl:call-template name="P1">
+		  <xsl:with-param name="str1" select="$str1"/>		   
+		</xsl:call-template>
+	 </info2>
+   </xsl:template>
+   
+   <xsl:template name="P1">
+     <xsl:param name="str1"/>
+	 <xsl:param name="str2" tunnel="yes"/>
+	 <xsl:value-of select="'*** ' || $str1 || ' ' || $str2 || ' ***'"/>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_tunnel_parameter/test5.xsl b/tests/xsl_tunnel_parameter/test5.xsl
new file mode 100644
index 000000000..3af2b868d
--- /dev/null
+++ b/tests/xsl_tunnel_parameter/test5.xsl
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				                
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- use with test4.xml -->
+   
+   <!-- An XSL stylesheet test case to test tunnel parameters. -->               		
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/info">
+	  <result>
+	     <xsl:apply-templates select="*">
+			<xsl:with-param name="str1" select="'hello'" tunnel="yes"/>
+		 </xsl:apply-templates>
+	  </result>
+   </xsl:template>
+   
+   <xsl:template match="*">
+	 <xsl:param name="str1" tunnel="yes"/>
+	 <info1>
+	   <xsl:value-of select="'{' || name() || '}' || ' ' || $str1"/>
+	 </info1>
+	 <info2>
+	    <xsl:apply-templates select="M"/>
+	 </info2>
+   </xsl:template>
+   
+   <xsl:template match="M">
+	 <xsl:param name="str1" tunnel="yes"/>
+	 <xsl:value-of select="'*** ' || $str1 || ' ***'"/>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org