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 2023/08/16 16:44:06 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing few fixes and improvements to, xslt 3.0 and xpath 3.1 implementations, along with few new working test cases as well. minor codebase comments enhancements as well.

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 2cf904b1 committing few fixes and improvements to, xslt 3.0 and xpath 3.1 implementations, along with few new working test cases as well. minor codebase comments enhancements as well.
     new 5d229854 Merge pull request #52 from mukulga/xalan-j_xslt3.0_mukul
2cf904b1 is described below

commit 2cf904b11edcaa0ff4732fe80de28ea47f5c76cd
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Wed Aug 16 22:09:43 2023 +0530

    committing few fixes and improvements to, xslt 3.0 and xpath 3.1 implementations, along with few new working test cases as well. minor codebase comments enhancements as well.
---
 src/org/apache/xalan/templates/ElemCopyOf.java     |  58 +++++++---
 src/org/apache/xalan/templates/ElemForEach.java    |  55 ++++++----
 src/org/apache/xalan/templates/ElemIterate.java    |  50 +++++----
 .../xalan/templates/ElemIterateNextIteration.java  |   6 +-
 .../xalan/templates/ElemTemplateElement.java       |  68 ++++++++++--
 src/org/apache/xalan/templates/ElemValueOf.java    |  45 +++++---
 src/org/apache/xalan/templates/ElemVariable.java   |   2 +-
 .../templates/XslIterateParamWithparamData.java    |   1 +
 src/org/apache/xpath/XPath.java                    | 120 ++++++++++++++++++++-
 src/org/apache/xpath/axes/PredicatedNodeTest.java  |   9 ++
 src/org/apache/xpath/compiler/XPathParser.java     |  19 ++--
 src/org/apache/xpath/composite/ForExpr.java        |  73 ++++++++-----
 .../composite/ForQuantifiedExprVarBinding.java     |  10 +-
 src/org/apache/xpath/composite/IfExpr.java         |   2 +-
 src/org/apache/xpath/composite/LetExpr.java        |   2 +-
 src/org/apache/xpath/composite/QuantifiedExpr.java |   4 +-
 .../xpath/composite/SimpleSequenceConstructor.java |   2 +-
 .../xpath/functions/DynamicFunctionCall.java       |  21 ++--
 src/org/apache/xpath/functions/FuncFilter.java     |   2 +-
 src/org/apache/xpath/functions/FuncForEach.java    |   2 +-
 src/org/apache/xpath/functions/FuncSum.java        |   7 ++
 .../apache/xpath/functions/FunctionDef1Arg.java    |   9 +-
 tests/fn_sort/gold/test6.out                       |  11 ++
 tests/fn_sort/gold/test7.out                       |  11 ++
 tests/fn_sort/gold/test8.out                       |   1 +
 tests/fn_sort/gold/test9.out                       |  20 ++++
 tests/fn_sort/{test5.xsl => test10.xsl}            |  38 ++++---
 tests/fn_sort/{test3.xsl => test11.xsl}            |  26 ++---
 tests/fn_sort/{test5.xsl => test12.xsl}            |  43 ++++----
 tests/fn_sort/test1_d.xml                          |  11 ++
 tests/fn_sort/test1_e.xml                          |  14 +++
 tests/fn_sort/test3.xsl                            |   2 +-
 tests/fn_sort/test5.xsl                            |   4 +-
 tests/fn_sort/{test5.xsl => test6.xsl}             |  29 +++--
 tests/fn_sort/{test5.xsl => test7.xsl}             |  31 +++---
 tests/fn_sort/{test5.xsl => test8.xsl}             |  29 ++---
 tests/fn_sort/{test5.xsl => test9.xsl}             |  40 ++++---
 tests/org/apache/xalan/xpath3/FnSortTests.java     |  70 ++++++++++++
 .../xalan/xpath3/SequenceConstructorTests.java     |  20 ++++
 tests/sequence_constructor/gold/test9.out          |  14 +++
 .../test3.xsl => sequence_constructor/test11.xsl}  |  24 +++--
 .../test3.xsl => sequence_constructor/test12.xsl}  |  24 +++--
 tests/sequence_constructor/test1_e.xml             |  11 ++
 43 files changed, 770 insertions(+), 270 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemCopyOf.java b/src/org/apache/xalan/templates/ElemCopyOf.java
index 2d3b308e..7658ede8 100644
--- a/src/org/apache/xalan/templates/ElemCopyOf.java
+++ b/src/org/apache/xalan/templates/ElemCopyOf.java
@@ -20,15 +20,17 @@
  */
 package org.apache.xalan.templates;
 
+import java.util.Vector;
+
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.serialize.SerializerUtils;
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xalan.transformer.TreeWalker2Result;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.dtm.ref.DTMTreeWalker;
-import org.apache.xalan.serialize.SerializerUtils;
 import org.apache.xml.serializer.SerializationHandler;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
@@ -39,7 +41,7 @@ import org.apache.xpath.xs.types.XSNumericType;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
 
-/*
+/**
  * Implementation of XSLT xsl:copy-of instruction.
  * 
  * XSLT 3.0 spec, provides following definition of xsl:copy-of
@@ -63,6 +65,17 @@ public class ElemCopyOf extends ElemTemplateElement
    * @serial
    */
   public XPath m_selectExpression = null;
+  
+  /**
+   * True if the pattern is a simple ".".
+   */
+  private boolean m_isDot = false;
+  
+  // The following two fields of this class, are used during 
+  // XPath.fixupVariables(..) action as performed within object of 
+  // this class.    
+  private Vector fVars;    
+  private int fGlobalsSize;
 
   /**
    * Set the "select" attribute.
@@ -72,6 +85,12 @@ public class ElemCopyOf extends ElemTemplateElement
    */
   public void setSelect(XPath expr)
   {
+    if (expr != null) {
+       String patternStr = expr.getPatternString();
+
+       m_isDot = (patternStr != null) && patternStr.equals(".");
+    }
+      
     m_selectExpression = expr;
   }
 
