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/06/24 11:31:43 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 value comparison operator lt, and various other xalanj xslt 3.0 implementation improvements. also committing few new related working test cases 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 76f6fb54 committing implementation of xpath 3.1 value comparison operator lt, and various other xalanj xslt 3.0 implementation improvements. also committing few new related working test cases as well.
     new 65a35b0d Merge pull request #10 from mukulga/xalan-j_xslt3.0_mukul
76f6fb54 is described below

commit 76f6fb54cbcf0614ee9c501111d501ed8309f614
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Jun 24 16:46:43 2023 +0530

    committing implementation of xpath 3.1 value comparison operator lt, and various other xalanj xslt 3.0 implementation improvements. also committing few new related working test cases as well.
---
 src/org/apache/xalan/templates/ElemValueOf.java    |  23 +-
 src/org/apache/xalan/templates/ElemVariable.java   |  20 +-
 .../xalan/templates/XSConstructorFunctionUtil.java |  15 +-
 src/org/apache/xpath/compiler/Compiler.java        |  16 +-
 src/org/apache/xpath/compiler/Keywords.java        |   3 +
 src/org/apache/xpath/compiler/OpCodes.java         |   9 +-
 src/org/apache/xpath/compiler/XPathParser.java     |  21 ++
 .../apache/xpath/functions/FuncCurrentDate.java    |   9 +-
 .../xpath/functions/FuncCurrentDateTime.java       |  11 +-
 src/org/apache/xpath/objects/XObject.java          |  81 +++++
 src/org/apache/xpath/operations/VcLt.java          |  54 ++++
 src/org/apache/xpath/xs/types/XSBoolean.java       |  20 ++
 src/org/apache/xpath/xs/types/XSCalendarType.java  |  23 +-
 src/org/apache/xpath/xs/types/XSDate.java          | 260 +++++++++++++--
 src/org/apache/xpath/xs/types/XSDateTime.java      | 351 +++++++++++----------
 src/org/apache/xpath/xs/types/XSDecimal.java       |   8 +
 src/org/apache/xpath/xs/types/XSDouble.java        |   8 +
 src/org/apache/xpath/xs/types/XSFloat.java         |   8 +
 src/org/apache/xpath/xs/types/XSInt.java           |   8 +
 src/org/apache/xpath/xs/types/XSInteger.java       |  26 +-
 src/org/apache/xpath/xs/types/XSLong.java          |   8 +
 src/org/apache/xpath/xs/types/XSTime.java          |  88 +++---
 .../apache/xalan/util/XslTransformTestsUtil.java   |  36 ++-
 .../apache/xalan/xpath3/ValueComparisonTests.java  |  35 +-
 tests/org/apache/xalan/xslt3/XSLConstants.java     |   4 +-
 tests/org/apache/xalan/xslt3/XslIterateTests.java  |  10 +
 tests/xpath_value_comparison/gold/test5.out        |  14 +
 tests/xpath_value_comparison/gold/test6.out        |  14 +
 tests/xpath_value_comparison/gold/test7.out        |  14 +
 tests/xpath_value_comparison/test1.xsl             |   5 +-
 tests/xpath_value_comparison/test1_b.xml           |  11 +
 tests/xpath_value_comparison/test2.xsl             |   5 +-
 tests/xpath_value_comparison/test3.xsl             |   5 +-
 tests/xpath_value_comparison/test4.xsl             |   5 +-
 .../{test3.xsl => test5.xsl}                       |  11 +-
 .../{test2.xsl => test6.xsl}                       |  13 +-
 tests/xpath_value_comparison/test7.xsl             |  63 ++++
 tests/xsl_iterate/gold/test13.out                  |   4 +
 tests/xsl_iterate/test13.xsl                       |  59 ++++
 39 files changed, 1056 insertions(+), 322 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index 4824efad..b54ff9da 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -293,16 +293,21 @@ public class ElemValueOf extends ElemTemplateElement {
                   if (expr instanceof FuncExtFunction) {                      
                       XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn
                                                                                               (xctxt, expr);
-                      String strValue = null;
-                      
-                      if (evalResult instanceof XSAnyType) {
-                          strValue = ((XSAnyType)evalResult).stringValue();    
+                      if (evalResult != null) {
+                          String strValue = null;
+                          
+                          if (evalResult instanceof XSAnyType) {
+                              strValue = ((XSAnyType)evalResult).stringValue();    
+                          }
+                          else {
+                              strValue = evalResult.str();  
+                          }
+    
+                          (new XString(strValue)).dispatchCharactersEvents(rth);
                       }
                       else {
-                          strValue = evalResult.str();  
+                          expr.executeCharsToContentHandler(xctxt, rth);   
                       }
-
-                      (new XString(strValue)).dispatchCharactersEvents(rth);
                   }
                   else if (expr instanceof Function) {
                       XObject evalResult = ((Function)expr).execute(xctxt);
@@ -364,8 +369,8 @@ public class ElemValueOf extends ElemTemplateElement {
     {
         throw new TransformerException(se);
     }
-    catch (RuntimeException re) {
-    	TransformerException te = new TransformerException(re);
+    catch (Exception ex) {
+    	TransformerException te = new TransformerException(ex);
     	te.setLocator(this);
     	throw te;
     }
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index b2e3bf13..ba3d236f 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -279,7 +279,7 @@ public class ElemVariable extends ElemTemplateElement
                                                                  throws TransformerException
   {
 
-    XObject var;
+    XObject var = null;
     
     final XPathContext xctxtOriginal = transformer.getXPathContext();
     
@@ -293,14 +293,18 @@ public class ElemVariable extends ElemTemplateElement
         if (selectExpression instanceof FuncExtFunction) {
             XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
                                                                                         selectExpression);
-            return evalResult;
+            if (evalResult != null) {
+                return evalResult;    
+            }
+            else {
+                var = m_selectPattern.execute(xctxt, sourceNode, this);    
+            }            
         }
         else if (selectExpression instanceof Function) {
             XObject evalResult = ((Function)selectExpression).execute(xctxt);            
             if ((evalResult instanceof ResultSequence) || 
-                                                (evalResult instanceof XSAnyType)) {
-                var = evalResult;
-                return var; 
+                                                (evalResult instanceof XSAnyType)) {                
+                return evalResult; 
             }
         }
         else if (selectExpression instanceof Operation) {
@@ -313,8 +317,10 @@ public class ElemVariable extends ElemTemplateElement
             
             return evalResult;
         }
-          
-        var = m_selectPattern.execute(xctxt, sourceNode, this);
+  
+        if (var == null) {
+           var = m_selectPattern.execute(xctxt, sourceNode, this);
+        }
 
         var.allowDetachToRelease(false);
 
diff --git a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
index 8f4911ee..f06455f8 100644
--- a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
+++ b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
@@ -27,6 +27,7 @@ import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.operations.Operation;
 import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDecimal;
 import org.apache.xpath.xs.types.XSDouble;
 import org.apache.xpath.xs.types.XSFloat;
@@ -37,7 +38,8 @@ import org.xml.sax.SAXException;
 
 /**
  * An utility class, to support evaluations of XPath 3.1 constructor 
- * functions, and few other XPath expression evaluations.
+ * functions (ref, https://www.w3.org/TR/xpath-functions-31/#constructor-functions), 
+ * and few other XPath expression evaluations.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
@@ -58,6 +60,7 @@ public class XSConstructorFunctionUtil {
             if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcExtFunction.getNamespace())) {
                 // evaluate XPath 3.1 constructor function calls, corresponding to XML Schema 
                 // built-in types.
+                
                 if ((Keywords.FUNC_XS_DECIMAL).equals(funcExtFunction.getFunctionName())) {                              
                     ResultSequence argSequence = new ResultSequence();
                     for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
@@ -129,6 +132,16 @@ public class XSConstructorFunctionUtil {
                     ResultSequence rSeq = (new XSBoolean()).constructor(argSequence);
                     evalResult = rSeq.item(0);              
                 }
+                else if ((Keywords.FUNC_XS_DATE).equals(funcExtFunction.getFunctionName())) {                              
+                    ResultSequence argSequence = new ResultSequence();
+                    for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
+                        XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
+                        argSequence.add(XSDate.parseDate(argVal.str()));
+                    }
+
+                    ResultSequence rSeq = (new XSDate()).constructor(argSequence); 
+                    evalResult = rSeq.item(0);              
+                }
             }
         }
         else if (expr instanceof Operation) {
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
index e16ce7cf..d3ce8db2 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -59,6 +59,7 @@ import org.apache.xpath.operations.Range;
 import org.apache.xpath.operations.UnaryOperation;
 import org.apache.xpath.operations.Variable;
 import org.apache.xpath.operations.VcEquals;
+import org.apache.xpath.operations.VcLt;
 import org.apache.xpath.operations.VcNotEquals;
 import org.apache.xpath.patterns.FunctionPattern;
 import org.apache.xpath.patterns.NodeTest;
@@ -137,6 +138,8 @@ public class Compiler extends OpMap
       expr = vcEquals(opPos); break;
     case OpCodes.OP_VC_NOT_EQUALS :
       expr = vcNotEquals(opPos); break;
+    case OpCodes.OP_VC_LT :
+      expr = vcLt(opPos); break;
     case OpCodes.OP_LTE :
       expr = lte(opPos); break;
     case OpCodes.OP_LT :
@@ -305,7 +308,7 @@ public class Compiler extends OpMap
   }
   
   /**
-   * Compile an 'eq' operation. 
+   * Compile an XPath 3.1 value comparison 'eq' operation. 
    */
   protected Expression vcEquals(int opPos) throws TransformerException
   {
@@ -313,7 +316,7 @@ public class Compiler extends OpMap
   }
   
   /**
-   * Compile an 'ne' operation. 
+   * Compile an XPath 3.1 value comparison 'ne' operation. 
    */
   protected Expression vcNotEquals(int opPos) throws TransformerException
   {
@@ -347,6 +350,15 @@ public class Compiler extends OpMap
   {
     return compileOperation(new Lt(), opPos);
   }
+  
+  /**
+   * Compile an XPath 3.1 value comparison 'lt' operation.
+   *  
+   */
+  protected Expression vcLt(int opPos) throws TransformerException
+  {
+    return compileOperation(new VcLt(), opPos);
+  }
 
   /**
    * Compile a '>=' operation.
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index a5f4f4a3..5bfd7851 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -284,6 +284,9 @@ public class Keywords
   
   /** xs:int data type string. */
   public static final String FUNC_XS_INT = "int";
+  
+  /** xs:date data type string. */
+  public static final String FUNC_XS_DATE = "date";
 
   static
   {
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
index 799dd7fc..80d07447 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -647,8 +647,15 @@ public class OpCodes
    * @xsl.usage advanced
    */
   public static final int OP_VC_NOT_EQUALS = 56;
+  
+  /**
+   * For XPath 3.1 value comparison operator "lt".
+   * 
+   * @xsl.usage advanced
+   */
+  public static final int OP_VC_LT = 57;
 
   /** The next free ID. Please keep this up to date. */
-  private static final int NEXT_FREE_ID = 57;
+  private static final int NEXT_FREE_ID = 58;
   
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 649a658e..b697beb4 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -851,6 +851,8 @@ public class XPathParser
    *
    * EqualityExpr  ::=  RelationalExpr
    * | EqualityExpr '=' RelationalExpr
+   * | EqualityExpr 'eq' RelationalExpr
+   * | EqualityExpr 'ne' RelationalExpr
    *
    *
    * @param addPos Position where expression is to be added, or -1 for append.
@@ -940,6 +942,10 @@ public class XPathParser
    * | RelationalExpr '<=' AdditiveExpr
    * | RelationalExpr '>=' AdditiveExpr
    * | RelationalExpr 'to' AdditiveExpr
+   * | RelationalExpr 'lt' AdditiveExpr
+   * | RelationalExpr 'le' AdditiveExpr
+   * | RelationalExpr 'gt' AdditiveExpr
+   * | RelationalExpr 'ge' AdditiveExpr
    *
    * @param addPos Position where expression is to be added, or -1 for append.
    *
@@ -1016,6 +1022,21 @@ public class XPathParser
             m_ops.getOp(addPos + op1 + 1) + op1);
           addPos += 2; 
       }
+      else if (tokenIs("lt"))
+      {
+          // support for XPath 3.1 value comparison operator "lt"
+          
+          nextToken();
+        
+          insertOp(addPos, 2, OpCodes.OP_VC_LT);
+
+          int op1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+          addPos = RelationalExpr(addPos);
+          m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+             m_ops.getOp(addPos + op1 + 1) + op1);
+          addPos += 2;
+      }
     }
 
     return addPos;
diff --git a/src/org/apache/xpath/functions/FuncCurrentDate.java b/src/org/apache/xpath/functions/FuncCurrentDate.java
index 4b953dec..52166951 100644
--- a/src/org/apache/xpath/functions/FuncCurrentDate.java
+++ b/src/org/apache/xpath/functions/FuncCurrentDate.java
@@ -22,8 +22,6 @@ package org.apache.xpath.functions;
 
 import java.util.Vector;
 
-import javax.xml.transform.SourceLocator;
-
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XObject;
@@ -53,12 +51,11 @@ public class FuncCurrentDate extends Function {
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
-
-    SourceLocator srcLocator = xctxt.getSAXLocator();
     
-    XSDate currentDate = new XSDate(xctxt.getCurrentDateTime(), xctxt.getTimezone());
+    XSDate xsDate = new XSDate(xctxt.getCurrentDateTime(), xctxt.getTimezone());
+    xsDate.setPopulatedFromFnCurrentDate(true);
 
-    return (XObject)currentDate;
+    return (XObject)xsDate;
   }
 
   /**
diff --git a/src/org/apache/xpath/functions/FuncCurrentDateTime.java b/src/org/apache/xpath/functions/FuncCurrentDateTime.java
index f15b59ab..ad26223e 100644
--- a/src/org/apache/xpath/functions/FuncCurrentDateTime.java
+++ b/src/org/apache/xpath/functions/FuncCurrentDateTime.java
@@ -22,8 +22,6 @@ package org.apache.xpath.functions;
 
 import java.util.Vector;
 
-import javax.xml.transform.SourceLocator;
-
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XObject;
@@ -54,7 +52,7 @@ public class FuncCurrentDateTime extends Function {
 
    private static final long serialVersionUID = -2032033071326423919L;
 
- /**
+   /**
    * Execute the function. The function must return a valid object.
    * 
    * @param xctxt The current execution context.
@@ -64,13 +62,10 @@ public class FuncCurrentDateTime extends Function {
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
-
-    SourceLocator srcLocator = xctxt.getSAXLocator();
     
-    XSDateTime currentDateTime = new XSDateTime(xctxt.getCurrentDateTime(), 
-                                                               xctxt.getTimezone());
+    XSDateTime xsDateTime = new XSDateTime(xctxt.getCurrentDateTime(), xctxt.getTimezone());
 
-    return (XObject)currentDateTime;
+    return (XObject)xsDateTime;
   }
 
   /**
diff --git a/src/org/apache/xpath/objects/XObject.java b/src/org/apache/xpath/objects/XObject.java
index f2374675..79c2415c 100644
--- a/src/org/apache/xpath/objects/XObject.java
+++ b/src/org/apache/xpath/objects/XObject.java
@@ -35,6 +35,7 @@ import org.apache.xpath.XPathException;
 import org.apache.xpath.XPathVisitor;
 import org.apache.xpath.res.XPATHErrorResources;
 import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDecimal;
 import org.apache.xpath.xs.types.XSDouble;
 import org.apache.xpath.xs.types.XSFloat;
@@ -557,6 +558,80 @@ public class XObject extends Expression implements Serializable, Cloneable
 
     return this.num() < obj2.num();
   }
+  
+  /**
+   * Tell if one object is less than an another one, using the rules 
+   * of value comparison operator "lt".
+   *
+   * @param obj2                Object to compare this to
+   * @param expressionOwner     this object is used, for error reporting 
+   *
+   * @return True if this object is less than the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   * 
+   * Notes : Currently, we don't implement following XPath 3.1 spec definitions for
+   *         value comparison operator "lt",
+   *         1) XPath 3.1 spec, requires atomizing the operands of XPath operator "lt",
+   *            before applying operator "lt" to the operands.
+   *         2) If any of the operands of operator "lt", after atomization is an empty
+   *            sequence, the result of operation "lt" should be an empty sequence.              
+   */
+  public boolean vcLessThan(XObject obj2, ExpressionNode expressionOwner) throws 
+                                                                    javax.xml.transform.TransformerException {
+       
+       if ((this instanceof XSDecimal) && (obj2 instanceof XSDecimal)) {
+          return ((XSDecimal)this).lt((XSDecimal)obj2);        
+       }
+       else if ((this instanceof XSFloat) && (obj2 instanceof XSFloat)) {
+          return ((XSFloat)this).lt((XSFloat)obj2);        
+       }
+       else if ((this instanceof XSDouble) && (obj2 instanceof XSDouble)) {
+          return ((XSDouble)this).lt((XSDouble)obj2);        
+       }
+       else if ((this instanceof XSBoolean) && (obj2 instanceof XSBoolean)) {
+          return ((XSBoolean)this).lt((XSBoolean)obj2);    
+       }
+       else if ((this instanceof XSInteger) && (obj2 instanceof XSInteger)) {
+          return ((XSInteger)this).lt((XSInteger)obj2);    
+       }
+       else if ((this instanceof XSLong) && (obj2 instanceof XSLong)) {
+          return ((XSLong)this).lt((XSLong)obj2);    
+       }
+       else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
+          return ((XSInt)this).lt((XSInt)obj2);    
+       }
+       else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+           return ((XSDate)this).lt((XSDate)obj2);    
+       }
+       
+       boolean isOperandNodeSet1 = false;
+       boolean isOperandNodeSet2 = false;
+       
+       if (this.getType() == XObject.CLASS_NODESET) {       
+          isOperandNodeSet1 = true;
+          if ((((XNodeSet)this).getLength() > 1)) {
+              error(XPATHErrorResources.ER_EQ_OPERAND_CARDINALITY_ERROR, null, expressionOwner);    
+          }
+       }
+       
+       if (obj2.getType() == XObject.CLASS_NODESET) {
+          isOperandNodeSet2 = true; 
+          if ((((XNodeSet)obj2).getLength() > 1)) {
+              error(XPATHErrorResources.ER_EQ_OPERAND_CARDINALITY_ERROR, null, expressionOwner);    
+          }
+       }
+       
+       if (isOperandNodeSet1 || this instanceof XNumber) {
+           return this.num() < obj2.num();    
+       }    
+       else if (isOperandNodeSet2 || obj2 instanceof XNumber) {
+           return obj2.num() < this.num();    
+       }
+       
+       // revisit
+       return true;
+  }
 
   /**
    * Tell if one object is less than or equal to the other.
@@ -662,6 +737,9 @@ public class XObject extends Expression implements Serializable, Cloneable
     else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
        return ((XSInt)this).equals((XSInt)obj2);    
     }
+    else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+       return ((XSDate)this).equals((XSDate)obj2);    
+    }
         
     if (obj2.getType() == XObject.CLASS_NODESET) {
        return obj2.equals(this);
@@ -718,6 +796,9 @@ public class XObject extends Expression implements Serializable, Cloneable
     else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
        return ((XSInt)this).equals((XSInt)obj2);    
     }
+    else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+        return ((XSDate)this).equals((XSDate)obj2);    
+    }
     
     boolean isOperandNodeSet1 = false;
     boolean isOperandNodeSet2 = false;
diff --git a/src/org/apache/xpath/operations/VcLt.java b/src/org/apache/xpath/operations/VcLt.java
new file mode 100644
index 00000000..0928099b
--- /dev/null
+++ b/src/org/apache/xpath/operations/VcLt.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The XPath 3.1 value comparison "lt" operation.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class VcLt extends Operation
+{
+
+   private static final long serialVersionUID = 3832212036565766741L;
+
+   /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right) 
+                                                 throws javax.xml.transform.TransformerException
+  {
+      return left.vcLessThan(right, getExpressionOwner()) ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/src/org/apache/xpath/xs/types/XSBoolean.java b/src/org/apache/xpath/xs/types/XSBoolean.java
index 94589a87..84fa2670 100644
--- a/src/org/apache/xpath/xs/types/XSBoolean.java
+++ b/src/org/apache/xpath/xs/types/XSBoolean.java
@@ -103,6 +103,26 @@ public class XSBoolean extends XSCtrType {
         return _value == xsBoolean.value();  
     }
     
+    public boolean lt(XSBoolean xsBoolean) {
+        boolean resultVal = false;
+
+        if (!value() && xsBoolean.value()) {
+            resultVal = true;
+        }
+        
+        return resultVal;  
+    }
+    
+    public boolean gt(XSBoolean xsBoolean) {
+        boolean resultVal = false;
+
+        if (value() && !xsBoolean.value()) {
+            resultVal = true;
+        }
+        
+        return resultVal;  
+    }
+    
     /*
      * Check whether, a string value represents a boolean 
      * 'false' value.
diff --git a/src/org/apache/xpath/xs/types/XSCalendarType.java b/src/org/apache/xpath/xs/types/XSCalendarType.java
index f3b954d7..8a2ecc09 100644
--- a/src/org/apache/xpath/xs/types/XSCalendarType.java
+++ b/src/org/apache/xpath/xs/types/XSCalendarType.java
@@ -15,13 +15,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id$
- */
 package org.apache.xpath.xs.types;
 
-import java.util.Calendar;
-
 /**
  * Base class for all calendar based classes.
  * 
@@ -31,22 +26,6 @@ import java.util.Calendar;
  */
 public abstract class XSCalendarType extends XSCtrType {
 
-	public Calendar normalizeCalendar(Calendar cal, XSDuration timezone) {
-		Calendar adjusted = (Calendar)cal.clone();
-		
-		if (timezone != null) {
-			int hours = timezone.hours();
-			int minutes = timezone.minutes();
-			if (!timezone.negative()) {
-				hours *= -1;
-				minutes *= -1;
-			}
-			adjusted.add(Calendar.HOUR_OF_DAY, hours);
-			adjusted.add(Calendar.MINUTE, minutes);
-		}
-		
-		return adjusted;
-		
-	}
+    private static final long serialVersionUID = -6546129697566314664L;
 	
 }
diff --git a/src/org/apache/xpath/xs/types/XSDate.java b/src/org/apache/xpath/xs/types/XSDate.java
index a192954a..ec3a5ea2 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -18,7 +18,6 @@ package org.apache.xpath.xs.types;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
-import java.util.TimeZone;
 
 import org.apache.xpath.objects.ResultSequence;
 
@@ -36,21 +35,27 @@ public class XSDate extends XSCalendarType {
     private static final String XS_DATE = "xs:date";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
+    // stores the fact that, whether this XSDate object is constructed
+    // via XPath function call fn:current-date().
+    private boolean isPopulatedFromFnCurrentDate = false;
+    
     /**
      * Class constructor.
      * 
-     * Creates a new 'XSDate' instance, corresponding to the supplied 
-     * date and time.
+     * Creates a new XSDate object instance, corresponding to the provided 
+     * date and timezone.
      * 
      * @param cal     the java.util.Calendar representation of the date to be stored
      * 
-     * @param tz      the time zone of the date to be stored
+     * @param tz      the timezone of the date to be stored
      */
     public XSDate(Calendar cal, XSDuration tz) {
-        _calendar = cal;
+        _calendar = cal;        
         _tz = tz;
         
         if (tz == null) {
@@ -64,14 +69,74 @@ public class XSDate extends XSCalendarType {
     /*
      * Class constructor. 
      */
-    public XSDate() {
-        this(new GregorianCalendar(TimeZone.getTimeZone("GMT")), null);
-    }
+    public XSDate() {}
 
     @Override
     public ResultSequence constructor(ResultSequence arg) {
-        // TO DO
-        return null;
+        ResultSequence resultSeq = new ResultSequence();
+        
+        if (arg.size() == 0) {
+           return resultSeq;     
+        }
+        
+        XSAnyType xsAnyType = (XSAnyType)arg.item(0);
+        
+        XSDate xsDate = castToDate(xsAnyType);
+        
+        resultSeq.add(xsDate);
+
+        return resultSeq;        
+    }
+    
+    /**
+     * Parse a string representation of a date and construct an new XSDate object.
+     * 
+     * XML Schema 1.1 datatypes spec, provides following to be the valid string
+     * representation (which is an ISO 8601 date format) of xs:date typed value,
+     * 
+     * dateLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag timezoneFrag? 
+     * 
+     * @param strVal     the string representation of the date
+     * @return           the XSDate representation of the provided string
+     */
+    public static XSDate parseDate(String strVal) {
+        String dateStr = "";
+        String timeStr = "T00:00:00.0";
+
+        int idx = strVal.indexOf('+', 1);
+        if (idx == -1) {
+            idx = strVal.indexOf('-', 1);
+            if (idx == -1) {
+                return null;
+            }
+            idx = strVal.indexOf('-', idx + 1);
+            if (idx == -1) {
+                return null;
+            }
+            idx = strVal.indexOf('-', idx + 1);
+        }
+        if (idx == -1) {
+            idx = strVal.indexOf('Z', 1);
+        }
+        if (idx != -1) {
+            dateStr = strVal.substring(0, idx);
+            dateStr += timeStr;
+            dateStr += strVal.substring(idx, strVal.length());
+        } else {
+            dateStr = strVal + timeStr;
+        }
+
+        XSDateTime dateTime = XSDateTime.parseDateTime(dateStr);        
+        if (dateTime == null) {
+           return null;
+        }
+
+        return new XSDate(dateTime.getCalendar(), dateTime.getTimezone());
+        
+    }
+    
+    public XSDuration getTimezone() {
+        return _tz;
     }
 
     @Override
@@ -87,9 +152,9 @@ public class XSDate extends XSCalendarType {
     /**
      * Get the Calendar representation of the date stored.
      * 
-     * @return    Calendar representation of the date stored
+     * @return    the java.util.Calendar representation of the date stored
      */
-    public Calendar calendar() {
+    public Calendar getCalendar() {
         return _calendar;
     }
     
@@ -103,55 +168,180 @@ public class XSDate extends XSCalendarType {
     }
     
     /**
-     * Check whether this date has an optional, timezone associated with it.
+     * Check whether this XSDate object has an, timezone associated with it.
      * 
-     * @return true    if there is a timezone associated with this date. false
-     *                 otherwise.
+     * @return true    if there is a timezone associated with this XSDate object.
+     *                 false otherwise.
      */
-    public boolean timezoned() {
+    public boolean isXsDateObjectTimezoned() {
         return _timezoned;
     }
 
     @Override
     public String stringValue() {
-        String ret = "";
+        String xsDateStrValue = "";
 
-        Calendar adjustFortimezone = calendar();
+        Calendar calendarObj = getCalendar();
 
-        if (adjustFortimezone.get(Calendar.ERA) == GregorianCalendar.BC) {
-            ret += "-";
+        if (calendarObj.get(Calendar.ERA) == GregorianCalendar.BC) {
+            xsDateStrValue += "-";
         }
 
-        ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.YEAR), 4);
+        xsDateStrValue += XSDateTime.padInt(calendarObj.get(Calendar.YEAR), 4);
 
-        ret += "-";
-        ret += XSDateTime.pad_int(month(), 2);
+        xsDateStrValue += "-";
+        xsDateStrValue += XSDateTime.padInt(month(), 2);
 
-        ret += "-";
-        ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.DAY_OF_MONTH), 2);
+        xsDateStrValue += "-";
+        xsDateStrValue += XSDateTime.padInt(calendarObj.get(Calendar.
+                                                                  DAY_OF_MONTH), 2);
 
-        if (timezoned()) {
+        if (isXsDateObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
             if (hrs == 0 && min == 0 && secs == 0) {
-                ret += "Z";
+                xsDateStrValue += "Z";
             } else {
-                String tZoneStr = "";
+                String timezoneStr = "";
                 if (_tz.negative()) {
-                    tZoneStr += "-";
+                    timezoneStr += "-";
                 } else {
-                    tZoneStr += "+";
+                    timezoneStr += "+";
                 }
-                tZoneStr += XSDateTime.pad_int(hrs, 2);
-                tZoneStr += ":";
-                tZoneStr += XSDateTime.pad_int(min, 2);
+                timezoneStr += XSDateTime.padInt(hrs, 2);
+                timezoneStr += ":";
+                timezoneStr += XSDateTime.padInt(min, 2);
 
-                ret += tZoneStr;
+                xsDateStrValue += timezoneStr;
             }
         }
 
-        return ret;
+        return xsDateStrValue;
+    }
+    
+    /*
+     * Determine whether, two XSDate objects are equal.
+     */
+    public boolean equals(XSDate xsDate) {
+        boolean isDateEqual = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        XSDuration tz1 = getTimezone();
+        XSDuration tz2 = xsDate.getTimezone();
+        
+        isDateEqual = (((year1 + month1 + date1) == (year2 + month2 + date2)) && 
+                                     isTimezoneEqual(tz1, tz2, isPopulatedFromFnCurrentDate, 
+                                                                   xsDate.isPopulatedFromFnCurrentDate())); 
+        
+        return isDateEqual; 
+    }
+    
+    /*
+     * Determine whether, this XSDate object is less that, the 
+     * XSDate object passed as an argument to this method. 
+     */
+    public boolean lt(XSDate xsDate) {
+        boolean isDateBefore = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        isDateBefore = ((year1 + month1 + date1) < (year2 + month2 + date2)); 
+        
+        return isDateBefore;
+    }
+    
+    /*
+     * Determine whether, this XSDate object is greater that, the 
+     * XSDate object passed as an argument to this method. 
+     */
+    public boolean gt(XSDate xsDate) {
+        boolean isDateAfter = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        isDateAfter = ((year1 + month1 + date1) > (year2 + month2 + date2)); 
+        
+        return isDateAfter; 
+    }
+
+    public boolean isPopulatedFromFnCurrentDate() {
+        return isPopulatedFromFnCurrentDate;
+    }
+
+    public void setPopulatedFromFnCurrentDate(boolean isPopulatedFromFnCurrentDate) {
+        this.isPopulatedFromFnCurrentDate = isPopulatedFromFnCurrentDate;
+    }
+    
+    /*
+     * Do a data type cast, of an XSAnyType argument passed to this method, to
+     * an XSDate object.
+     */
+    private XSDate castToDate(XSAnyType xsAnyType) {
+        if (xsAnyType instanceof XSDate) {
+            XSDate date = (XSDate) xsAnyType;
+            return new XSDate(date.getCalendar(), date.getTimezone());
+        }
+
+        if (xsAnyType instanceof XSDateTime) {
+            XSDateTime dateTime = (XSDateTime) xsAnyType;
+            return new XSDate(dateTime.getCalendar(), dateTime.getTimezone());
+        }
+
+        return parseDate(xsAnyType.stringValue());
+    }
+    
+    /*
+     * Determine whether, two timezone values (represented as XSDuration objects) 
+     * are equal. 
+     */
+    private boolean isTimezoneEqual(XSDuration tz1, XSDuration tz2, 
+                                          boolean isPopulatedFromFnCurrentDate1, 
+                                                          boolean isPopulatedFromFnCurrentDate2) {
+         
+        boolean isTimezoneEqual = false;         
+        
+        if (tz1 == null && tz2 == null) {
+           isTimezoneEqual = true;
+        }
+        else if (tz1 != null && tz2 != null) {
+           isTimezoneEqual = ((tz1.hours() == tz2.hours()) && 
+                                                   (tz1.minutes() == tz2.minutes()) && 
+                                                           (tz1.negative() == tz2.negative()));
+        }
+        else if (isPopulatedFromFnCurrentDate1 || isPopulatedFromFnCurrentDate2) {
+            isTimezoneEqual = true; 
+        }
+        
+        return isTimezoneEqual;
     }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSDateTime.java b/src/org/apache/xpath/xs/types/XSDateTime.java
index 2a3204b8..e601ccf2 100644
--- a/src/org/apache/xpath/xs/types/XSDateTime.java
+++ b/src/org/apache/xpath/xs/types/XSDateTime.java
@@ -40,14 +40,16 @@ public class XSDateTime extends XSCalendarType {
     private static final String XS_DATE_TIME = "xs:dateTime";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
     /**
      * Class constructor.
      * 
-     * Creates a new 'XSDateTime' instance, corresponding to the supplied 
-     * date and time.
+     * Creates a new XSDateTime object instance, corresponding to the provided 
+     * date, time and timezone.
      * 
      * @param cal     the java.util.Calendar representation of the date and 
      *                time to be stored
@@ -92,6 +94,14 @@ public class XSDateTime extends XSCalendarType {
         // TO DO
         return null;
     }
+    
+    public Calendar getCalendar() {
+        return _calendar;
+    }
+    
+    public XSDuration getTimezone() {
+        return _tz;
+    }
 
     @Override
     public String typeName() {
@@ -99,13 +109,13 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Check to see if a character is numeric.
+     * Method to check, whether the provided character is numeric.
      * 
-     * @param x    character to be tested
+     * @param x    the character for which, this check is done
      * 
      * @return     true if the character is numeric. false otherwise.
      */
-    public static boolean is_digit(char x) {
+    public static boolean isDigit(char x) {
         if ('0' <= x && x <= '9') {
            return true;
         }
@@ -117,27 +127,29 @@ public class XSDateTime extends XSCalendarType {
      * Parse a string representation of a date and time, and retrieve the year,
      * month and day components from this string.
      * 
-     * @param  str    the String representation of the date (with optional timezone)
+     * @param  strVal    the string representation of the date (with an optional  
+     *                   timezone value)
      * 
-     * @return        an integer array of size 3. first element is the year, second 
-     *                element is the month, and third element is the day.
+     * @return           an integer array of size 3. first element of this array is the year, 
+     *                   second element is the month, and third element is the day.
      */
-    public static int[] parse_date(String str) {
+    public static int[] parseDate(String strVal) {
+        
+        int[] returnVal = new int[3];
+        
         int state = 0;
 
-        int[] ret = new int[3];
-
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = 0;
+        for (int i = 0; i < returnVal.length; i++) {
+            returnVal[i] = 0;
         }
 
         String token = "";
-        for (int i = 0; i < str.length(); i++) {
-            char x = str.charAt(i);
+        for (int i = 0; i < strVal.length(); i++) {
+            char x = strVal.charAt(i);
 
             switch (state) {
             case 0:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 } else if (x == '-') {
                     token += x;
@@ -167,11 +179,11 @@ public class XSDateTime extends XSCalendarType {
                         return null;
                     }
 
-                    ret[0] = Integer.parseInt(token);
+                    returnVal[0] = Integer.parseInt(token);
                     token = "";
                     state = 2;
                 } 
-                else if (is_digit(x)) {
+                else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -184,10 +196,10 @@ public class XSDateTime extends XSCalendarType {
                         return null;
                     }
 
-                    ret[1] = Integer.parseInt(token);
+                    returnVal[1] = Integer.parseInt(token);
                     token = "";
                     state = 3;
-                } else if (is_digit(x)) {
+                } else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -195,7 +207,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 3:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -203,7 +215,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             default:
-                return ret;
+                return returnVal;
             }
         }
         
@@ -215,29 +227,31 @@ public class XSDateTime extends XSCalendarType {
             return null;
         }
 
-        ret[2] = Integer.parseInt(token);
+        returnVal[2] = Integer.parseInt(token);
 
-        return ret;
+        return returnVal;
     }
     
     /**
      * Parse a string representation of a date and time, and retrieve the hour,
-     * minute and seconds components from this string.
+     * minute and second components from this string.
      * 
-     * @param   str    the String representation of the date (with optional timezone)
+     * @param   strVal    the string representation of the date (with an optional 
+     *                    timezone value)
      * 
-     * @return         an integer array of size 3. first element is the hour, second 
-     *                 element is the minute, and third element is the seconds.
+     * @return            an integer array of size 3. first element is the hour, second 
+     *                    element is the minute, and third element is the seconds.
      */
-    public static double[] parse_time(String str) {
-        int state = 0; 
-
-        double[] ret = new double[3];
+    public static double[] parseTime(String strVal) {
+        
+        double[] returnVal = new double[3];
+        
+        int state = 0;
 
         String token = "";
 
-        for (int i = 0; i < str.length(); i++) {
-            char x = str.charAt(i);
+        for (int i = 0; i < strVal.length(); i++) {
+            char x = strVal.charAt(i);
 
             switch (state) {
             case 0:
@@ -246,10 +260,10 @@ public class XSDateTime extends XSCalendarType {
                     if (token.length() != 2) {
                         return null;
                     }
-                    ret[state] = Integer.parseInt(token);
+                    returnVal[state] = Integer.parseInt(token);
                     state++;
                     token = "";
-                } else if (is_digit(x)) {
+                } else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -257,7 +271,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 2:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                     if (token.length() > 2) {
                         return null;
@@ -270,7 +284,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 3:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -290,172 +304,179 @@ public class XSDateTime extends XSCalendarType {
             return null;
         }
 
-        ret[2] = Double.parseDouble(token);
+        returnVal[2] = Double.parseDouble(token);
 
-        if (ret[0] == 24.0) {
-            ret[0] = 00.0;
+        if (returnVal[0] == 24.0) {
+            returnVal[0] = 00.0;
         }
 
-        return ret;
+        return returnVal;
     }
     
     /**
-     * Parse a String representation of a date and time, and retrieve the
+     * Parse a string representation of a date and time, and retrieve the
      * timezone component from this string.
      * 
-     * @param  str   the String representation of the date (with optional timezone)
+     * @param  strVal   the string representation of the date (with an optional 
+     *                  timezone value)
      * 
-     * @return       an integer array of size 3. first element represents whether the
-     *               timezone is ahead or behind GMT, second element is the hour
-     *               displacement, and third element is the minute displacement.
+     * @return          an integer array of size 3. first element represents whether the
+     *                  timezone is ahead or behind GMT, second element is the hour
+     *                  displacement, and third element is the minute displacement.
      */
-    public static int[] parse_timezone(String str) {
-        int[] ret = new int[3];
+    public static int[] parseTimezone(String strVal) {
+        
+        int[] returnVal = new int[3];
 
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = 0;
+        for (int i = 0; i < returnVal.length; i++) {
+            returnVal[i] = 0;
         }
         
-        ret[0] = 1;
+        returnVal[0] = 1;
 
-        if (str.equals("Z")) {
-            return ret;
+        if (strVal.equals("Z")) {
+            return returnVal;
         }
 
-        if (str.startsWith("+")) {
-            ret[0] = 1;
+        if (strVal.startsWith("+")) {
+            returnVal[0] = 1;
         }
-        else if (str.startsWith("-")) {
-            ret[0] = -1;
+        else if (strVal.startsWith("-")) {
+            returnVal[0] = -1;
         }
         else {
             return null;
         }
 
-        str = str.substring(1, str.length());
+        strVal = strVal.substring(1, strVal.length());
 
-        if (str.length() != (2 + 1 + 2)) {
+        if (strVal.length() != (2 + 1 + 2)) {
             return null;
         }
 
         try {
-            ret[1] = Integer.parseInt(str.substring(0, 2));
-            ret[2] = Integer.parseInt(str.substring(3, 5));
+            returnVal[1] = Integer.parseInt(strVal.substring(0, 2));
+            returnVal[2] = Integer.parseInt(strVal.substring(3, 5));
 
-            if (ret[1] > 14) {
+            if (returnVal[1] > 14) {
                 return null;
             }
             
-            if (ret[2] > 59) {
+            if (returnVal[2] > 59) {
                 return null;
             }
 
-            return ret;
+            return returnVal;
         } catch (NumberFormatException ex) {
             return null;
         }
     }
     
     /**
-     * Parse a String representation of a date and time, and construct a new
+     * Parse a string representation of a date and time, and construct a new
      * XSDateTime object using that information.
      * 
-     * @param str    the String representation of the date (with optional timezone)
+     * @param strVal    the string representation of the date (with an optional 
+     *                  timezone value)
      * 
-     * @return       the XSDateTime representation of the date and time (with optional
-     *               timezone)
+     * @return          the XSDateTime representation of the date and time (with an 
+     *                  optional timezone value)
      */
-    public static XSDateTime parseDateTime(String str) {
+    public static XSDateTime parseDateTime(String strVal) {
+        
+        XSDateTime xsDateTime = null;
 
-        int index = str.indexOf('T');
-        if (index == -1) {
+        int idx = strVal.indexOf('T');
+        if (idx == -1) {
             return null;
         }
 
-        String date = str.substring(0, index);
-        String time = str.substring(index + 1, str.length());
+        String date = strVal.substring(0, idx);
+        String time = strVal.substring(idx + 1, strVal.length());
         String timezone = null;
 
-        index = time.indexOf('+');
-        if (index == -1) {
-            index = time.indexOf('-');
+        idx = time.indexOf('+');
+        if (idx == -1) {
+            idx = time.indexOf('-');
         }
-        if (index == -1) {
-            index = time.indexOf('Z');
+        if (idx == -1) {
+            idx = time.indexOf('Z');
         }
-        if (index != -1) {
-            timezone = time.substring(index, time.length());
-            time = time.substring(0, index);
+        if (idx != -1) {
+            timezone = time.substring(idx, time.length());
+            time = time.substring(0, idx);
         }
 
-        int d[] = parse_date(date);
+        int d[] = parseDate(date);
         if (d == null) {
             return null;
         }
 
-        TimeZone UTC = TimeZone.getTimeZone("UTC");
-        GregorianCalendar cal = new GregorianCalendar(UTC);
+        TimeZone defaultTimezone = TimeZone.getDefault();
+        GregorianCalendar gregorianCalendarObj = new GregorianCalendar(
+                                                                 defaultTimezone);
 
         int year = d[0];
         if (year < 0) {
             year *= -1;
-            cal.set(Calendar.ERA, GregorianCalendar.BC);
+            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.BC);
         } else {
-            cal.set(Calendar.ERA, GregorianCalendar.AD);
+            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.AD);
         }
 
-        cal.set(Calendar.DAY_OF_MONTH, 2);
-        cal.set(Calendar.MONTH, 2);
+        gregorianCalendarObj.set(Calendar.DAY_OF_MONTH, 2);
+        gregorianCalendarObj.set(Calendar.MONTH, 2);
 
-        if (!set_item(cal, Calendar.YEAR, year)) {
+        if (!setItem(gregorianCalendarObj, Calendar.YEAR, year)) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.MONTH, d[1] - 1)) {
+        if (!setItem(gregorianCalendarObj, Calendar.MONTH, d[1] - 1)) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.DAY_OF_MONTH, d[2])) {
+        if (!setItem(gregorianCalendarObj, Calendar.DAY_OF_MONTH, d[2])) {
             return null;
         }
 
-        double t[] = parse_time(time);
+        double t[] = parseTime(time);
         if (t == null) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.HOUR_OF_DAY, (int) t[0])) {
+        if (!setItem(gregorianCalendarObj, Calendar.HOUR_OF_DAY, (int) t[0])) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.MINUTE, (int) t[1])) {
+        if (!setItem(gregorianCalendarObj, Calendar.MINUTE, (int) t[1])) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.SECOND, (int) t[2])) {
+        if (!setItem(gregorianCalendarObj, Calendar.SECOND, (int) t[2])) {
             return null;
         }
 
         double ms = t[2] - ((int) t[2]);
         ms *= 1000;
-        if (!set_item(cal, Calendar.MILLISECOND, (int) ms)) {
+        if (!setItem(gregorianCalendarObj, Calendar.MILLISECOND, (int) ms)) {
             return null;
         }
 
         int tz[] = null;
-        XSDuration tzd = null;
+        XSDuration timezoneVal = null;
         if (timezone != null) {
-            tz = parse_timezone(timezone);
+            tz = parseTimezone(timezone);
 
             if (tz == null) {
                 return null;
             }
 
-            tzd = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
-
+            timezoneVal = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
         }
+        
+        xsDateTime = new XSDateTime(gregorianCalendarObj, timezoneVal); 
 
-        return new XSDateTime(cal, tzd);
+        return xsDateTime;
     }
 
     @Override
@@ -463,47 +484,53 @@ public class XSDateTime extends XSCalendarType {
         return XS_DATE_TIME;
     }
     
-    public Calendar calendar() {
-        return _calendar;
-    }
-    
-    public static String pad_int(int num, int len) {
-        String ret = "";
-        String snum = "" + num;
+    public static String padInt(int num, int len) {        
+        String returnVal = "";
+        
+        String numStr = "" + num;
 
-        int pad = len - snum.length();
+        int pad = len - numStr.length();
 
-        // sort out the negative
         if (num < 0) {
-            ret += "-";
-            snum = snum.substring(1, snum.length());
+            returnVal += "-";
+            numStr = numStr.substring(1, numStr.length());
             pad++;
         }
 
-        StringBuffer buf = new StringBuffer(ret);
+        StringBuffer strBuf = new StringBuffer(returnVal);
+        
         for (int i = 0; i < pad; i++) {
-            buf.append("0");
+            strBuf.append("0");
         }
-        buf.append(snum);
-        ret = buf.toString();
-        return ret;
+        
+        strBuf.append(numStr);
+        
+        returnVal = strBuf.toString();
+        
+        return returnVal;
     }
     
     public double second() {
-        double s = _calendar.get(Calendar.SECOND);
-        double ms = _calendar.get(Calendar.MILLISECOND);
+        double secondVal = _calendar.get(Calendar.SECOND);
+        double millisecVal = _calendar.get(Calendar.MILLISECOND);
 
-        ms /= 1000;
-        s += ms;
+        millisecVal /= 1000;
+        secondVal += millisecVal;
         
-        return s;
+        return secondVal;
     }
     
     public int month() {
         return _calendar.get(Calendar.MONTH) + 1;
     }
     
-    public boolean timezoned() {
+    /**
+     * Check whether this XSDateTime object has an, timezone associated with it.
+     * 
+     * @return true    if there is a timezone associated with this XSDateTime object.
+     *                 false otherwise.
+     */
+    public boolean isXsDateTimeObjectTimezoned() {
         return _timezoned;
     }
 
@@ -511,59 +538,61 @@ public class XSDateTime extends XSCalendarType {
     public String stringValue() {
         String returnVal = "";
 
-        Calendar adjustFortimezone = calendar();
+        Calendar calendarVal = getCalendar();
 
-        if (adjustFortimezone.get(Calendar.ERA) == GregorianCalendar.BC) {
+        if (calendarVal.get(Calendar.ERA) == GregorianCalendar.BC) {
             returnVal += "-";
         }
 
-        returnVal += pad_int(adjustFortimezone.get(Calendar.YEAR), 4);
+        returnVal += padInt(calendarVal.get(Calendar.YEAR), 4);
 
         returnVal += "-";
-        returnVal += pad_int(month(), 2);
+        returnVal += padInt(month(), 2);
 
         returnVal += "-";
-        returnVal += pad_int(adjustFortimezone.get(Calendar.DAY_OF_MONTH), 2);
+        returnVal += padInt(calendarVal.get(Calendar.DAY_OF_MONTH), 2);
 
-        // time
         returnVal += "T";
 
-        returnVal += pad_int(adjustFortimezone.get(Calendar.HOUR_OF_DAY), 2);
+        returnVal += padInt(calendarVal.get(Calendar.HOUR_OF_DAY), 2);
 
         returnVal += ":";
-        returnVal += pad_int(adjustFortimezone.get(Calendar.MINUTE), 2);
+        returnVal += padInt(calendarVal.get(Calendar.MINUTE), 2);
 
         returnVal += ":";
-        int isecond = (int) second();
-        double sec = second();
+        int intSec = (int)second();
+        double doubleSec = second();
 
-        if ((sec - (isecond)) == 0.0)
-            returnVal += pad_int(isecond, 2);
+        if ((doubleSec - intSec) == 0.0) {
+           returnVal += padInt(intSec, 2);
+        }
         else {
-            if (sec < 10.0)
-                returnVal += "0" + sec;
-            else
-                returnVal += sec;
+            if (doubleSec < 10.0) {
+               returnVal += "0" + doubleSec;
+            }
+            else {
+               returnVal += doubleSec;
+            }
         }
 
-        if (timezoned()) {
+        if (isXsDateTimeObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
-            if (hrs == 0 && min == 0 && secs == 0) {
+            if ((hrs == 0) && (min == 0) && (secs == 0)) {
                 returnVal += "Z";
             } else {
-                String tZoneStr = "";
+                String timezoneStr = "";
                 if (_tz.negative()) {
-                    tZoneStr += "-";
+                    timezoneStr += "-";
                 } else {
-                    tZoneStr += "+";
+                    timezoneStr += "+";
                 }
-                tZoneStr += pad_int(hrs, 2);
-                tZoneStr += ":";
-                tZoneStr += pad_int(min, 2);
+                timezoneStr += padInt(hrs, 2);
+                timezoneStr += ":";
+                timezoneStr += padInt(min, 2);
 
-                returnVal += tZoneStr;
+                returnVal += timezoneStr;
             }
         }
 
@@ -571,26 +600,26 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Set a particular field within the Calendar.
+     * Set a particular field within an java.util.Calendar object.
      * 
-     * @param cal     the Calendar object to set the field in
-     * @param item    the field to set
-     * @param val     the value to set the field to
+     * @param cal           the Calendar object to set the field in
+     * @param fieldId       the field to set
+     * @param fieldval      the value to set the field to
      * 
-     * @return        true if successfully set. false otherwise
+     * @return              true if successfully set. false otherwise
      */
-    private static boolean set_item(Calendar cal, int item, int val) {
-        int min = cal.getActualMinimum(item);
+    private static boolean setItem(Calendar cal, int fieldId, int fieldval) {
 
-        if (val < min)
+        if (fieldval < cal.getActualMinimum(fieldId)) {
             return false;
+        }
 
-        int max = cal.getActualMaximum(item);
-
-        if (val > max)
+        if (fieldval > cal.getActualMaximum(fieldId)) {
             return false;
+        }
 
-        cal.set(item, val);
+        cal.set(fieldId, fieldval);
+        
         return true;
     }
 
diff --git a/src/org/apache/xpath/xs/types/XSDecimal.java b/src/org/apache/xpath/xs/types/XSDecimal.java
index b020bb09..980a9519 100644
--- a/src/org/apache/xpath/xs/types/XSDecimal.java
+++ b/src/org/apache/xpath/xs/types/XSDecimal.java
@@ -137,6 +137,14 @@ public class XSDecimal extends XSNumericType {
         return _value.equals(xsDecimal.getValue()); 
     }
     
+    public boolean lt(XSDecimal xsDecimal) {
+        return (_value.compareTo(xsDecimal.getValue()) == -1);
+    }
+    
+    public boolean gt(XSDecimal xsDecimal) {
+        return (_value.compareTo(xsDecimal.getValue()) == 1);
+    }
+    
     /*
      * Cast an object of type XSAnyType, to an object of type 
      * XSDecimal.  
diff --git a/src/org/apache/xpath/xs/types/XSDouble.java b/src/org/apache/xpath/xs/types/XSDouble.java
index 1d39f653..7ab6467f 100644
--- a/src/org/apache/xpath/xs/types/XSDouble.java
+++ b/src/org/apache/xpath/xs/types/XSDouble.java
@@ -193,4 +193,12 @@ public class XSDouble extends XSNumericType {
         return _value.equals(xsDouble.doubleValue()); 
     }
     
+    public boolean lt(XSDouble xsDouble) {
+        return doubleValue() < xsDouble.doubleValue(); 
+    }
+    
+    public boolean gt(XSDouble xsDouble) {
+        return doubleValue() > xsDouble.doubleValue(); 
+    }
+    
 }
diff --git a/src/org/apache/xpath/xs/types/XSFloat.java b/src/org/apache/xpath/xs/types/XSFloat.java
index c71f03f4..fb935958 100644
--- a/src/org/apache/xpath/xs/types/XSFloat.java
+++ b/src/org/apache/xpath/xs/types/XSFloat.java
@@ -187,4 +187,12 @@ public class XSFloat extends XSNumericType {
         return _value.equals(xsFloat.floatValue()); 
     }
 	
+	public boolean lt(XSFloat xsFloat) {
+	    return floatValue() < xsFloat.floatValue(); 
+    }
+	
+	public boolean gt(XSFloat xsFloat) {
+	    return floatValue() > xsFloat.floatValue(); 
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInt.java b/src/org/apache/xpath/xs/types/XSInt.java
index 72249bf6..7f93a0ac 100644
--- a/src/org/apache/xpath/xs/types/XSInt.java
+++ b/src/org/apache/xpath/xs/types/XSInt.java
@@ -98,4 +98,12 @@ public class XSInt extends XSLong {
         return _value.equals(xsInt.intValue()); 
     }
 	
+	public boolean lt(XSInt xsInt) {
+	    return _value.compareTo(xsInt.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSInt xsInt) {
+	    return _value.compareTo(xsInt.intValue()) > 0; 
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInteger.java b/src/org/apache/xpath/xs/types/XSInteger.java
index 0d207894..8232b066 100644
--- a/src/org/apache/xpath/xs/types/XSInteger.java
+++ b/src/org/apache/xpath/xs/types/XSInteger.java
@@ -128,12 +128,24 @@ public class XSInteger extends XSDecimal {
 		_value = val;
 	}
 	
+	public boolean equals(XSInteger xsInteger) {
+        return _value.equals(xsInteger.intValue()); 
+    }
+	
+	public boolean lt(XSInteger xsInteger) {
+	    return (intValue()).compareTo(xsInteger.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSInteger xsInteger) {
+	    return (intValue()).compareTo(xsInteger.intValue()) > 0; 
+    }
+	
 	/*
-	 * Do a datatype cast, of a generic typed XML Schema value,
-	 * to a java.math.BigInteger value. 
-	 */
-	private BigInteger castToInteger(XSAnyType xsAnyType) {
-	    
+     * Cast an object of type XSAnyType, to an object of type 
+     * java.math.BigInteger.  
+     */
+    private BigInteger castToInteger(XSAnyType xsAnyType) {
+        
         if (xsAnyType instanceof XSBoolean) {
             if ((xsAnyType.stringValue()).equals("true")) {
                 return BigInteger.ONE;
@@ -152,9 +164,5 @@ public class XSInteger extends XSDecimal {
         
         return new BigInteger(xsAnyType.stringValue());
     }
-	
-	public boolean equals(XSInteger xsInteger) {
-        return _value.equals(xsInteger.intValue()); 
-    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSLong.java b/src/org/apache/xpath/xs/types/XSLong.java
index 482bfb1d..e1e7032d 100644
--- a/src/org/apache/xpath/xs/types/XSLong.java
+++ b/src/org/apache/xpath/xs/types/XSLong.java
@@ -96,5 +96,13 @@ public class XSLong extends XSInteger {
 	public boolean equals(XSLong xsLong) {
         return _value.equals(xsLong.intValue()); 
     }
+	
+	public boolean lt(XSLong xsLong) {
+	    return _value.compareTo(xsLong.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSLong xsLong) {
+	    return _value.compareTo(xsLong.intValue()) > 0; 
+    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSTime.java b/src/org/apache/xpath/xs/types/XSTime.java
index 6289d915..e5c46d5b 100644
--- a/src/org/apache/xpath/xs/types/XSTime.java
+++ b/src/org/apache/xpath/xs/types/XSTime.java
@@ -36,16 +36,20 @@ public class XSTime extends XSCalendarType {
     private static final String XS_TIME = "xs:time";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
     /**
      * Class constructor.
      * 
-     * Initializes this object, to the supplied time and timezone.
+     * Construct an XSTime object, with the provided time and timezone 
+     * values.
      * 
-     * @param cal   Calendar representation of the time to be stored
-     * @param tz    the timezone (possibly null) associated with this time
+     * @param cal   the java.util.Calendar representation of the time to be stored
+     * @param tz    the timezone (this could be possibly null) associated with this 
+     *              XSTime object.
      */
     public XSTime(Calendar cal, XSDuration tz) {
         _calendar = cal;
@@ -60,10 +64,12 @@ public class XSTime extends XSCalendarType {
     }
 
     /**
-     * Initialises to the current time
+     * Class constructor.
+     * 
+     * Construct an XSTime object, and initialize it to the current time.
      */
     public XSTime() {
-        this (new GregorianCalendar(TimeZone.getTimeZone("GMT")), null);
+        this (new GregorianCalendar(TimeZone.getDefault()), null);
     }
 
     @Override
@@ -75,7 +81,7 @@ public class XSTime extends XSCalendarType {
     /**
      * Get the datatype's name.
      * 
-     * @return   "time" which is the datatype's name
+     * @return   "time" which is this datatype's name
      */
     @Override
     public String typeName() {
@@ -85,7 +91,7 @@ public class XSTime extends XSCalendarType {
     /**
      * Get the datatype's full name.
      * 
-     * @return   "xs:time" which is the datatype's full name
+     * @return   "xs:time" which is this datatype's full name
      */
     @Override
     public String stringType() {
@@ -93,8 +99,8 @@ public class XSTime extends XSCalendarType {
     }
     
     /**
-     * Get a java.util.Calendar representation of time stored, 
-     * within this object.
+     * Get a java.util.Calendar representation of an time value stored, 
+     * within this XSTime object.
      * 
      * @return    Calendar representation of the time stored
      */
@@ -103,63 +109,59 @@ public class XSTime extends XSCalendarType {
     }
     
     /**
-     * Get the seconds stored as an integer, within this object.
+     * Get the seconds value as an integer stored within this 
+     * XSTime object.
      * 
-     * @return    the second stored
+     * @return    the seconds value stored
      */
     public double second() {
-        double s = _calendar.get(Calendar.SECOND);
-        double ms = _calendar.get(Calendar.MILLISECOND);
+        double secondVal = _calendar.get(Calendar.SECOND);
+        double millisecVal = _calendar.get(Calendar.MILLISECOND);
 
-        ms /= 1000;
-        s += ms;
+        millisecVal /= 1000;
+        secondVal += millisecVal;
         
-        return s;
+        return secondVal;
     }
     
     /**
-     * Check whether the time component stored within this object, 
-     * has a timezone associated with it.
+     * Check whether this XSTime object has an, timezone associated with it.
      * 
-     * @return    true if the time has a timezone associated. false otherwise.
+     * @return true    if there is a timezone associated with this XSTime object.
+     *                 false otherwise.
      */
-    public boolean timezoned() {
+    public boolean isXsTimeObjectTimezoned() {
         return _timezoned;
     }
 
-    /**
-     * Get a String representation of the time stored.
-     * 
-     * @return   String representation of the time stored
-     */
     @Override
     public String stringValue() {
         String returnVal = "";
         
-        Calendar adjustFortimezone = calendar();
-        returnVal += XSDateTime.pad_int(adjustFortimezone.get(Calendar.HOUR_OF_DAY), 2);
+        Calendar calendarVal = calendar();
+        returnVal += XSDateTime.padInt(calendarVal.get(Calendar.HOUR_OF_DAY), 2);
         
         returnVal += ":";
-        returnVal += XSDateTime.pad_int(adjustFortimezone.get(Calendar.MINUTE), 2);
+        returnVal += XSDateTime.padInt(calendarVal.get(Calendar.MINUTE), 2);
         
 
         returnVal += ":";
-        int isecond = (int) second();
-        double sec = second();
+        int intSec = (int) second();
+        double doubleSec = second();
 
-        if ((sec - (isecond)) == 0.0) {
-            returnVal += XSDateTime.pad_int(isecond, 2);
+        if ((doubleSec - intSec) == 0.0) {
+            returnVal += XSDateTime.padInt(intSec, 2);
         }
         else {
-            if (sec < 10.0) {
-               returnVal += "0" + sec;
+            if (doubleSec < 10.0) {
+               returnVal += "0" + doubleSec;
             }
             else {
-               returnVal += sec;
+               returnVal += doubleSec;
             }
         }
 
-        if (timezoned()) {
+        if (isXsTimeObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
@@ -167,18 +169,18 @@ public class XSTime extends XSCalendarType {
                returnVal += "Z";
             }
             else {
-               String tZoneStr = "";
+               String timezoneStr = "";
                if (_tz.negative()) {
-                  tZoneStr += "-";  
+                  timezoneStr += "-";  
                }
                else {
-                  tZoneStr += "+"; 
+                  timezoneStr += "+"; 
                }
-               tZoneStr += XSDateTime.pad_int(hrs, 2);  
-               tZoneStr += ":";
-               tZoneStr += XSDateTime.pad_int(min, 2);
+               timezoneStr += XSDateTime.padInt(hrs, 2);  
+               timezoneStr += ":";
+               timezoneStr += XSDateTime.padInt(min, 2);
               
-               returnVal += tZoneStr;
+               returnVal += timezoneStr;
             }
          }
 
diff --git a/tests/org/apache/xalan/util/XslTransformTestsUtil.java b/tests/org/apache/xalan/util/XslTransformTestsUtil.java
index b7302aa3..41ee006f 100644
--- a/tests/org/apache/xalan/util/XslTransformTestsUtil.java
+++ b/tests/org/apache/xalan/util/XslTransformTestsUtil.java
@@ -19,6 +19,8 @@ package org.apache.xalan.util;
 import java.io.StringWriter;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.time.OffsetDateTime;
+import java.util.Date;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -37,7 +39,7 @@ import org.xml.sax.InputSource;
 import junit.framework.Assert;
 
 /**
- * A class providing, common services to this junit test suite.
+ * A class providing, common services to this JUnit test suite.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
@@ -89,15 +91,41 @@ public class XslTransformTestsUtil {
                    // the test has passed
                    return;
                }
+               else {
+                   // the test has failed
+                   Assert.fail();  
+               }
            }
+           else {
+              byte[] goldFileBytes = Files.readAllBytes(Paths.get(goldFilePath));
            
-           byte[] goldFileBytes = Files.readAllBytes(Paths.get(goldFilePath));
-           
-           Assert.assertEquals(new String(goldFileBytes), resultStrWriter.toString());          
+              Assert.assertEquals(new String(goldFileBytes), resultStrWriter.toString());
+           }
         }
         catch (Exception ex) {
             Assert.fail();    
         }
      }
     
+     public static Date getCurrentDate() {
+         Date currentDate = new Date();
+       
+         return currentDate;
+     }
+    
+     public static String getDefaultTimezoneOffsetStr() {
+         String timeZoneoffsetStr = null;
+        
+         String dateStr = (OffsetDateTime.now()).toString();
+         if (dateStr.endsWith("Z")) {
+             timeZoneoffsetStr = "Z";   
+         }
+         else {
+             int dateStrLength = dateStr.length();
+             timeZoneoffsetStr = dateStr.substring(dateStrLength - 6, dateStrLength); 
+         }
+        
+         return timeZoneoffsetStr;
+     }
+    
 }
diff --git a/tests/org/apache/xalan/xpath3/ValueComparisonTests.java b/tests/org/apache/xalan/xpath3/ValueComparisonTests.java
index e6638fc6..2d639ce2 100644
--- a/tests/org/apache/xalan/xpath3/ValueComparisonTests.java
+++ b/tests/org/apache/xalan/xpath3/ValueComparisonTests.java
@@ -24,7 +24,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath test cases, for value comparison operators 
+ * XPath 3.1 test cases, for value comparison operators 
  * eq, ne, lt, le, gt, ge.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
@@ -87,8 +87,37 @@ public class ValueComparisonTests extends XslTransformTestsUtil {
         
         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
         
-        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
-                                                                        new XslTestsErrorHandler());
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslValueComparison5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslValueComparison6() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.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 xslValueComparison7() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XSLConstants.java b/tests/org/apache/xalan/xslt3/XSLConstants.java
index c85a98db..ccaf7dab 100644
--- a/tests/org/apache/xalan/xslt3/XSLConstants.java
+++ b/tests/org/apache/xalan/xslt3/XSLConstants.java
@@ -36,8 +36,8 @@ public class XSLConstants {
     // the values of following, two variables are host specific where this test suite shall be run. the values of
     // following two variables may be modified, accordingly.
     
-    public static final String XSL_TRANSFORM_INPUT_DIRPATH_PREFIX = "file:///d:/eclipseWorkspaces/xalanj/xalan-java/tests/";
+    public static final String XSL_TRANSFORM_INPUT_DIRPATH_PREFIX = "file:///d:/eclipseWorkspaces/xalanj/xalan-java_mukul/tests/";
     
-    public static final String XSL_TRANSFORM_GOLD_DIRPATH_PREFIX = "d:/eclipseWorkspaces/xalanj/xalan-java/tests/";
+    public static final String XSL_TRANSFORM_GOLD_DIRPATH_PREFIX = "d:/eclipseWorkspaces/xalanj/xalan-java_mukul/tests/";
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
index 131a2742..3ef89058 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -190,5 +190,15 @@ public class XslIterateTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslIterateTest15() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test13.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test13.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/xpath_value_comparison/gold/test5.out b/tests/xpath_value_comparison/gold/test5.out
new file mode 100644
index 00000000..1457921d
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test5.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <item pos="2">
+    <a>6.5</a>
+  </item>
+  <item pos="4">
+    <a>-55.23</a>
+  </item>
+  <item pos="6">
+    <b>hello1</b>
+  </item>
+  <item pos="8">
+    <b>5</b>
+  </item>
+</elem>
diff --git a/tests/xpath_value_comparison/gold/test6.out b/tests/xpath_value_comparison/gold/test6.out
new file mode 100644
index 00000000..360e660c
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test6.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <group>
+    <a>1</a>
+    <c>3</c>
+    <e>5</e>
+    <g>7</g>
+  </group>
+  <group>
+    <b>2</b>
+    <d>4</d>
+    <f>6</f>
+    <h>8</h>
+  </group>
+</elem>
diff --git a/tests/xpath_value_comparison/gold/test7.out b/tests/xpath_value_comparison/gold/test7.out
new file mode 100644
index 00000000..5e55aad3
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test7.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <result1>true</result1>
+  <result2>true</result2>
+  <result3>true</result3>
+  <result4>true</result4>
+  <result5>false</result5>
+  <result6>false</result6>
+  <result7>true</result7>
+  <result8>false</result8>
+  <result9>true</result9>
+  <result10>true</result10>
+  <result11>false</result11>
+  <result12>false</result12>
+</elem>
diff --git a/tests/xpath_value_comparison/test1.xsl b/tests/xpath_value_comparison/test1.xsl
index c10bcc01..b92e074e 100644
--- a/tests/xpath_value_comparison/test1.xsl
+++ b/tests/xpath_value_comparison/test1.xsl
@@ -2,7 +2,10 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 version="3.0">
                 
-   <!-- Author: mukulg@apache.org -->                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test1_b.xml b/tests/xpath_value_comparison/test1_b.xml
new file mode 100644
index 00000000..24f8e40c
--- /dev/null
+++ b/tests/xpath_value_comparison/test1_b.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<elem>
+   <a>1</a>
+   <b>2</b>
+   <c>3</c>
+   <d>4</d>
+   <e>5</e>
+   <f>6</f>
+   <g>7</g>
+   <h>8</h>
+</elem>
\ No newline at end of file
diff --git a/tests/xpath_value_comparison/test2.xsl b/tests/xpath_value_comparison/test2.xsl
index 4157a324..9ca96fca 100644
--- a/tests/xpath_value_comparison/test2.xsl
+++ b/tests/xpath_value_comparison/test2.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test3.xsl b/tests/xpath_value_comparison/test3.xsl
index 1a79f2d4..28619b38 100644
--- a/tests/xpath_value_comparison/test3.xsl
+++ b/tests/xpath_value_comparison/test3.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test4.xsl b/tests/xpath_value_comparison/test4.xsl
index 07de2645..ad9b7c34 100644
--- a/tests/xpath_value_comparison/test4.xsl
+++ b/tests/xpath_value_comparison/test4.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'ne'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test3.xsl b/tests/xpath_value_comparison/test5.xsl
similarity index 75%
copy from tests/xpath_value_comparison/test3.xsl
copy to tests/xpath_value_comparison/test5.xsl
index 1a79f2d4..41088d71 100644
--- a/tests/xpath_value_comparison/test3.xsl
+++ b/tests/xpath_value_comparison/test5.xsl
@@ -4,13 +4,20 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
    <xsl:template match="/elem">
       <elem>
-        <result><xsl:value-of select="a[1] eq a"/></result>
+        <xsl:for-each select="*">
+           <xsl:if test="(position() mod 2) eq 0">
+              <item pos="{position()}"><xsl:copy-of select="."/></item>
+           </xsl:if>
+        </xsl:for-each>
       </elem>
    </xsl:template>
    
diff --git a/tests/xpath_value_comparison/test2.xsl b/tests/xpath_value_comparison/test6.xsl
similarity index 72%
copy from tests/xpath_value_comparison/test2.xsl
copy to tests/xpath_value_comparison/test6.xsl
index 4157a324..e2bfe7ff 100644
--- a/tests/xpath_value_comparison/test2.xsl
+++ b/tests/xpath_value_comparison/test6.xsl
@@ -4,14 +4,21 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_b.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. This stylesheet, also uses an
+        XSLT instruction xsl:for-each-group. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
    <xsl:template match="/elem">
       <elem>
-        <result1><xsl:value-of select="a[1] eq a[2]"/></result1>
-        <result2><xsl:value-of select="a[1] eq a[3]"/></result2>
+        <xsl:for-each-group select="*" group-by="(. mod 2) eq 0">           
+           <group>
+              <xsl:copy-of select="current-group()"/>
+           </group> 
+        </xsl:for-each-group>
       </elem>
    </xsl:template>
    
diff --git a/tests/xpath_value_comparison/test7.xsl b/tests/xpath_value_comparison/test7.xsl
new file mode 100644
index 00000000..b1d34e4f
--- /dev/null
+++ b/tests/xpath_value_comparison/test7.xsl
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:java="http://xml.apache.org/xalan/java"
+                exclude-result-prefixes="xs java"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet to test, XPath 3.1 value comparison 
+        operators 'eq' and 'lt'.
+        
+        To be able to test XPath 'eq' operator involving expression
+        like xs:date($currentDateStr) eq current-date(), where the
+        variable $currentDateStr has the current date's string value
+        (with format yyyy-mm-dd) when this test is been run, we use
+        XalanJ's java extension mechanism to get the current date's
+        string value.  
+   -->                
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <xsl:variable name="currentDateStr" select="java:format(java:java.text.SimpleDateFormat.new('yyyy-MM-dd'), 
+                                                        java:org.apache.xalan.util.XslTransformTestsUtil.getCurrentDate())"/>
+                                                        
+   <xsl:variable name="timeZoneOffsetStr" select="java:org.apache.xalan.util.XslTransformTestsUtil.getDefaultTimezoneOffsetStr()"/>                                                                    
+
+   <xsl:template match="/">            
+      <elem>                       
+        <result1><xsl:value-of select="xs:date('2023-06-19') lt current-date()"/></result1>
+        <result2><xsl:value-of select="xs:date('2023-06-20') lt current-date()"/></result2>
+        <result3><xsl:value-of select="xs:date('2023-06-21') lt current-date()"/></result3>
+        <result4><xsl:value-of select="xs:date($currentDateStr) eq current-date()"/></result4>
+        <result5><xsl:value-of select="xs:date('2023-06-21Z') eq current-date()"/></result5>
+        <result6><xsl:value-of select="xs:date('2023-06-15Z') eq xs:date('2023-06-15+05:30')"/></result6>        
+        <result7><xsl:value-of select="xs:date(concat($currentDateStr,$timeZoneOffsetStr)) eq current-date()"/></result7>
+        <result8><xsl:value-of select="xs:date('2023-06-21+10:00') eq xs:date('2023-06-21')"/></result8>
+        <result9><xsl:value-of select="current-date() eq current-date()"/></result9>
+        <result10><xsl:value-of select="xs:date('2023-06-21') eq xs:date('2023-06-21')"/></result10>
+        <result11><xsl:value-of select="xs:date('2023-06-19Z') lt xs:date('2023-06-19+05:30')"/></result11>
+        <result12><xsl:value-of select="xs:date('2023-06-19-06:00') lt xs:date('2023-06-19+05:30')"/></result12>
+      </elem>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_iterate/gold/test13.out b/tests/xsl_iterate/gold/test13.out
new file mode 100644
index 00000000..755e736e
--- /dev/null
+++ b/tests/xsl_iterate/gold/test13.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <balance value="12.00" date="2008-09-01"/>
+  <balance value="20.00" date="2008-09-01"/>
+</result>
diff --git a/tests/xsl_iterate/test13.xsl b/tests/xsl_iterate/test13.xsl
new file mode 100644
index 00000000..a70f3157
--- /dev/null
+++ b/tests/xsl_iterate/test13.xsl
@@ -0,0 +1,59 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_c.xml -->
+   
+  <!-- This XSLT stylesheet, uses xsl:iterate to compute cumulative 
+       totals.
+       
+       This XSLT stylesheet is borrowed from XSLT 3.0 spec, with 
+       slight modifications. -->                 
+  
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+        <xsl:iterate select="transactions/transaction">
+           <xsl:param name="balance" select="0.00"/>
+           <xsl:param name="prevDate"/>
+           <xsl:variable name="newBalance" select="$balance + xs:decimal(@value)"/>
+           <xsl:variable name="thisDate" select="xs:date(@date)"/>
+           <xsl:choose>
+              <xsl:when test="(position() eq 1) or ($thisDate eq $prevDate)">
+                 <balance date="{$thisDate}" value="{format-number($newBalance, '0.00')}"/>
+                 <xsl:next-iteration>
+                    <xsl:with-param name="balance" select="$newBalance"/>
+                    <xsl:with-param name="prevDate" select="$thisDate"/>
+                 </xsl:next-iteration>
+              </xsl:when>
+              <xsl:otherwise>
+                 <xsl:break/>
+              </xsl:otherwise>
+           </xsl:choose>
+        </xsl:iterate>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>


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