@@ -96,8 +115,14 @@ public class ElemCopyOf extends ElemTemplateElement
   {
     super.compose(sroot);
     
-    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
-    m_selectExpression.fixupVariables(cstate.getVariableNames(), cstate.getGlobalsSize());
+    java.util.Vector vnames = (sroot.getComposeState()).getVariableNames();
+    
+    fVars = (Vector)(vnames.clone()); 
+    fGlobalsSize = (sroot.getComposeState()).getGlobalsSize();
+
+    if (m_selectExpression != null) {
+        m_selectExpression.fixupVariables(vnames, fGlobalsSize);
+    }
   }
 
   /**
@@ -140,8 +165,18 @@ public class ElemCopyOf extends ElemTemplateElement
     try
     {
       XPathContext xctxt = transformer.getXPathContext();
+              
       int sourceNode = xctxt.getCurrentNode();
-      XObject value = m_selectExpression.execute(xctxt, sourceNode, this);
+      
+      XObject value = null;
+      
+      XObject xpath3ContextItem = xctxt.getXPath3ContextItem();
+      if (m_isDot && (xpath3ContextItem != null)) {
+         value = xpath3ContextItem;  
+      }
+      else {
+         value = m_selectExpression.execute(xctxt, sourceNode, this);
+      }
 
       if (transformer.getDebug())
         transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
@@ -245,12 +280,12 @@ public class ElemCopyOf extends ElemTemplateElement
                     handler.characters(spaceCharArr, 0, 1);
                  } 
              }
-             else if (sequenceItem.getType() == XObject.CLASS_NODESET) {
+             else if (sequenceItem.getType() == XObject.CLASS_NODESET) {                 
                  DTMIterator nl1 = sequenceItem.iter();
 
                  DTMTreeWalker tw1 = new TreeWalker2Result(transformer, handler);
-                 int pos1;
-
+                 int pos1;                 
+                 
                  while (DTM.NULL != (pos1 = nl1.nextNode())) {
                      DTM dtm = xctxt.getDTMManager().getDTM(pos1);
                      short t = dtm.getNodeType(pos1);
@@ -267,7 +302,7 @@ public class ElemCopyOf extends ElemTemplateElement
                      else {
                          tw1.traverse(pos1);
                      }
-                 }    
+                 }
              }
           }
           
@@ -280,11 +315,6 @@ public class ElemCopyOf extends ElemTemplateElement
           break;
         }
       }
-                        
-      // I don't think we want this.  -sb
-      //  if (transformer.getDebug())
-      //  transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
-      //  "endSelect", m_selectExpression, value);
 
     }
     catch(org.xml.sax.SAXException se)
diff --git a/src/org/apache/xalan/templates/ElemForEach.java b/src/org/apache/xalan/templates/ElemForEach.java
index 6acbc0ad..6d82377a 100644
--- a/src/org/apache/xalan/templates/ElemForEach.java
+++ b/src/org/apache/xalan/templates/ElemForEach.java
@@ -39,6 +39,7 @@ import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.composite.ForExpr;
 import org.apache.xpath.composite.SimpleSequenceConstructor;
+import org.apache.xpath.functions.DynamicFunctionCall;
 import org.apache.xpath.functions.Function;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
@@ -345,12 +346,12 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
         XObject evalResult = ((Function)m_selectExpression).execute(xctxt);
         if (evalResult instanceof ResultSequence) {
             processResultSequence(transformer, xctxt, evalResult);
-            transformer.setXPathContext(xctxtOriginal);            
+            transformer.setXPathContext(xctxtOriginal);
+            
             return;
         }                
-    }
-    
-    if (m_selectExpression instanceof Variable) {
+    }    
+    else if (m_selectExpression instanceof Variable) {
         // evaluate an xslt variable reference.
         // for example,
         // <xsl:variable name="tokens" select="tokenize(..)"/>
@@ -358,36 +359,48 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
         XObject evalResult = ((Variable)m_selectExpression).execute(xctxt);
         if (evalResult instanceof ResultSequence) {
             processResultSequence(transformer, xctxt, evalResult);
-            transformer.setXPathContext(xctxtOriginal);            
+            transformer.setXPathContext(xctxtOriginal);
+            
             return;
         }
-    }
-    
-    if (m_selectExpression instanceof Operation) {
+    }    
+    else if (m_selectExpression instanceof Operation) {
         XObject  evalResult = m_selectExpression.execute(xctxt);
         if (evalResult instanceof ResultSequence) {
             processResultSequence(transformer, xctxt, evalResult);
             transformer.setXPathContext(xctxtOriginal);
+            
             return;
         }
-    }
-    
-    if (m_selectExpression instanceof ForExpr) {
+    }    
+    else if (m_selectExpression instanceof ForExpr) {
         ForExpr forExpr = (ForExpr)m_selectExpression;
         XObject  evalResult = forExpr.execute(xctxt);
         processResultSequence(transformer, xctxt, evalResult);
         transformer.setXPathContext(xctxtOriginal);
+        
         return;
-    }
-    
-    if (m_selectExpression instanceof SimpleSequenceConstructor) {
+    }    
+    else if (m_selectExpression instanceof SimpleSequenceConstructor) {
         SimpleSequenceConstructor seqCtrExpr = (SimpleSequenceConstructor)
                                                                      m_selectExpression;
         XObject  evalResult = seqCtrExpr.execute(xctxt);
         processResultSequence(transformer, xctxt, evalResult);
         transformer.setXPathContext(xctxtOriginal);
+        
         return;
     }
+    else if (m_selectExpression instanceof DynamicFunctionCall) {
+        DynamicFunctionCall dfc = (DynamicFunctionCall)m_selectExpression;
+        XObject evalResult = dfc.execute(xctxt);
+        
+        if (evalResult instanceof ResultSequence) {
+           processResultSequence(transformer, xctxt, evalResult);
+           transformer.setXPathContext(xctxtOriginal);
+            
+           return;
+        }
+    }
     
     // process the node-set, with body of xsl:for-each element as usual 
     final int sourceNode = xctxt.getCurrentNode();
@@ -600,12 +613,10 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
        ResultSequence resultSeq = (ResultSequence)evalResult;
        List<XObject> resultSeqItems = resultSeq.getResultSequenceItems();
        
-       xctxt.setXPath3ContextSize(resultSeqItems.size());
-       
        for (int idx = 0; idx < resultSeqItems.size(); idx++) {
            XObject resultSeqItem = resultSeqItems.get(idx);
-           xctxt.setXPath3ContextItem(resultSeqItem);
-           xctxt.setXPath3ContextPosition(idx + 1);
+           
+           setXPathContextForXslSequenceProcessing(resultSeqItems.size(), idx, resultSeqItem, xctxt);
            
            for (ElemTemplateElement elemTemplateElem = this.m_firstChild; elemTemplateElem != null; 
                                                           elemTemplateElem = elemTemplateElem.m_nextSibling) {
@@ -613,12 +624,10 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
               transformer.setCurrentElement(elemTemplateElem);
               elemTemplateElem.execute(transformer);              
            }
+           
+           // reset the, XPath context details
+           resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);
        }
-
-       // reset the, XPath context's size, item and position variables
-       xctxt.setXPath3ContextSize(-1);
-       xctxt.setXPath3ContextItem(null);
-       xctxt.setXPath3ContextPosition(-1);
    }
    
 }
diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
index 242e2a39..0289a604 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -32,6 +32,7 @@ import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.DynamicFunctionCall;
 import org.apache.xpath.functions.Function;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
@@ -73,11 +74,8 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
      
      private static final String OTHER_ELEM = "OTHER_ELEM";
      
-     // Can we have better way to maintain XSLT transformation xsl:iterate->xsl:param*
-     // run-time reference, instead of having this with 'public static' visibility?
-     // REVISIT
-     public static List<XslIterateParamWithparamData> fParamList = new 
-                                                              ArrayList<XslIterateParamWithparamData>();
+     public static List<XslIterateParamWithparamData> fXslIterateParamWithparamDataList = new 
+                                                                             ArrayList<XslIterateParamWithparamData>();
 
      /**
       * Construct an element representing xsl:iterate.
@@ -201,7 +199,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
            
            // Clear the, xsl:iterate->xsl:param* list storage before this xsl:iterate 
            // instruction's evaluation.
-           fParamList.clear();
+           fXslIterateParamWithparamDataList.clear();
            
            validateXslElemIterateChildElementsSequence(xctxt);
            
@@ -209,20 +207,24 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
            // to a 'ResultSequence'. 
            if ((m_selectExpression instanceof Variable) || 
                                                   (m_selectExpression instanceof Operation) || 
-                                                  (m_selectExpression instanceof Function)) {
+                                                  (m_selectExpression instanceof Function)  ||
+                                                  (m_selectExpression instanceof DynamicFunctionCall)) {
+               
                XObject  evalResult = m_selectExpression.execute(xctxt);
+               
                if (evalResult instanceof ResultSequence) {
                    ResultSequence resultSeq = (ResultSequence)evalResult;
-                   List<XObject> resultSeqItems = resultSeq.getResultSequenceItems();
-                   
-                   xctxt.setXPath3ContextSize(resultSeqItems.size());
+                   List<XObject> resultSeqItems = resultSeq.getResultSequenceItems();                                      
                    
                    ElemIterateOnCompletion xslOnCompletionTemplate = null;
                    
                    for (int idx = 0; idx < resultSeqItems.size(); idx++) {
                        XObject resultSeqItem = resultSeqItems.get(idx);
-                       xctxt.setXPath3ContextItem(resultSeqItem);
-                       xctxt.setXPath3ContextPosition(idx + 1);
+                       
+                       setXPathContextForXslSequenceProcessing(resultSeqItems.size(), idx, 
+                                                                                                 resultSeqItem, xctxt);
+                       
+                       boolean isBreakFromXslContentLoop = false;
                        
                        for (ElemTemplateElement elemTemplate = this.m_firstChild; elemTemplate != null; 
                                                                              elemTemplate = elemTemplate.m_nextSibling) {
@@ -236,12 +238,22 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                                elemTemplate.execute(transformer);
                            }
                            else {
+                               // reset the, XPath context details                               
+                               resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);
+                               
+                               isBreakFromXslContentLoop = true;
+                               
                                break;    
                            }
                        }
                        
+                       if (!isBreakFromXslContentLoop) {
+                          // reset the, XPath context details                           
+                          resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);
+                       }
+                       
                        if ((XslTransformSharedDatastore.isXslIterateBreakEvaluated).booleanValue()) {                       
-                           break;   
+                          break;   
                        }
                    }
                    
@@ -263,7 +275,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                   
                   transformer.setXPathContext(xctxtOriginal);
                 
-                  return;  // return from this xsl:iterate instruction's evaluation
+                  return;  // return from this xsl:iterate instruction's evaluation                  
                }
            }
            
@@ -363,8 +375,8 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
               }
           }
           
-          // Get index of specific XSLT stylesheet elements first occurrence with the list object 
-          // 'xslElemNamesList'. If a particular kind of XSLT stylesheet element that is checked is 
+          // Get index of XSLT stylesheet specific element(s)'s, first occurrence within the list object 
+          // 'xslElemNamesList'. If a particular kind of XSLT stylesheet element that is checked, is 
           // not present within the list object 'xslElemNamesList', its index is returned as -1.
           int paramIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING);
           int onCompletionIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING);          
@@ -394,12 +406,12 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                      XslIterateParamWithparamData paramWithparamDataObj = new XslIterateParamWithparamData();
                      paramWithparamDataObj.setNameVal(paramNameVal);
                      paramWithparamDataObj.setSelectVal(paramSelectXPath);
-                     if (fParamList.contains(paramWithparamDataObj)) {
-                         throw new TransformerException("XTSE0580 : the name of the xsl:param parameter '" + paramNameVal + "' "
+                     if (fXslIterateParamWithparamDataList.contains(paramWithparamDataObj)) {
+                        throw new TransformerException("XTSE0580 : the name of the xsl:param parameter '" + paramNameVal + "' "
                                                                                          + "is not unique.", xctxt.getSAXLocator());    
                      }
                      else {
-                         fParamList.add(paramWithparamDataObj);    
+                        fXslIterateParamWithparamDataList.add(paramWithparamDataObj);    
                      }
                   }                                    
               }
diff --git a/src/org/apache/xalan/templates/ElemIterateNextIteration.java b/src/org/apache/xalan/templates/ElemIterateNextIteration.java
index 2e708605..3ceaa4ad 100644
--- a/src/org/apache/xalan/templates/ElemIterateNextIteration.java
+++ b/src/org/apache/xalan/templates/ElemIterateNextIteration.java
@@ -225,13 +225,13 @@ public class ElemIterateNextIteration extends ElemTemplateElement implements Exp
                 }
             }
             
-            if ((ElemIterate.fParamList).size() != fWithparamList.size()) {
+            if ((ElemIterate.fXslIterateParamWithparamDataList).size() != fWithparamList.size()) {
                 throw new TransformerException("XTSE0580 : within xsl:iterate, the number of xsl:param elements are not equal to "
                                                                + "number of xsl:next-iteration's xsl:with-param elements.", xctxt.getSAXLocator());     
             }
             else {
-               for (int idx = 0; idx < (ElemIterate.fParamList).size(); idx ++) {
-                   XslIterateParamWithparamData paramData = (ElemIterate.fParamList).get(idx);
+               for (int idx = 0; idx < (ElemIterate.fXslIterateParamWithparamDataList).size(); idx ++) {
+                   XslIterateParamWithparamData paramData = (ElemIterate.fXslIterateParamWithparamDataList).get(idx);
                    XslIterateParamWithparamData withParamData = fWithparamList.get(idx);
                    if (!(paramData.getNameVal()).equals(withParamData.getNameVal())) {
                        throw new TransformerException("XTSE3130 : within xsl:iterate, xsl:param and xsl:with-param names at position " + 
diff --git a/src/org/apache/xalan/templates/ElemTemplateElement.java b/src/org/apache/xalan/templates/ElemTemplateElement.java
index 4d6d37d9..31761926 100644
--- a/src/org/apache/xalan/templates/ElemTemplateElement.java
+++ b/src/org/apache/xalan/templates/ElemTemplateElement.java
@@ -31,11 +31,15 @@ import javax.xml.transform.TransformerException;
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xalan.res.XSLTErrorResources;
 import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.serializer.SerializationHandler;
 import org.apache.xml.utils.PrefixResolver;
 import org.apache.xml.utils.UnImplNode;
 import org.apache.xpath.ExpressionNode;
 import org.apache.xpath.WhitespaceStrippingElementMatcher;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -62,13 +66,13 @@ public class ElemTemplateElement extends UnImplNode
 {
    static final long serialVersionUID = 4440018597841834447L;
     
-   // to support, xsl:for-each-group's grouping key. 
-   // the instance of this class, stores this value for a specific xsl:for-each-group element 
+   // 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;
     
-   // to support, xsl:for-each-group's current-group contents. 
-   // the instance of this class, stores this value for a specific xsl:for-each-group element 
+   // 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;
 
@@ -1681,7 +1685,7 @@ public class ElemTemplateElement extends UnImplNode
       this.fGroupNodesDtmHandles = groupNodesDtmHandles;
   }
   
-  /*
+  /**
    * Method to determine whether, an XSLT instruction is in a sequence constructor's tail position.
    * 
    * The XSLT 3.0 spec, provides following definition to determine, whether an XSLT instruction
@@ -1700,12 +1704,10 @@ public class ElemTemplateElement extends UnImplNode
      5) J is in a tail position within the sequence constructor that forms the body of an xsl:catch element within 
         an xsl:try instruction that is itself in a tail position within SC.
         
-     Notes : Presently, we check only points 1), 2) and 3) as mentioned within previous definition above (excluding 
-             checking the constraints, specified for xsl:fallback instruction).
+     Currently, we check only points 1), 2) and 3) as mentioned within previous definition above.
              
      @param  xslInstr    the XSLT instruction for which we need to find, whether its in a tail position of an XSLT 
-                         sequence constructor.                         
-                          
+                         sequence constructor.                          
    */
   protected boolean isXslInstructionInTailPositionOfSequenceConstructor(ElemTemplateElement xslInstr) {
       
@@ -1736,5 +1738,53 @@ public class ElemTemplateElement extends UnImplNode
       
       return isXslInstructionInTailPositionOfSequenceConstructor;
   }
+  
+  /**
+   * During processing of, xsl:for-each or xsl:iterate instructions, when the input data to be
+   * processed by these instructions is a 'ResultSequence' object, we use this method to set
+   * the XPath context information before each sequence item is processed by these instructions.
+   * 
+   * @param inpSequenceLength                  an input data sequence length
+   * @param currentlyProcessingItemIndex       an index of currently processed item within an 
+                                               input sequence.
+   * @param currentContextItem                 the current xdm item been processed
+   * @param xctxt                              the currently active, XPath context object
+   */
+  protected void setXPathContextForXslSequenceProcessing(int inpSequenceLength, 
+                                                                  int currentlyProcessingItemIndex, 
+                                                                  XObject currentContextItem, 
+                                                                  XPathContext xctxt) {
+      if (!(currentContextItem instanceof XNodeSet)) {
+         xctxt.setXPath3ContextSize(inpSequenceLength);
+         xctxt.setXPath3ContextItem(currentContextItem);
+         xctxt.setXPath3ContextPosition(currentlyProcessingItemIndex + 1);
+      }
+      else {
+         XNodeSet xNodeSet = (XNodeSet)currentContextItem;
+         DTMIterator dtmIter = xNodeSet.iterRaw();
+         int contextNode = dtmIter.nextNode();
+         xctxt.pushCurrentNode(contextNode); 
+      }
+  }
+  
+  /**
+   * During processing of, xsl:for-each or xsl:iterate instructions, when the input data to be
+   * processed by these instructions is a 'ResultSequence' object, we use this method to reset
+   * the XPath context information after each sequence item is processed by these instructions. 
+   * 
+   * @param currentContextItem      the current xdm item been processed
+   * @param xctxt                   the currently active, XPath context object
+   */
+  protected void resetXPathContextForXslSequenceProcessing(XObject currentContextItem, 
+                                                                            XPathContext xctxt) {
+     if (!(currentContextItem instanceof XNodeSet)) {
+        xctxt.setXPath3ContextSize(-1);
+        xctxt.setXPath3ContextItem(null);
+        xctxt.setXPath3ContextPosition(-1);
+     }
+     else {
+        xctxt.popCurrentNode();
+     }
+  }
 
 }
diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index e6818c81..35dd9bf9 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -18,6 +18,7 @@
 package org.apache.xalan.templates;
 
 import java.util.List;
+import java.util.Vector;
 
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
@@ -79,6 +80,12 @@ public class ElemValueOf extends ElemTemplateElement {
    * True if the pattern is a simple ".".
    */
   private boolean m_isDot = false;
+  
+  // The following two fields of this class, are used during 
+  // XPath.fixupVariables(..) action as performed within object of 
+  // this class.    
+  private Vector fVars;    
+  private int fGlobalsSize;
 
   /**
    * Set the "select" attribute.
@@ -197,11 +204,14 @@ public class ElemValueOf extends ElemTemplateElement {
 
     super.compose(sroot);
 
-    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+    java.util.Vector vnames = (sroot.getComposeState()).getVariableNames();
+    
+    fVars = (Vector)(vnames.clone()); 
+    fGlobalsSize = (sroot.getComposeState()).getGlobalsSize();
 
-    if (null != m_selectExpression)
-      m_selectExpression.fixupVariables(
-        vnames, sroot.getComposeState().getGlobalsSize());
+    if (m_selectExpression != null) {
+        m_selectExpression.fixupVariables(vnames, fGlobalsSize);
+    }
   }
 
   /**
@@ -438,9 +448,13 @@ public class ElemValueOf extends ElemTemplateElement {
                         
                         if (xpathPatternStr.startsWith("$") && xpathPatternStr.contains("[") && 
                                                                                     xpathPatternStr.endsWith("]")) {
+                           // Within this 'if' clause, we handle the case, where the XPath expression is
+                           // syntactically of type $varName[expr], for example $varName[1], $varName[$idx],
+                           // $varName[funcCall(arg)] etc, and $varName resolves to a 'ResultSequence' object.
+                            
                            String varRefXPathExprStr = "$" + xpathPatternStr.substring(1, xpathPatternStr.indexOf('['));
                            String xpathIndexExprStr = xpathPatternStr.substring(xpathPatternStr.indexOf('[') + 1, 
-                                                                                                 xpathPatternStr.indexOf(']'));
+                                                                                                   xpathPatternStr.indexOf(']'));
                            
                            ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
                            List<XMLNSDecl> prefixTable = null;
@@ -448,7 +462,7 @@ public class ElemValueOf extends ElemTemplateElement {
                               prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
                            }
                            
-                           // evaluate the, variable reference XPath expression
+                           // Evaluate the, variable reference XPath expression
                            if (prefixTable != null) {
                               varRefXPathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
                                                                                                              varRefXPathExprStr, 
@@ -457,20 +471,25 @@ public class ElemValueOf extends ElemTemplateElement {
                            
                            XPath xpathObj = new XPath(varRefXPathExprStr, srcLocator, 
                                                                                  xctxt.getNamespaceContext(), XPath.SELECT, null);
+                           if (fVars != null) {
+                              xpathObj.fixupVariables(fVars, fGlobalsSize);                            
+                           }
+                           
                            XObject varEvalResult = xpathObj.execute(xctxt, xctxt.getCurrentNode(), xctxt.getNamespaceContext());
                            
-                           // evaluate the, xdm sequence index XPath expression
+                           // Evaluate the, xdm sequence index XPath expression
                            if (prefixTable != null) {
                               xpathIndexExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
                                                                                                               xpathIndexExprStr, 
                                                                                                               prefixTable);
                            }
-                           
-                           // There may be a possibility, of a variable reference within the xpath expression 
-                           // string 'xpathIndexExprStr'. To try, resolve those variable references.
-                           // REVISIT 
+                            
                            xpathObj = new XPath(xpathIndexExprStr, srcLocator, xctxt.getNamespaceContext(), XPath.SELECT, null);
                            
+                           if (fVars != null) {
+                              xpathObj.fixupVariables(fVars, fGlobalsSize);                            
+                           }
+                           
                            XObject seqIndexEvalResult = xpathObj.execute(xctxt, xctxt.getCurrentNode(), 
                                                                                                   xctxt.getNamespaceContext());
                            if (varEvalResult instanceof ResultSequence) {
@@ -509,10 +528,6 @@ public class ElemValueOf extends ElemTemplateElement {
                               }
                            }                           
                         }
-                        else {
-                           // The implementation behavior is not known here.
-                           // REVISIT
-                        }
                      }
                   }
                   else if (expr instanceof LetExpr) {
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 201dde3d..9bb1ddfb 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -92,7 +92,7 @@ public class ElemVariable extends ElemTemplateElement
    */
   int m_frameSize = -1;
   
-  // the following two fields of this class, are used during 
+  // The following two fields of this class, are used during 
   // XPath.fixupVariables(..) action as performed within object of 
   // this class.    
   private Vector fVars;    
diff --git a/src/org/apache/xalan/templates/XslIterateParamWithparamData.java b/src/org/apache/xalan/templates/XslIterateParamWithparamData.java
index 57460d3f..9cad1878 100644
--- a/src/org/apache/xalan/templates/XslIterateParamWithparamData.java
+++ b/src/org/apache/xalan/templates/XslIterateParamWithparamData.java
@@ -61,6 +61,7 @@ public class XslIterateParamWithparamData {
         if (obj == null || getClass() != obj.getClass()) {
             return false;
         }
+        
         XslIterateParamWithparamData paramWithparamData = 
                                                 (XslIterateParamWithparamData)obj;
         return nameVal.equals(paramWithparamData.getNameVal());
diff --git a/src/org/apache/xpath/XPath.java b/src/org/apache/xpath/XPath.java
index ec3ac9e0..4c0eeb3c 100644
--- a/src/org/apache/xpath/XPath.java
+++ b/src/org/apache/xpath/XPath.java
@@ -21,20 +21,30 @@
 package org.apache.xpath;
 
 import java.io.Serializable;
+import java.util.List;
+import java.util.Vector;
 
 import javax.xml.transform.ErrorListener;
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.XMLNSDecl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.utils.PrefixResolver;
 import org.apache.xml.utils.SAXSourceLocator;
+import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.compiler.Compiler;
 import org.apache.xpath.compiler.FunctionTable;
 import org.apache.xpath.compiler.XPathParser;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSNumericType;
 
 /**
  * The XPath class wraps an expression object and provides general services 
@@ -53,6 +63,12 @@ public class XPath implements Serializable, ExpressionOwner
    * The function table for xpath built-in functions
    */
   private transient FunctionTable m_funcTable = null;
+  
+  // The following two fields of this class, are used during 
+  // XPath.fixupVariables(..) action as performed within object of 
+  // this class.    
+  private Vector fVars;    
+  private int fGlobalsSize;
 
   /**
    * initial the function table
@@ -84,6 +100,9 @@ public class XPath implements Serializable, ExpressionOwner
    */
   public void fixupVariables(java.util.Vector vars, int globalsSize)
   {
+    fVars = (Vector)(vars.clone());
+    fGlobalsSize = globalsSize;
+    
     m_mainExp.fixupVariables(vars, globalsSize);
   }
 
@@ -328,12 +347,111 @@ public class XPath implements Serializable, ExpressionOwner
     xctxt.pushNamespaceContext(namespaceContext);
 
     xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
+    
+    SourceLocator srcLocator = xctxt.getSAXLocator(); 
 
     XObject xobj = null;
+    
+    boolean isToBeProcessedAsNodeSet = true;
+    
+    if (m_mainExp instanceof LocPathIterator) {
+        LocPathIterator locPathIterator = (LocPathIterator)m_mainExp;
+        
+        DTMIterator dtmIter = null;                     
+        try {
+           dtmIter = locPathIterator.asIterator(xctxt, contextNode);
+        }
+        catch (ClassCastException ex) {
+           isToBeProcessedAsNodeSet = false;
+        }
+    }
 
     try
     {
-      xobj = m_mainExp.execute(xctxt);
+       if (isToBeProcessedAsNodeSet) {
+          xobj = m_mainExp.execute(xctxt);
+       }
+       else {
+           String xpathPatternStr = getPatternString();
+           
+           if (xpathPatternStr.startsWith("$") && xpathPatternStr.contains("[") && 
+                                                                        xpathPatternStr.endsWith("]")) {              
+              // Within this 'if' clause, we handle the case, where the XPath expression is
+              // syntactically of type $varName[expr], for example $varName[1], $varName[$idx],
+              // $varName[funcCall(arg)] etc, and $varName resolves to a 'ResultSequence' object.
+               
+              String varRefXPathExprStr = "$" + xpathPatternStr.substring(1, xpathPatternStr.indexOf('['));
+              String xpathIndexExprStr = xpathPatternStr.substring(xpathPatternStr.indexOf('[') + 1, 
+                                                                                      xpathPatternStr.indexOf(']'));
+              ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
+              List<XMLNSDecl> prefixTable = null;
+              if (elemTemplateElement != null) {
+                 prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
+              }
+              
+              // Evaluate the, variable reference XPath expression
+              if (prefixTable != null) {
+                 varRefXPathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+                                                                                                varRefXPathExprStr, 
+                                                                                                prefixTable);
+              }
+              
+              XPath xpathObj = new XPath(varRefXPathExprStr, srcLocator, 
+                                                                    xctxt.getNamespaceContext(), XPath.SELECT, null);            
+              if (fVars != null) {
+                 xpathObj.fixupVariables(fVars, fGlobalsSize);  
+              }
+              
+              XObject varEvalResult = xpathObj.execute(xctxt, xctxt.getCurrentNode(), xctxt.getNamespaceContext());
+              
+              // Evaluate the, xdm sequence index XPath expression
+              if (prefixTable != null) {
+                 xpathIndexExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+                                                                                                 xpathIndexExprStr, 
+                                                                                                 prefixTable);
+              }
+              
+              xpathObj = new XPath(xpathIndexExprStr, srcLocator, xctxt.getNamespaceContext(), XPath.SELECT, null);
+              
+              if (fVars != null) {
+                 xpathObj.fixupVariables(fVars, fGlobalsSize);  
+              }
+              
+              XObject seqIndexEvalResult = xpathObj.execute(xctxt, xctxt.getCurrentNode(), 
+                                                                                     xctxt.getNamespaceContext());
+              if (varEvalResult instanceof ResultSequence) {
+                 ResultSequence resultSeq = (ResultSequence)varEvalResult;
+                 
+                 if (seqIndexEvalResult instanceof XNumber) {
+                    double dValIndex = ((XNumber)seqIndexEvalResult).num();
+                    if (dValIndex == (int)dValIndex) {
+                       xobj = resultSeq.item((int)dValIndex - 1);
+                    }
+                    else {
+                       throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm "
+                                                                                            + "sequence reference, is not an integer.", 
+                                                                                                 srcLocator); 
+                    }  
+                 }
+                 else if (seqIndexEvalResult instanceof XSNumericType) {
+                    String indexStrVal = ((XSNumericType)seqIndexEvalResult).stringValue();
+                    double dValIndex = (Double.valueOf(indexStrVal)).doubleValue();
+                    if (dValIndex == (int)dValIndex) {
+                       xobj = resultSeq.item((int)dValIndex - 1);                                  
+                    }
+                    else {
+                       throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm "
+                                                                                            + "sequence reference, is not an integer.", 
+                                                                                                 srcLocator); 
+                    } 
+                 }
+                 else {
+                    throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm sequence "
+                                                                                           + "reference, is not numeric.", srcLocator);  
+                 }
+              }          
+           }  
+       }
     }
     catch (TransformerException te)
     {
diff --git a/src/org/apache/xpath/axes/PredicatedNodeTest.java b/src/org/apache/xpath/axes/PredicatedNodeTest.java
index e6dbd7af..4cedf4fc 100644
--- a/src/org/apache/xpath/axes/PredicatedNodeTest.java
+++ b/src/org/apache/xpath/axes/PredicatedNodeTest.java
@@ -28,8 +28,10 @@ import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.XPathVisitor;
 import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.patterns.NodeTest;
+import org.apache.xpath.xs.types.XSInteger;
 
 public abstract class PredicatedNodeTest extends NodeTest implements SubContextList
 {
@@ -340,6 +342,13 @@ public abstract class PredicatedNodeTest extends NodeTest implements SubContextL
       {
         // System.out.println("Executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
         XObject pred = m_predicates[i].execute(xctxt);
+        
+        if (pred instanceof XSInteger) {
+           // added for XPath 3.1
+           String strValue = ((XSInteger)pred).stringValue();
+           pred = new XNumber((Double.valueOf(strValue)).doubleValue());
+        }
+        
         // System.out.println("\nBack from executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
         // System.out.println("pred.getType(): "+pred.getType());
         if (XObject.CLASS_NUMBER == pred.getType())
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 0668e2a8..2806c54f 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -98,9 +98,9 @@ public class XPathParser
                                                       "else", "some", "every", "satisfies", 
                                                       "let", ":=", "-", "||"};
   
-  // If the XPath expression is () (i.e, representing an xdm empty sequence), we
-  // translate that internally within this XPath parser implementation, to an
-  // XPath range "to" expression using this class field (this equivalently produces
+  // If the 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).
   private static final String XPATH_EXPR_STR_EMPTY_SEQUENCE = "1 to 0";
   
@@ -1226,7 +1226,7 @@ public class XPathParser
           
           ForQuantifiedExprVarBinding forExprVarBinding = new ForQuantifiedExprVarBinding();
           forExprVarBinding.setVarName(bindingVarName);
-          forExprVarBinding.setXpathExprStr(varBindingXpathStr);
+          forExprVarBinding.setXPathExprStr(varBindingXpathStr);
           
           forExprVarBindingList.add(forExprVarBinding);
           
@@ -1409,7 +1409,7 @@ public class XPathParser
           
           ForQuantifiedExprVarBinding quantifiedExprVarBinding = new ForQuantifiedExprVarBinding();
           quantifiedExprVarBinding.setVarName(bindingVarName);
-          quantifiedExprVarBinding.setXpathExprStr(varBindingXpathStr);
+          quantifiedExprVarBinding.setXPathExprStr(varBindingXpathStr);
           
           quantifiedExprVarBindingList.add(quantifiedExprVarBinding);
           
@@ -2519,9 +2519,11 @@ public class XPathParser
 
     int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
     
+    appendOp(2, OpCodes.OP_ARGUMENT);
+    
     if (tokenIs('(') && lookahead(')', 1)) {
-        // handles the case, where the XPath expression (i.e, 
-        // function argument) is ().
+        // handles the case, where the XPath function 
+        // argument is ().                
         
         nextToken();
         nextToken();                            
@@ -2542,11 +2544,10 @@ public class XPathParser
         return; 
     }
 
-    appendOp(2, OpCodes.OP_ARGUMENT);
     Expr();
     
     m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
-      m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+                                           m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
   }
 
   /**
diff --git a/src/org/apache/xpath/composite/ForExpr.java b/src/org/apache/xpath/composite/ForExpr.java
index b46c7ad6..583f950a 100644
--- a/src/org/apache/xpath/composite/ForExpr.java
+++ b/src/org/apache/xpath/composite/ForExpr.java
@@ -65,7 +65,7 @@ public class ForExpr extends Expression {
     
     private String fReturnExprXPathStr = null;
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
@@ -93,11 +93,11 @@ public class ForExpr extends Expression {
                                                                                        fReturnExprXPathStr, prefixTable);
        }
        
-       XPath returnExprXpath = new XPath(fReturnExprXPathStr, srcLocator, xctxt.getNamespaceContext(), 
+       XPath returnExprXPath = new XPath(fReturnExprXPathStr, srcLocator, xctxt.getNamespaceContext(), 
                                                                                                XPath.SELECT, null);
        
        ResultSequence resultSeq = getForExpressionEvalResult(fForExprVarBindingList.listIterator(), 
-                                                                            returnExprXpath, xctxt);       
+                                                                            returnExprXPath, xctxt);       
        
        // An xdm sequence object 'resultSeq', may have items that are themselves sequence 
        // objects. We need to expand such nested sequence objects, to get a final sequence
@@ -141,7 +141,7 @@ public class ForExpr extends Expression {
      * of the XPath 'for' expression, returned as a 'ResultSequence' object.
      */
     private ResultSequence getForExpressionEvalResult(ListIterator listIter, 
-                                                                     XPath returnExprXpath, 
+                                                                     XPath returnExprXPath, 
                                                                      XPathContext xctxt) throws TransformerException {
         ResultSequence resultSeq = new ResultSequence();
         
@@ -154,10 +154,10 @@ public class ForExpr extends Expression {
         if (listIter.hasNext()) {           
            ForQuantifiedExprVarBinding forExprVarBinding = (ForQuantifiedExprVarBinding)listIter.next();            
             
-           // evaluate the current, variable binding xpath expression
+           // Evaluate the XPath 'for' expression's, one of the variable binding xpath expression
            
            String varName = forExprVarBinding.getVarName();
-           String varBindingXPathStr = forExprVarBinding.getXpathExprStr();
+           String varBindingXPathStr = forExprVarBinding.getXPathExprStr();
            
            ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
            List<XMLNSDecl> prefixTable = null;
@@ -170,16 +170,14 @@ public class ForExpr extends Expression {
                                                                                             varBindingXPathStr, prefixTable);
            }
            
-           XPath varBindingXpath = new XPath(varBindingXPathStr, srcLocator, xctxt.getNamespaceContext(), 
+           XPath varBindingXPath = new XPath(varBindingXPathStr, srcLocator, xctxt.getNamespaceContext(), 
                                                                                                  XPath.SELECT, null);
            if (fVars != null) {
-              if (!m_xpathVarList.contains(new QName(varName))) {
-                 m_xpathVarList.add(new QName(varName));
-              }
-              varBindingXpath.fixupVariables(fVars, fGlobalsSize);
+              m_xpathVarList.add(new QName(varName));
+              varBindingXPath.fixupVariables(fVars, fGlobalsSize);
            }
            
-           XObject xsObj = varBindingXpath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+           XObject xsObj = varBindingXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
            
            ResultSequence xsObjResultSeq = new ResultSequence(); 
            
@@ -201,9 +199,7 @@ public class ForExpr extends Expression {
                }
            }
            else {
-              // we're assuming here that, 'for' expression's variable binding XPath 
-              // expression evaluation, returned a singleton value.
-              xsObjResultSeq.add(xsObj);
+               xsObjResultSeq.add(xsObj);
            }
            
            if (xsObjResultSeq.size() == 0) {
@@ -212,7 +208,7 @@ public class ForExpr extends Expression {
                return resultSeq;    
            }
            
-           // for each xdm item within sequence object 'xsObjResultSeq' (which is the 
+           // For each xdm item within sequence object 'xsObjResultSeq' (which is the 
            // result of variable binding xpath expression's evaluation), bind the 'for' 
            // expression's binding variable in turn to that item.
            for (int idx = 0; idx < xsObjResultSeq.size(); idx++) {
@@ -220,10 +216,11 @@ public class ForExpr extends Expression {
                              
                forExprVarBindingMap.put(new QName(varName), xdmItem);
                
-               ResultSequence res = getForExpressionEvalResult(listIter, returnExprXpath, xctxt);
-               // append xdm items of sequence 'res', to the final sequence object 'resultSeq'   
+               ResultSequence res = getForExpressionEvalResult(listIter, returnExprXPath, xctxt);
+               // Append xdm items of sequence 'res', to the final sequence object 'resultSeq'   
                for (int idx1 = 0; idx1 < res.size(); idx1++) {
-                  resultSeq.add(res.item(idx1));    
+                  XObject xObj = res.item(idx1);
+                  resultSeq.add(xObj);    
                }
            }
            
@@ -232,18 +229,44 @@ public class ForExpr extends Expression {
            return resultSeq;
         }
         else {
-            // this else clause, actually evaluates the current XPath 'for' expression's 
-            // 'return' expression clause.
+            // This else clause, evaluates the XPath 'for' expression's 'return' 
+            // expression. The XPath 'for' expression's 'return' expression may
+            // be evaluated multiple times depending upon, how may 'for' expression
+            // iterations are there.
             
             if (fVars != null) {              
-               returnExprXpath.fixupVariables(fVars, fGlobalsSize);
+               returnExprXPath.fixupVariables(fVars, fGlobalsSize);
             }
             
-            XObject retExprValue = returnExprXpath.execute(xctxt, contextNode, 
+            ResultSequence returnExprResultSet = new ResultSequence();
+            
+            XObject retExprResultVal = returnExprXPath.execute(xctxt, contextNode, 
                                                                         xctxt.getNamespaceContext());
-            resultSeq.add(retExprValue);
             
-            return resultSeq; 
+            if (retExprResultVal instanceof XNodeSet) { 
+               XNodeSet xNodeSetItem = (XNodeSet)retExprResultVal;
+               
+               XNodeSet xsObjNodeSet = (XNodeSet)xNodeSetItem;
+               DTMIterator dtmIter = xsObjNodeSet.iterRaw();
+               
+               int nextNodeDtmHandle;
+                      
+               while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {       
+                  XNodeSet singletonXPathNode = new XNodeSet(nextNodeDtmHandle, xctxt);
+                  returnExprResultSet.add(singletonXPathNode);
+               }
+            }
+            else if (retExprResultVal instanceof ResultSequence) {
+                ResultSequence rSeq = (ResultSequence)retExprResultVal;
+                for (int idx = 0; idx < rSeq.size(); idx++) {
+                    returnExprResultSet.add(rSeq.item(idx)); 
+                } 
+            }
+            else {
+                returnExprResultSet.add(retExprResultVal);
+            }
+            
+            return returnExprResultSet; 
         }
     }
 
diff --git a/src/org/apache/xpath/composite/ForQuantifiedExprVarBinding.java b/src/org/apache/xpath/composite/ForQuantifiedExprVarBinding.java
index fd4d40ab..e6b32f8d 100644
--- a/src/org/apache/xpath/composite/ForQuantifiedExprVarBinding.java
+++ b/src/org/apache/xpath/composite/ForQuantifiedExprVarBinding.java
@@ -32,7 +32,7 @@ public class ForQuantifiedExprVarBinding {
     
     private String fVarName = null;
     
-    private String fXpathExprStr = null;
+    private String fXPathExprStr = null;
 
     public String getVarName() {
         return fVarName;
@@ -42,12 +42,12 @@ public class ForQuantifiedExprVarBinding {
         this.fVarName = varName;
     }
 
-    public String getXpathExprStr() {
-        return fXpathExprStr;
+    public String getXPathExprStr() {
+        return fXPathExprStr;
     }
 
-    public void setXpathExprStr(String xpathExprStr) {
-        this.fXpathExprStr = xpathExprStr;
+    public void setXPathExprStr(String xpathExprStr) {
+        this.fXPathExprStr = xpathExprStr;
     }
 
 }
diff --git a/src/org/apache/xpath/composite/IfExpr.java b/src/org/apache/xpath/composite/IfExpr.java
index b06399c1..ce07ea93 100644
--- a/src/org/apache/xpath/composite/IfExpr.java
+++ b/src/org/apache/xpath/composite/IfExpr.java
@@ -56,7 +56,7 @@ public class IfExpr extends Expression {
     
     private String elseExprXPathStr;
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
diff --git a/src/org/apache/xpath/composite/LetExpr.java b/src/org/apache/xpath/composite/LetExpr.java
index e36f364e..a3ee20b8 100644
--- a/src/org/apache/xpath/composite/LetExpr.java
+++ b/src/org/apache/xpath/composite/LetExpr.java
@@ -61,7 +61,7 @@ public class LetExpr extends Expression {
     
     private String fReturnExprXPathStr = null;
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
diff --git a/src/org/apache/xpath/composite/QuantifiedExpr.java b/src/org/apache/xpath/composite/QuantifiedExpr.java
index d6e4357d..76736246 100644
--- a/src/org/apache/xpath/composite/QuantifiedExpr.java
+++ b/src/org/apache/xpath/composite/QuantifiedExpr.java
@@ -74,7 +74,7 @@ public class QuantifiedExpr extends Expression {
 
     private String fQuantifierTestXPathStr = null;
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
@@ -207,7 +207,7 @@ public class QuantifiedExpr extends Expression {
            // evaluate the current, variable binding xpath expression
            
            String varName = quantifiedExprVarBinding.getVarName();
-           String varBindingXPathStr = quantifiedExprVarBinding.getXpathExprStr();                      
+           String varBindingXPathStr = quantifiedExprVarBinding.getXPathExprStr();                      
            
            if (prefixTable != null) {
                varBindingXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
diff --git a/src/org/apache/xpath/composite/SimpleSequenceConstructor.java b/src/org/apache/xpath/composite/SimpleSequenceConstructor.java
index d2026c82..d3065cc0 100644
--- a/src/org/apache/xpath/composite/SimpleSequenceConstructor.java
+++ b/src/org/apache/xpath/composite/SimpleSequenceConstructor.java
@@ -63,7 +63,7 @@ public class SimpleSequenceConstructor extends Expression {
     
     private List<String> sequenceConstructorXPathParts = new ArrayList<String>();
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
diff --git a/src/org/apache/xpath/functions/DynamicFunctionCall.java b/src/org/apache/xpath/functions/DynamicFunctionCall.java
index 20a7c810..de869f33 100644
--- a/src/org/apache/xpath/functions/DynamicFunctionCall.java
+++ b/src/org/apache/xpath/functions/DynamicFunctionCall.java
@@ -56,7 +56,7 @@ public class DynamicFunctionCall extends Expression {
     
     private List<String> argList;
     
-    // the following two fields of this class, are used during 
+    // The following two fields of this class, are used during 
     // XPath.fixupVariables(..) action as performed within object of 
     // this class.    
     private Vector fVars;    
@@ -123,7 +123,7 @@ public class DynamicFunctionCall extends Expression {
        if ((functionRef != null) && (functionRef instanceof InlineFunction)) {
            InlineFunction inlineFunction = (InlineFunction)functionRef;
            
-           String inlineFnXpathStr = inlineFunction.getFuncBodyXPathExprStr();
+           String inlineFnXPathStr = inlineFunction.getFuncBodyXPathExprStr();
            List<String> funcParamNameList = inlineFunction.getFuncParamNameList();           
            
            if (argList.size() != funcParamNameList.size()) {
@@ -148,25 +148,30 @@ public class DynamicFunctionCall extends Expression {
                                                                                                       prefixTable);
               }
               
-              XPath argXpath = new XPath(argXPathStr, srcLocator, xctxt.getNamespaceContext(), 
+              XPath argXPath = new XPath(argXPathStr, srcLocator, xctxt.getNamespaceContext(), 
                                                                                         XPath.SELECT, null);
               if (fVars != null) {
-                 argXpath.fixupVariables(fVars, fGlobalsSize);
+                 argXPath.fixupVariables(fVars, fGlobalsSize);
               }
               
-              XObject argValue = argXpath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+              XObject argValue = argXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
               
+              m_xpathVarList.add(new QName(funcParamName));
               inlineFunctionVarMap.put(new QName(funcParamName), argValue);
            }
            
            if (prefixTable != null) {
-               inlineFnXpathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(inlineFnXpathStr, 
+              inlineFnXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(inlineFnXPathStr, 
                                                                                                            prefixTable);
            }
            
-           XPath inlineFnXpath = new XPath(inlineFnXpathStr, srcLocator, xctxt.getNamespaceContext(), 
+           XPath inlineFnXPath = new XPath(inlineFnXPathStr, srcLocator, xctxt.getNamespaceContext(), 
                                                                                        XPath.SELECT, null);
-           evalResult = inlineFnXpath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+           if (fVars != null) {
+              inlineFnXPath.fixupVariables(fVars, fGlobalsSize);
+           }
+           
+           evalResult = inlineFnXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
            
            inlineFunctionVarMap.clear();           
        }
diff --git a/src/org/apache/xpath/functions/FuncFilter.java b/src/org/apache/xpath/functions/FuncFilter.java
index 0aefe020..6cc59fdd 100644
--- a/src/org/apache/xpath/functions/FuncFilter.java
+++ b/src/org/apache/xpath/functions/FuncFilter.java
@@ -69,7 +69,7 @@ public class FuncFilter extends Function2Args {
    
    private static final String FUNCTION_NAME = "filter()";
    
-   // the following two fields of this class, are used during 
+   // The following two fields of this class, are used during 
    // XPath.fixupVariables(..) action as performed within object of 
    // this class.    
    private Vector fVars;    
diff --git a/src/org/apache/xpath/functions/FuncForEach.java b/src/org/apache/xpath/functions/FuncForEach.java
index 1c9ad874..057a024d 100644
--- a/src/org/apache/xpath/functions/FuncForEach.java
+++ b/src/org/apache/xpath/functions/FuncForEach.java
@@ -64,7 +64,7 @@ public class FuncForEach extends Function2Args {
    
    private static final String FUNCTION_NAME = "for-each()";
    
-   // the following two fields of this class, are used during 
+   // The following two fields of this class, are used during 
    // XPath.fixupVariables(..) action as performed within object of 
    // this class.    
    private Vector fVars;    
diff --git a/src/org/apache/xpath/functions/FuncSum.java b/src/org/apache/xpath/functions/FuncSum.java
index b8c0a699..2436087a 100644
--- a/src/org/apache/xpath/functions/FuncSum.java
+++ b/src/org/apache/xpath/functions/FuncSum.java
@@ -62,6 +62,13 @@ public class FuncSum extends FunctionOneArg
           sum = sumResultSequence(resultSeq);          
        }       
     }
+    else if (m_arg0 instanceof Function) {
+       XObject resultObj = ((Function)m_arg0).execute(xctxt);
+       if (resultObj instanceof ResultSequence) {
+          ResultSequence resultSeq = (ResultSequence)resultObj;
+          sum = sumResultSequence(resultSeq);          
+       }  
+    }
     else if (m_arg0 instanceof ForExpr) {
        ForExpr forExpr = (ForExpr)m_arg0;
        ResultSequence forExprResult = (ResultSequence)(forExpr.execute(xctxt));
diff --git a/src/org/apache/xpath/functions/FunctionDef1Arg.java b/src/org/apache/xpath/functions/FunctionDef1Arg.java
index 27082536..848a4a80 100644
--- a/src/org/apache/xpath/functions/FunctionDef1Arg.java
+++ b/src/org/apache/xpath/functions/FunctionDef1Arg.java
@@ -21,9 +21,11 @@
 package org.apache.xpath.functions;
 
 import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.utils.XMLString;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
 import org.apache.xpath.objects.XString;
 import org.apache.xpath.res.XPATHErrorResources;
 
@@ -93,8 +95,11 @@ public class FunctionDef1Arg extends FunctionOneArg
       }
       
     }
-    else
-      return m_arg0.execute(xctxt).xstr();   
+    else {
+      XObject arg0XObject = m_arg0.execute(xctxt);
+      
+      return new XString(XslTransformEvaluationHelper.getStrVal(arg0XObject));
+    }
   }
 
   /**
diff --git a/tests/fn_sort/gold/test6.out b/tests/fn_sort/gold/test6.out
new file mode 100644
index 00000000..c582bb8a
--- /dev/null
+++ b/tests/fn_sort/gold/test6.out
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><document>
+  <person>
+      <name>Michael</name>
+   </person>
+  <person>
+      <name>Mary</name>
+   </person>
+  <person>
+      <name>Dave</name>
+   </person>
+</document>
diff --git a/tests/fn_sort/gold/test7.out b/tests/fn_sort/gold/test7.out
new file mode 100644
index 00000000..b2c1b3ad
--- /dev/null
+++ b/tests/fn_sort/gold/test7.out
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><document>
+  <person id="1">
+    <name>Michael</name>
+  </person>
+  <person id="3">
+    <name>Mary</name>
+  </person>
+  <person id="2">
+    <name>Dave</name>
+  </person>
+</document>
diff --git a/tests/fn_sort/gold/test8.out b/tests/fn_sort/gold/test8.out
new file mode 100644
index 00000000..11d292ed
--- /dev/null
+++ b/tests/fn_sort/gold/test8.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>16 15 12 11 10 2 -2</result>
diff --git a/tests/fn_sort/gold/test9.out b/tests/fn_sort/gold/test9.out
new file mode 100644
index 00000000..987df541
--- /dev/null
+++ b/tests/fn_sort/gold/test9.out
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>
+    <val>16</val>
+    <val>15</val>
+    <val>12</val>
+    <val>11</val>
+    <val>10</val>
+    <val>2</val>
+    <val>-2</val>
+  </one>
+  <two>
+    <val>16</val>
+    <val>15</val>
+    <val>12</val>
+    <val>11</val>
+    <val>10</val>
+    <val>2</val>
+    <val>-2</val>
+  </two>
+</result>
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test10.xsl
similarity index 52%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test10.xsl
index cb7a4ac8..f2df7950 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test10.xsl
@@ -4,31 +4,41 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
+   <!-- use with test1_e.xml -->
    
    <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
         by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   
+        This stylesheet example, first sorts an XML input element list using
+        fn:sort function, and then reverses that produced sequence using a 
+        dynamic function call to a function item, which provides us the
+        final resulting information in descending order.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
+   <!-- A variable, defining a function item, that reverses the order of an xdm 
+        input sequence. -->
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
    <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
+      <document>        
+        <xsl:variable name="sortedPersonList" select="sort(person, (), function($person) { string($person/name) })"/>
+        <xsl:iterate select="$fnReverse($sortedPersonList)">
+           <xsl:apply-templates select="." mode="m1"/>
         </xsl:iterate>
       </document>
    </xsl:template>
    
+   <!-- XSL transformation of XML person element, transforming an XML element 
+        information to attribute. Using a 'mode' attribute allows us to
+        unambiguously select this XSL template during transformation. -->
+   <xsl:template match="person" mode="m1">
+      <person id="{id}">
+         <xsl:copy-of select="name"/>
+      </person>
+   </xsl:template>
+   
    <!--
       * Licensed to the Apache Software Foundation (ASF) under one
       * or more contributor license agreements. See the NOTICE file
diff --git a/tests/fn_sort/test3.xsl b/tests/fn_sort/test11.xsl
similarity index 66%
copy from tests/fn_sort/test3.xsl
copy to tests/fn_sort/test11.xsl
index 462d0a3a..8c8e2652 100644
--- a/tests/fn_sort/test3.xsl
+++ b/tests/fn_sort/test11.xsl
@@ -4,22 +4,22 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_b.xml -->
-   
-   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
-        by reading input data from an XML external source document. 
-        
-        This stylesheet, sorts a sequence of XML person elements by last name 
-        as the major sort key and first name as the minor sort key, using the 
-        default collation.
-   -->                
+   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function, and
+        post processing the fn:sort function result, with an XPath dynamic function
+        call to a function item.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
-   <xsl:template match="/document">
-      <document>       
-         <xsl:copy-of select="sort(person, (), function($person) { $person/lName || ':' || $person/fName })"/>
-      </document>
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
+   <xsl:template match="/">
+      <result>
+        <xsl:variable name="seq1" select="(10, 15, 16, 2, -2, 11, 12)"/>        
+        <xsl:variable name="sortedSequence" select="sort($seq1, (), function($num) { number($num) })"/>
+        
+        <xsl:copy-of select="$fnReverse($sortedSequence)"/>
+      </result>
    </xsl:template>
    
    <!--
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test12.xsl
similarity index 52%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test12.xsl
index cb7a4ac8..63ed68b2 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test12.xsl
@@ -4,29 +4,32 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
-   
-   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
-        by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function, and
+        post processing the fn:sort function result, with an XPath dynamic function
+        call to a function item.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
-   <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
-        </xsl:iterate>
-      </document>
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
+   <xsl:template match="/">
+      <result>
+        <xsl:variable name="seq1" select="(10, 15, 16, 2, -2, 11, 12)"/>        
+        <xsl:variable name="sortedSequence" select="sort($seq1, (), function($num) { number($num) })"/>
+        <one>
+           <!-- process result of function call $fnReverse(..) with an xsl:for-each instruction. -->
+           <xsl:for-each select="$fnReverse($sortedSequence)">
+              <val><xsl:value-of select="."/></val>
+           </xsl:for-each>
+        </one>
+        <two>
+           <!-- process result of function call $fnReverse(..) with an xsl:iterate instruction. -->
+           <xsl:iterate select="$fnReverse($sortedSequence)">
+              <val><xsl:value-of select="."/></val>
+           </xsl:iterate>
+        </two>
+      </result>
    </xsl:template>
    
    <!--
diff --git a/tests/fn_sort/test1_d.xml b/tests/fn_sort/test1_d.xml
new file mode 100644
index 00000000..9c8fa6a6
--- /dev/null
+++ b/tests/fn_sort/test1_d.xml
@@ -0,0 +1,11 @@
+<document>
+   <person>
+      <name>Michael</name>
+   </person>
+   <person>
+      <name>Dave</name>
+   </person>
+   <person>
+      <name>Mary</name>
+   </person>
+</document>
\ No newline at end of file
diff --git a/tests/fn_sort/test1_e.xml b/tests/fn_sort/test1_e.xml
new file mode 100644
index 00000000..b8adab19
--- /dev/null
+++ b/tests/fn_sort/test1_e.xml
@@ -0,0 +1,14 @@
+<document>
+   <person>
+      <id>1</id>
+      <name>Michael</name>
+   </person>
+   <person>
+      <id>2</id>
+      <name>Dave</name>
+   </person>
+   <person>
+      <id>3</id>
+      <name>Mary</name>
+   </person>
+</document>
\ No newline at end of file
diff --git a/tests/fn_sort/test3.xsl b/tests/fn_sort/test3.xsl
index 462d0a3a..6c754ea3 100644
--- a/tests/fn_sort/test3.xsl
+++ b/tests/fn_sort/test3.xsl
@@ -18,7 +18,7 @@
    
    <xsl:template match="/document">
       <document>       
-         <xsl:copy-of select="sort(person, (), function($person) { $person/lName || ':' || $person/fName })"/>
+         <xsl:copy-of select="sort(person, (), function($person) { string($person/lName) || ':' || string($person/fName) })"/>
       </document>
    </xsl:template>
    
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test5.xsl
index cb7a4ac8..c4e911df 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test5.xsl
@@ -10,8 +10,8 @@
         by reading input data from an XML external source document.
         
         The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
+        is in the descending order (due to the fact that, fn:sort function
+        call specifies an XPath sort key expression as -1 * number(..)). 
         
         This stylesheet example, post processes the result of fn:sort
         function call, by the xsl:iterate instruction.
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test6.xsl
similarity index 62%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test6.xsl
index cb7a4ac8..3cdecf6e 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test6.xsl
@@ -4,28 +4,27 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
+   <!-- use with test1_d.xml -->
    
    <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
         by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   
+        This stylesheet example, first sorts an XML input element list using
+        fn:sort function, and then reverses that produced sequence using a 
+        dynamic function call to a function item, which provides us the
+        final resulting information in descending order.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
+   <!-- A variable, defining a function item, that reverses the order of an xdm 
+        input sequence. -->
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
    <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
-        </xsl:iterate>
+      <document>        
+        <xsl:variable name="sortedPersonList" select="sort(person, (), function($person) { string($person/name) })"/>
+        <xsl:copy-of select="$fnReverse($sortedPersonList)"/>
       </document>
    </xsl:template>
    
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test7.xsl
similarity index 60%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test7.xsl
index cb7a4ac8..8a09b674 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test7.xsl
@@ -4,28 +4,29 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
+   <!-- use with test1_d.xml -->
    
    <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
         by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   
+        This stylesheet example, first sorts an XML input element list using
+        fn:sort function, and then reverses that produced sequence using a 
+        dynamic function call to a function item, which provides us the
+        final resulting information in descending order.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
+   <!-- A variable, defining a function item, that reverses the order of an xdm 
+        input sequence. -->
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
    <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
-        </xsl:iterate>
+      <document>        
+        <xsl:variable name="sortedPersonList" select="sort(person, (), function($person) { string($person/name) })"/>
+        <xsl:for-each select="$fnReverse($sortedPersonList)">
+           <xsl:copy-of select="."/>
+        </xsl:for-each>
       </document>
    </xsl:template>
    
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test8.xsl
similarity index 61%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test8.xsl
index cb7a4ac8..d3a0a20b 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test8.xsl
@@ -4,27 +4,28 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
+   <!-- use with test1_d.xml -->
    
    <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
         by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   
+        This stylesheet example, first sorts an XML input element list using
+        fn:sort function, and then reverses that produced sequence using a 
+        dynamic function call to a function item, which provides us the
+        final resulting information in descending order.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
+   <!-- A variable, defining a function item, that reverses the order of an xdm 
+        input sequence. -->
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
    <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
+      <document>        
+        <xsl:variable name="sortedPersonList" select="sort(person, (), function($person) { string($person/name) })"/>
+        <xsl:iterate select="$fnReverse($sortedPersonList)">
+           <xsl:copy-of select="."/>
         </xsl:iterate>
       </document>
    </xsl:template>
diff --git a/tests/fn_sort/test5.xsl b/tests/fn_sort/test9.xsl
similarity index 51%
copy from tests/fn_sort/test5.xsl
copy to tests/fn_sort/test9.xsl
index cb7a4ac8..a058d853 100644
--- a/tests/fn_sort/test5.xsl
+++ b/tests/fn_sort/test9.xsl
@@ -4,31 +4,41 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_c.xml -->
+   <!-- use with test1_e.xml -->
    
    <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
         by reading input data from an XML external source document.
-        
-        The fn:sort function call result, produced by this stylesheet,
-        is in the descending order, because fn:sort function call
-        specifies an XPath sort key expression as -1 * number(..). 
-        
-        This stylesheet example, post processes the result of fn:sort
-        function call, by the xsl:iterate instruction.
-   -->                
+   
+        This stylesheet example, first sorts an XML input element list using
+        fn:sort function, and then reverses that produced sequence using a 
+        dynamic function call to a function item, which provides us the
+        final resulting information in descending order.
+   -->                             
 
    <xsl:output method="xml" indent="yes"/>
    
+   <!-- A variable, defining a function item, that reverses the order of an xdm 
+        input sequence. -->
+   <xsl:variable name="fnReverse" select="function($seq) { for $idx in (-1 * count($seq)) to -1 return $seq[abs($idx)]}"/>
+   
    <xsl:template match="/document">
-      <document>
-        <xsl:iterate select="sort((a | data/@*), (), function($val) { -1 * number($val) })">
-          <val>
-            <xsl:value-of select="."/>
-          </val>        
-        </xsl:iterate>
+      <document>        
+        <xsl:variable name="sortedPersonList" select="sort(person, (), function($person) { string($person/name) })"/>
+        <xsl:for-each select="$fnReverse($sortedPersonList)">
+           <xsl:apply-templates select="." mode="m1"/>
+        </xsl:for-each>
       </document>
    </xsl:template>
    
+   <!-- XSL transformation of XML person element, transforming an XML element 
+        information to attribute. Using a 'mode' attribute allows us to
+        unambiguously select this XSL template during transformation. -->
+   <xsl:template match="person" mode="m1">
+      <person id="{id}">
+         <xsl:copy-of select="name"/>
+      </person>
+   </xsl:template>
+   
    <!--
       * Licensed to the Apache Software Foundation (ASF) under one
       * or more contributor license agreements. See the NOTICE file
diff --git a/tests/org/apache/xalan/xpath3/FnSortTests.java b/tests/org/apache/xalan/xpath3/FnSortTests.java
index 8e2cfe54..c5ccb818 100644
--- a/tests/org/apache/xalan/xpath3/FnSortTests.java
+++ b/tests/org/apache/xalan/xpath3/FnSortTests.java
@@ -98,5 +98,75 @@ public class FnSortTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslFnSortTest6() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest7() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest8() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest9() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest10() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test8.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/org/apache/xalan/xpath3/SequenceConstructorTests.java b/tests/org/apache/xalan/xpath3/SequenceConstructorTests.java
index b534f0f4..c6aa5c76 100644
--- a/tests/org/apache/xalan/xpath3/SequenceConstructorTests.java
+++ b/tests/org/apache/xalan/xpath3/SequenceConstructorTests.java
@@ -147,5 +147,25 @@ public class SequenceConstructorTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslSequenceConstructorTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslSequenceConstructorTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/sequence_constructor/gold/test9.out b/tests/sequence_constructor/gold/test9.out
new file mode 100644
index 00000000..082a7c16
--- /dev/null
+++ b/tests/sequence_constructor/gold/test9.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><document>
+  <info>10</info>
+  <info>15</info>
+  <info>
+    <person>
+    <name>Dave</name>
+  </person>
+  </info>
+  <info>
+    <person>
+    <name>Mary</name>
+  </person>
+  </info>
+</document>
diff --git a/tests/fn_sort/test3.xsl b/tests/sequence_constructor/test11.xsl
similarity index 64%
copy from tests/fn_sort/test3.xsl
copy to tests/sequence_constructor/test11.xsl
index 462d0a3a..158539f2 100644
--- a/tests/fn_sort/test3.xsl
+++ b/tests/sequence_constructor/test11.xsl
@@ -4,21 +4,25 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_b.xml -->
+   <!-- use with test1_e.xml -->
    
-   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
-        by reading input data from an XML external source document. 
-        
-        This stylesheet, sorts a sequence of XML person elements by last name 
-        as the major sort key and first name as the minor sort key, using the 
-        default collation.
-   -->                
+   <!-- An XSLT stylesheet test, to test the XPath 3.1 sequence construction
+        using comma operator. The XPath sequence constructor example,
+        illustrated within this stylesheet is a heterogeneous sequence
+        comprising of atomic values and XML elements. We traverse this
+        sequence, using xsl:for-each instruction. -->                              
 
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/document">
-      <document>       
-         <xsl:copy-of select="sort(person, (), function($person) { $person/lName || ':' || $person/fName })"/>
+      <document>
+        <xsl:variable name="seq1" select="(10, 15, person[2], person[3])"/>
+
+        <xsl:for-each select="$seq1">
+           <info>
+              <xsl:copy-of select="."/>
+           </info>
+        </xsl:for-each>
       </document>
    </xsl:template>
    
diff --git a/tests/fn_sort/test3.xsl b/tests/sequence_constructor/test12.xsl
similarity index 64%
copy from tests/fn_sort/test3.xsl
copy to tests/sequence_constructor/test12.xsl
index 462d0a3a..b2656675 100644
--- a/tests/fn_sort/test3.xsl
+++ b/tests/sequence_constructor/test12.xsl
@@ -4,21 +4,25 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_b.xml -->
+   <!-- use with test1_e.xml -->
    
-   <!-- An XSLT stylesheet test case, to test XPath 3.1 fn:sort function,
-        by reading input data from an XML external source document. 
-        
-        This stylesheet, sorts a sequence of XML person elements by last name 
-        as the major sort key and first name as the minor sort key, using the 
-        default collation.
-   -->                
+   <!-- An XSLT stylesheet test, to test the XPath 3.1 sequence construction
+        using comma operator. The XPath sequence constructor example,
+        illustrated within this stylesheet is a heterogeneous sequence
+        comprising of atomic values and XML elements. We traverse this
+        sequence, using xsl:iterate instruction. -->                              
 
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/document">
-      <document>       
-         <xsl:copy-of select="sort(person, (), function($person) { $person/lName || ':' || $person/fName })"/>
+      <document>
+        <xsl:variable name="seq1" select="(10, 15, person[2], person[3])"/>
+
+        <xsl:iterate select="$seq1">
+           <info>
+              <xsl:copy-of select="."/>
+           </info>
+        </xsl:iterate>
       </document>
    </xsl:template>
    
diff --git a/tests/sequence_constructor/test1_e.xml b/tests/sequence_constructor/test1_e.xml
new file mode 100644
index 00000000..b983f4e1
--- /dev/null
+++ b/tests/sequence_constructor/test1_e.xml
@@ -0,0 +1,11 @@
+<document>
+  <person>
+    <name>Michael</name>
+  </person>
+  <person>
+    <name>Dave</name>
+  </person>
+  <person>
+    <name>Mary</name>
+  </person>
+</document>
\ No newline at end of file


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