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/09/02 13:36:06 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 sequence type expressions that can handle various xml schema built-in types, and their use within xslt 3.0 xsl:variable instruction with 'as' attribute. also committing few new related working test cases as well. doing minor codebase refactoring as well, within few other parts of xalanj implementation on this dev repos branch.

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 3659d3bd committing implementation of xpath 3.1 sequence type expressions that can handle various xml schema built-in types, and their use within xslt 3.0 xsl:variable instruction with 'as' attribute. also committing few new related working test cases as well. doing minor codebase refactoring as well, within few other parts of xalanj implementation on this dev repos branch.
     new b2e143f5 Merge pull request #73 from mukulga/xalan-j_xslt3.0_mukul
3659d3bd is described below

commit 3659d3bd06e5a16def812eab968ba59bc893aa15
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Sep 2 19:02:42 2023 +0530

    committing implementation of xpath 3.1 sequence type expressions that can handle various xml schema built-in types, and their use within xslt 3.0 xsl:variable instruction with 'as' attribute. also committing few new related working test cases as well. doing minor codebase refactoring as well, within few other parts of xalanj implementation on this dev repos branch.
---
 src/org/apache/xalan/processor/XSLTSchema.java     |  11 +-
 src/org/apache/xalan/templates/ElemVariable.java   |  83 +++-
 src/org/apache/xpath/XPath.java                    |  41 +-
 src/org/apache/xpath/compiler/Compiler.java        |  20 +
 src/org/apache/xpath/compiler/Lexer.java           |   3 +-
 src/org/apache/xpath/compiler/OpCodes.java         |   4 +-
 src/org/apache/xpath/compiler/XPathParser.java     | 113 ++++-
 src/org/apache/xpath/composite/ForExpr.java        |  11 +-
 .../apache/xpath/composite/SequenceTypeData.java   |  56 +++
 .../xpath/composite/SequenceTypeSupport.java       | 516 +++++++++++++++++++++
 .../xpath/composite/XPathSequenceTypeExpr.java     |  87 ++++
 .../apache/xpath/functions/FuncContainsToken.java  |   6 +-
 src/org/apache/xpath/objects/XObject.java          |  39 ++
 src/org/apache/xpath/xs/types/XSBoolean.java       |   4 +
 src/org/apache/xpath/xs/types/XSDate.java          |  80 ++--
 src/org/apache/xpath/xs/types/XSDateTime.java      | 199 ++++----
 .../apache/xpath/xs/types/XSDayTimeDuration.java   |  45 +-
 src/org/apache/xpath/xs/types/XSDecimal.java       |   4 +
 src/org/apache/xpath/xs/types/XSDouble.java        |   4 +
 src/org/apache/xpath/xs/types/XSDuration.java      |  38 +-
 src/org/apache/xpath/xs/types/XSFloat.java         |   4 +
 src/org/apache/xpath/xs/types/XSInt.java           |   4 +
 src/org/apache/xpath/xs/types/XSInteger.java       |   4 +
 src/org/apache/xpath/xs/types/XSLong.java          |   4 +
 src/org/apache/xpath/xs/types/XSString.java        |   4 +
 src/org/apache/xpath/xs/types/XSTime.java          |   4 +
 src/org/apache/xpath/xs/types/XSUntyped.java       |   2 +-
 src/org/apache/xpath/xs/types/XSUntypedAtomic.java |   2 +-
 .../apache/xpath/xs/types/XSYearMonthDuration.java | 154 +++---
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   3 +-
 .../apache/xalan/xslt3/XslAttributeAsTests.java    |  85 ++++
 tests/xsl_attribute_as/gold/test1.out              |   8 +
 tests/xsl_attribute_as/gold/test2.out              |   4 +
 tests/xsl_attribute_as/gold/test3.out              |   1 +
 tests/xsl_attribute_as/test1.xsl                   |  53 +++
 tests/xsl_attribute_as/test1_a.xml                 |   7 +
 tests/xsl_attribute_as/test2.xsl                   |  48 ++
 tests/xsl_attribute_as/test3.xsl                   |  46 ++
 38 files changed, 1555 insertions(+), 246 deletions(-)

diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index d0aeb9cf..2e5e6f76 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -244,7 +244,12 @@ public class XSLTSchema extends XSLTElementDef
     // Optional.                                          
     // xsl:variable, xsl:param, xsl:with-param, xsl:attribute, xsl:break, xsl:on-completion                                       
     XSLTAttributeDef selectAttrOpt = new XSLTAttributeDef(null, "select",
-                                       XSLTAttributeDef.T_EXPR, false, false,XSLTAttributeDef.ERROR);
+                                       XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
+    
+    // Optional.
+    // xsl:variable 
+    XSLTAttributeDef asAttrOpt = new XSLTAttributeDef(null, "as",
+                                       XSLTAttributeDef.T_STRING, false, false, XSLTAttributeDef.ERROR);
 
     // Optional.
     // Default: "node()"
@@ -595,7 +600,7 @@ public class XSLTSchema extends XSLTElementDef
                                    null /*alias */,
                                    templateElements /* elements */,  // %template;>
                                    new XSLTAttributeDef[]{ nameAttrRequired,
-                                                           selectAttrOpt }, 
+                                                           selectAttrOpt, asAttrOpt }, 
                                   new ProcessorTemplateElem(),
                                    ElemVariable.class /* class object */, 20, true);
     XSLTElementDef xslParam = new XSLTElementDef(this,
@@ -872,7 +877,7 @@ public class XSLTSchema extends XSLTElementDef
                                            templateElements /* elements */,
                                            new XSLTAttributeDef[]{
                                                    nameAttrRequired,
-                                                   selectAttrOpt }, 
+                                                   selectAttrOpt, asAttrOpt }, 
                                            new ProcessorGlobalVariableDecl(),
                                            ElemVariable.class /* class object */, 20, true),
                                   new XSLTElementDef(
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 9bb1ddfb..992dedbe 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -34,6 +34,7 @@ import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.axes.SelfIteratorNoPredicate;
+import org.apache.xpath.composite.SequenceTypeSupport;
 import org.apache.xpath.functions.FuncExtFunction;
 import org.apache.xpath.functions.Function;
 import org.apache.xpath.objects.InlineFunction;
@@ -153,6 +154,26 @@ public class ElemVariable extends ElemTemplateElement
   {
     return m_selectPattern;
   }
+  
+  /**
+   * The value of the "as" attribute.
+   */
+  private String m_asAttr;
+  
+  /**
+   * Set the "as" attribute.
+   */
+  public void setAs(String val) {
+     m_asAttr = val;
+  }
+  
+  /**
+   * Get the "as" attribute.
+   */
+  public String getAs()
+  {
+     return m_asAttr;
+  }
 
   /**
    * The value of the "name" attribute.
@@ -253,7 +274,7 @@ public class ElemVariable extends ElemTemplateElement
   {
 
     m_selectPattern = param.m_selectPattern;
-    m_qname = param.m_qname;
+    m_qname = param.m_qname;   
     m_isTopLevel = param.m_isTopLevel;
 
     // m_value = param.m_value;
@@ -314,15 +335,21 @@ public class ElemVariable extends ElemTemplateElement
 
     xctxt.pushCurrentNode(sourceNode);
     
-    SourceLocator srcLocator = xctxt.getSAXLocator(); 
+    SourceLocator srcLocator = xctxt.getSAXLocator();
+    
+    Expression selectExpression = null;
  
     try {        
       if (m_selectPattern != null) {          
-        Expression selectExpression = m_selectPattern.getExpression();
+        selectExpression = m_selectPattern.getExpression();
         if (selectExpression instanceof FuncExtFunction) {
             XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
                                                                                         selectExpression);
             if (evalResult != null) {
+                if (m_asAttr != null) {
+                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+                }
+                
                 return evalResult;    
             }
             else {
@@ -332,18 +359,30 @@ public class ElemVariable extends ElemTemplateElement
         else if (selectExpression instanceof Function) {
             XObject evalResult = ((Function)selectExpression).execute(xctxt);            
             if ((evalResult instanceof ResultSequence) || 
-                                                (evalResult instanceof XSAnyType)) {                
+                                                (evalResult instanceof XSAnyType)) {
+                if (m_asAttr != null) {
+                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+                }
+                
                 return evalResult; 
             }
         }
         else if (selectExpression instanceof SimpleMapOperator) {
             XObject evalResult = selectExpression.execute(xctxt);
             
+            if (m_asAttr != null) {
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+            }
+             
             return evalResult;
         }
         else if (selectExpression instanceof Range) {
             XObject evalResult = ((Range)selectExpression).execute(xctxt);
             
+            if (m_asAttr != null) {
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+            }
+             
             return evalResult; 
         }
         else if (selectExpression instanceof Operation) {
@@ -354,12 +393,20 @@ public class ElemVariable extends ElemTemplateElement
                                                                                          xctxt, opn.getRightOperand());
             XObject evalResult = opn.operate(leftOperand, rightOperand);
             
+            if (m_asAttr != null) {
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+            }
+             
             return evalResult;
         }
         else if (selectExpression instanceof SelfIteratorNoPredicate) {
             XObject xpath3ContextItem = xctxt.getXPath3ContextItem();
-            if (xpath3ContextItem != null) {
-               return xpath3ContextItem;     
+            if (xpath3ContextItem != null) {               
+              if (m_asAttr != null) {
+                 xpath3ContextItem = SequenceTypeSupport.convertXDMValueToAnotherType(xpath3ContextItem, m_asAttr, xctxt);  
+              }
+                
+              return xpath3ContextItem;
             }
         }
         else if (selectExpression instanceof LocPathIterator) {                        
@@ -377,7 +424,11 @@ public class ElemVariable extends ElemTemplateElement
             
             if (dtmIter != null) {               
                var = new XNodeSet(dtmIter);
-                
+               
+               if (m_asAttr != null) {
+                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+               }
+                 
                return var; 
             }
             else {
@@ -397,7 +448,7 @@ public class ElemVariable extends ElemTemplateElement
                    String xpathIndexExprStr = xpathExprStr.substring(xpathExprStr.indexOf('[') + 1, 
                                                                                         xpathExprStr.indexOf(']'));
 
-                   // evaluate the, variable reference XPath expression
+                   // Evaluate the, variable reference XPath expression
                    if (prefixTable != null) {
                        varRefXPathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
                                                                                                  varRefXPathExprStr, 
@@ -412,7 +463,7 @@ public class ElemVariable extends ElemTemplateElement
                    
                    XObject varEvalResult = varXPathObj.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, 
@@ -467,6 +518,10 @@ public class ElemVariable extends ElemTemplateElement
                
                var = resultSeq;
                
+               if (m_asAttr != null) {
+                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+               }
+                  
                return var;
             }
         }
@@ -505,7 +560,7 @@ public class ElemVariable extends ElemTemplateElement
 
         // var = new XRTreeFrag(df, xctxt, this);
 		
-		// with XSLT 3.0, RTFs are treated as proper node sets
+		// With XSLT 3.0, RTFs are treated as proper node sets
 		NodeList nodeList = (new XRTreeFrag(df, xctxt, this)).convertToNodeset();		
 		
 		var = new XNodeSetForDOM(nodeList, xctxt); 
@@ -518,9 +573,13 @@ public class ElemVariable extends ElemTemplateElement
        xctxt.popCurrentNode();
     }
     
-    // restore the original xpath context, on the xslt transformer object
+    // Restore the original xpath context, on the xslt transformer object
     transformer.setXPathContext(xctxtOriginal);
-
+    
+    if (m_asAttr != null) {
+       var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+    }
+        
     return var;
     
   }
diff --git a/src/org/apache/xpath/XPath.java b/src/org/apache/xpath/XPath.java
index 5c121a3a..40410ff4 100644
--- a/src/org/apache/xpath/XPath.java
+++ b/src/org/apache/xpath/XPath.java
@@ -181,7 +181,7 @@ public class XPath implements Serializable, ExpressionOwner
     Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
 
     if (SELECT == type)
-      parser.initXPath(compiler, exprString, prefixResolver);
+      parser.initXPath(compiler, exprString, prefixResolver, false);
     else if (MATCH == type)
       parser.initMatchPattern(compiler, exprString, prefixResolver);
     else
@@ -228,7 +228,7 @@ public class XPath implements Serializable, ExpressionOwner
     Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
 
     if (SELECT == type)
-      parser.initXPath(compiler, exprString, prefixResolver);
+      parser.initXPath(compiler, exprString, prefixResolver, false);
     else if (MATCH == type)
       parser.initMatchPattern(compiler, exprString, prefixResolver);
     else
@@ -266,6 +266,43 @@ public class XPath implements Serializable, ExpressionOwner
   {  
     this(exprString, locator, prefixResolver, type, null);    
   }
+  
+  /**
+   * Construct an XPath object. This method has an additional parameter
+   * 'isSequenceTypeXPathExpr', to handle XPath 3.1 expressions that 
+   * represent sequence type declarations. 
+   *
+   * @throws javax.xml.transform.TransformerException if syntax or other error.
+   */
+  public XPath(
+          String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type,
+          ErrorListener errorListener, boolean isSequenceTypeXPathExpr)
+            throws javax.xml.transform.TransformerException {
+      initFunctionTable();     
+      if(null == errorListener)
+        errorListener = new org.apache.xml.utils.DefaultErrorHandler();
+      
+      m_patternString = exprString;
+
+      XPathParser parser = new XPathParser(errorListener, locator);
+      Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
+
+      if (SELECT == type)
+        parser.initXPath(compiler, exprString, prefixResolver, isSequenceTypeXPathExpr);
+      else if (MATCH == type)
+        parser.initMatchPattern(compiler, exprString, prefixResolver);
+      else
+        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)}));
+
+      Expression expr = compiler.compile(0);
+
+      this.setExpression(expr);
+      
+      if((null != locator) && locator instanceof ExpressionNode)
+      {
+          expr.exprSetParent((ExpressionNode)locator);
+      } 
+  }
 
   /**
    * Construct an XPath object.
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
index 20b8da3d..dd5a99fb 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -172,6 +172,8 @@ public class Compiler extends OpMap
       expr = nodeComparisonFollows(opPos); break;
     case OpCodes.OP_SIMPLE_MAP_OPERATOR :
       expr = simpleMapOperator(opPos); break;
+    case OpCodes.OP_SEQUENCE_TYPE_EXPR :
+      expr = sequenceTypeExpr(opPos); break;
     case OpCodes.OP_LTE :
       expr = lte(opPos); break;
     case OpCodes.OP_LT :
@@ -512,6 +514,24 @@ public class Compiler extends OpMap
   {
     return compileOperation(new SimpleMapOperator(), opPos);
   }
+  
+  /**
+   * Compile an XPath 'SequenceType', expression.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   *
+   * @return the compiled 'SequenceType' expression returned as an object of class
+   *         XPathSequenceTypeExpr. An object of class XPathSequenceTypeExpr
+   *         has already been created and populated by XPath expression parser,
+   *         and this function just returns that object to the caller of this 
+   *         method.       
+   *
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  Expression sequenceTypeExpr(int opPos) throws TransformerException
+  {
+      return XPathParser.fXpathSequenceTypeExpr;
+  }
 
   /**
    * Compile a '>=' operation.
diff --git a/src/org/apache/xpath/compiler/Lexer.java b/src/org/apache/xpath/compiler/Lexer.java
index 55eba0db..c8881789 100644
--- a/src/org/apache/xpath/compiler/Lexer.java
+++ b/src/org/apache/xpath/compiler/Lexer.java
@@ -252,7 +252,8 @@ class Lexer
       case ')' :
       case ']' :
       case '{' :   // added for XPath 3.1
-      case '}' :   // added for XPath 3.1    
+      case '}' :   // added for XPath 3.1
+      case '?' :   // added for XPath 3.1    
       case '|' :
         if ((pat.length() > (i + 1)) && (pat.charAt(i + 1) == '|')) {
           // added for XPath 3.1.
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
index 0aeb90bd..3d10a259 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -724,8 +724,10 @@ public class OpCodes
    * @xsl.usage advanced
    */
   public static final int OP_SIMPLE_MAP_OPERATOR = 72;
+  
+  public static final int OP_SEQUENCE_TYPE_EXPR = 73;
 
   /** The next free ID. Please keep this up to date. */
-  private static final int NEXT_FREE_ID = 73;
+  private static final int NEXT_FREE_ID = 74;
   
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 2806c54f..79d0c75c 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Stack;
 
+import javax.xml.XMLConstants;
 import javax.xml.transform.ErrorListener;
 import javax.xml.transform.TransformerException;
 
@@ -37,7 +38,9 @@ import org.apache.xpath.composite.IfExpr;
 import org.apache.xpath.composite.LetExpr;
 import org.apache.xpath.composite.LetExprVarBinding;
 import org.apache.xpath.composite.QuantifiedExpr;
+import org.apache.xpath.composite.SequenceTypeSupport;
 import org.apache.xpath.composite.SimpleSequenceConstructor;
+import org.apache.xpath.composite.XPathSequenceTypeExpr;
 import org.apache.xpath.domapi.XPathStylesheetDOM3Exception;
 import org.apache.xpath.functions.DynamicFunctionCall;
 import org.apache.xpath.objects.InlineFunction;
@@ -112,6 +115,8 @@ public class XPathParser
   
   private boolean fIsBeginParse = false;
   
+  private boolean fIsSequenceTypeXPathExpr = false;
+  
   static InlineFunction fInlineFunction = null;
   
   static DynamicFunctionCall fDynamicFunctionCall = null;
@@ -126,6 +131,8 @@ public class XPathParser
   
   static SimpleSequenceConstructor fSimpleSequenceConstructor = null;
   
+  static XPathSequenceTypeExpr fXpathSequenceTypeExpr = null;
+  
   /**
    * The parser constructor.
    */
@@ -149,17 +156,25 @@ public class XPathParser
    * @param expression A string conforming to the XPath grammar.
    * @param namespaceContext An object that is able to resolve prefixes in
    * the XPath to namespaces.
+   * @param isSequenceTypeXPathExpr When this method is called, with this parameter
+   *                                set to boolean value 'true', then an XPath parser object 
+   *                                instance, instantiated from this class shall parse the XPath
+   *                                expression string assuming that it represents an XPath 3.1
+   *                                sequence type expression (for e.g, as a value of "as" 
+   *                                attribute of xsl:variable instruction). 
    *
    * @throws javax.xml.transform.TransformerException
    */
   public void initXPath(
-          Compiler compiler, String expression, PrefixResolver namespaceContext)
+          Compiler compiler, String expression, PrefixResolver namespaceContext, boolean isSequenceTypeXPathExpr)
             throws javax.xml.transform.TransformerException
   {
 
     m_ops = compiler;
     m_namespaceContext = namespaceContext;
     m_functionTable = compiler.getFunctionTable();
+    
+    fIsSequenceTypeXPathExpr = isSequenceTypeXPathExpr; 
 
     Lexer lexer = new Lexer(compiler, namespaceContext, this);
 
@@ -211,7 +226,7 @@ public class XPathParser
 		// What I _want_ to do is null out this XPath.
 		// I doubt this has the desired effect, but I'm not sure what else to do.
 		// %REVIEW%!!!
-		initXPath(compiler, "/..",  namespaceContext);
+		initXPath(compiler, "/..",  namespaceContext, false);
 	  }
 	  else
 		throw e;
@@ -1116,6 +1131,9 @@ public class XPathParser
              ExprSingle();
           }
       }
+      else if (fIsSequenceTypeXPathExpr) {
+         fXpathSequenceTypeExpr = SequenceTypeExpr(); 
+      }
       else {
          ExprSingle();  
       }
@@ -3554,4 +3572,95 @@ public class XPathParser
     return trailingSlashConsumed;
   }
   
+  protected XPathSequenceTypeExpr SequenceTypeExpr() throws javax.xml.transform.TransformerException
+  {
+      int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+                  
+      insertOp(opPos, 2, OpCodes.OP_SEQUENCE_TYPE_EXPR);
+      
+      XPathSequenceTypeExpr xpathSequenceTypeExpr = new XPathSequenceTypeExpr();
+      
+      if (tokenIs("empty-sequence") && lookahead('(', 1) && lookahead(')', 2)) {
+         xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.EMPTY_SEQUENCE);
+         consumeExpected("empty-sequence");
+         consumeExpected('(');
+         consumeExpected(')');
+      }
+      else if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+         consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+         consumeExpected(':');
+         
+         switch (m_token) {
+            case Keywords.FUNC_BOOLEAN_STRING :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.BOOLEAN);
+               break;
+            case Keywords.XS_STRING :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.STRING);
+               break; 
+            case Keywords.XS_DECIMAL :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
+               break; 
+            case Keywords.XS_FLOAT :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_FLOAT);
+               break; 
+            case Keywords.XS_DOUBLE :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
+               break;
+            case Keywords.XS_INTEGER :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INTEGER);
+               break;
+            case Keywords.XS_LONG :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_LONG);
+               break; 
+            case Keywords.XS_INT :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_INT);
+               break;
+            case Keywords.XS_DATE :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DATE);
+               break;
+            case Keywords.XS_DURATION :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DURATION);
+               break;
+            case Keywords.XS_YEAR_MONTH_DURATION :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
+               break;
+            case Keywords.XS_DAY_TIME_DURATION :
+               xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
+               break;
+            default :
+               throw new XPathProcessorException("XPST0051 An XML Schema type 'xs:" + m_token + "' is not "
+                                                                             + "recognized, within the provided sequence type expression.");        
+         }
+         
+         nextToken();
+         
+         if ((m_token != null) && (xpathSequenceTypeExpr.getSequenceType() > 0)) {
+            if (tokenIs(SequenceTypeSupport.Q_MARK)) {
+               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                     OccurenceIndicator.ZERO_OR_ONE);
+               nextToken();
+            }
+            else if (tokenIs(SequenceTypeSupport.STAR)) {
+               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                     OccurenceIndicator.ZERO_OR_MANY);
+               nextToken();
+            }
+            else if (tokenIs(SequenceTypeSupport.PLUS)) {
+               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                     OccurenceIndicator.ONE_OR_MANY);
+               nextToken();
+            }
+            else {
+               throw new XPathProcessorException("XPST0051 A sequence type occurence indicator '" + m_token + "', is not recognized."); 
+            }
+         }
+         
+      }
+      
+      m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
+                                             m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
+      
+      return xpathSequenceTypeExpr;
+  }
+  
 }
diff --git a/src/org/apache/xpath/composite/ForExpr.java b/src/org/apache/xpath/composite/ForExpr.java
index 583f950a..5feb5ebe 100644
--- a/src/org/apache/xpath/composite/ForExpr.java
+++ b/src/org/apache/xpath/composite/ForExpr.java
@@ -244,16 +244,15 @@ public class ForExpr extends Expression {
                                                                         xctxt.getNamespaceContext());
             
             if (retExprResultVal instanceof XNodeSet) { 
-               XNodeSet xNodeSetItem = (XNodeSet)retExprResultVal;
+               XNodeSet xNodeSet = (XNodeSet)retExprResultVal;
                
-               XNodeSet xsObjNodeSet = (XNodeSet)xNodeSetItem;
-               DTMIterator dtmIter = xsObjNodeSet.iterRaw();
+               DTMIterator dtmIter = xNodeSet.iterRaw();               
                
                int nextNodeDtmHandle;
-                      
+               
                while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {       
-                  XNodeSet singletonXPathNode = new XNodeSet(nextNodeDtmHandle, xctxt);
-                  returnExprResultSet.add(singletonXPathNode);
+                  XNodeSet nodeSetItem = new XNodeSet(nextNodeDtmHandle, xctxt);
+                  returnExprResultSet.add(nodeSetItem);
                }
             }
             else if (retExprResultVal instanceof ResultSequence) {
diff --git a/src/org/apache/xpath/composite/SequenceTypeData.java b/src/org/apache/xpath/composite/SequenceTypeData.java
new file mode 100644
index 00000000..5ec295a2
--- /dev/null
+++ b/src/org/apache/xpath/composite/SequenceTypeData.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.composite;
+
+import org.apache.xpath.objects.XObject;
+
+/**
+ * An object of this class, stores information about use of one
+ * sequence type XPath expression, while doing an XSLT stylesheet 
+ * transformation.
+ * 
+ * For e.g, an object of this class can store XSLT transformation
+ * run-time data for sequence type expressions like xs:string, 
+ * xs:string+, xs:integer, xs:integer*, empty-sequence() etc. 
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class SequenceTypeData extends XObject {
+    
+    private int fSequenceType;
+    
+    private int fItemTypeOccurrenceIndicator;
+
+    public int getSequenceType() {
+        return fSequenceType;
+    }
+
+    public void setSequenceType(int sequenceType) {
+        this.fSequenceType = sequenceType;
+    }
+
+    public int getItemTypeOccurrenceIndicator() {
+        return fItemTypeOccurrenceIndicator;
+    }
+
+    public void setItemTypeOccurrenceIndicator(int itemTypeOccurrenceIndicator) {
+        this.fItemTypeOccurrenceIndicator = itemTypeOccurrenceIndicator;
+    }
+
+}
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
new file mode 100644
index 00000000..6a23c2eb
--- /dev/null
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.composite;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
+import org.apache.xpath.xs.types.XSDateTime;
+import org.apache.xpath.xs.types.XSDayTimeDuration;
+import org.apache.xpath.xs.types.XSDecimal;
+import org.apache.xpath.xs.types.XSDouble;
+import org.apache.xpath.xs.types.XSDuration;
+import org.apache.xpath.xs.types.XSFloat;
+import org.apache.xpath.xs.types.XSInt;
+import org.apache.xpath.xs.types.XSInteger;
+import org.apache.xpath.xs.types.XSLong;
+import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSTime;
+import org.apache.xpath.xs.types.XSUntyped;
+import org.apache.xpath.xs.types.XSUntypedAtomic;
+import org.apache.xpath.xs.types.XSYearMonthDuration;
+
+/**
+ * This class provides few utility methods, to help implement
+ * XPath 3.1 sequence type expressions.
+ * 
+ * Ref : https://www.w3.org/TR/xpath-31/#id-sequencetype-syntax
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class SequenceTypeSupport {
+    
+    // Following are various constant int values, denoting 
+    // XPath 3.1 and XML Schema data types.
+        
+    public static int EMPTY_SEQUENCE = 1;
+    
+    // Represents both XalanJ legacy boolean data type,
+    // and XML Schema data type xs:boolean.
+    public static int BOOLEAN = 2;
+    
+    // Represents both XalanJ legacy string data type,
+    // and XML Schema data type xs:string.
+    public static int STRING = 3;
+    
+    public static int XS_DATE = 4;
+    
+    public static int XS_DATETIME = 5;
+    
+    public static int XS_TIME = 6;
+    
+    public static int XS_DURATION = 7;
+    
+    public static int XS_DAYTIME_DURATION = 8;
+    
+    public static int XS_YEARMONTH_DURATION = 9;
+    
+    public static int XS_DECIMAL = 10;
+    
+    public static int XS_INTEGER = 11;
+    
+    public static int XS_LONG = 12;
+    
+    public static int XS_INT = 13;
+    
+    public static int XS_DOUBLE = 14;
+    
+    public static int XS_FLOAT = 15;
+        
+    public static class OccurenceIndicator {
+       // Represents the sequence type occurrence indicator '?'
+       public static int ZERO_OR_ONE = 1;
+       
+       // Represents the sequence type occurrence indicator '*'
+       public static int ZERO_OR_MANY = 2;
+       
+       // Represents the sequence type occurrence indicator '+'
+       public static int ONE_OR_MANY = 3;
+    }
+    
+    public static String Q_MARK = "?";
+    
+    public static String STAR = "*";
+    
+    public static String PLUS = "+";
+    
+    /**
+     * This method converts/casts an xdm source value represented by an XObject
+     * object instance, to a value of another type. This method is called 
+     * recursively at certain places.
+     *  
+     * @param srcValue                     an XObject object instance that represents a
+     *                                     source xdm value. 
+     * @param sequenceTypeXPathExprStr     a string representing an XPath 3.1 sequence type,
+     *                                     conforming to which the source value srcValue needs
+     *                                     to be converted. 
+     * @param xctxt                        the current XPath context object.
+     * 
+     * @return                             an XObject object instance produced, as a result of data type 
+     *                                     conversion performed by this method on an object instance
+     *                                     srcValue.
+     *                                
+     * @throws TransformerException 
+     */
+    public static XObject convertXDMValueToAnotherType(XObject srcValue, String sequenceTypeXPathExprStr, 
+                                                                                       XPathContext xctxt) throws TransformerException {
+        XObject result = null;
+        
+        final int contextNode = xctxt.getContextNode(); 
+        
+        SourceLocator srcLocator = xctxt.getSAXLocator();
+        
+        try {
+            XPath seqTypeXPath = new XPath(sequenceTypeXPathExprStr, srcLocator, 
+                                                                            xctxt.getNamespaceContext(), XPath.SELECT, null, true);
+            
+            XObject seqTypeExpressionEvalResult = seqTypeXPath.execute(xctxt, contextNode, 
+                                                                                    xctxt.getNamespaceContext());
+            
+            SequenceTypeData seqExpectedTypeData = (SequenceTypeData)seqTypeExpressionEvalResult;
+            
+            int expectedType = seqExpectedTypeData.getSequenceType();            
+            int itemTypeOccurenceIndicator = seqExpectedTypeData.getItemTypeOccurrenceIndicator();
+            
+            if (srcValue instanceof XString) {
+                String srcStrVal = ((XString)srcValue).str();
+                
+                if (expectedType == STRING) {
+                   // The source and expected data types are same. Return the original value unchanged.
+                   result = srcValue; 
+                }
+                else {
+                   result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
+                }
+            }
+            else if (srcValue instanceof XSString) {           
+               String srcStrVal = ((XSString)srcValue).stringValue();
+               
+               if (expectedType == STRING) {
+                  // The source and expected data types are same. Return the original value unchanged.
+                  result = srcValue; 
+               }
+               else {
+                  result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
+               }
+            }
+            else if (srcValue instanceof XNumber) {
+               XSDouble xsDouble = new XSDouble(((XNumber)srcValue).num());
+               result = performXDMNumericTypeConversion(xsDouble, expectedType);
+            }
+            else if (srcValue instanceof XSNumericType) {
+               result = performXDMNumericTypeConversion((XSNumericType)srcValue, expectedType); 
+            }
+            else if (srcValue instanceof XBoolean) {
+               String srcStrVal = ((XBoolean)srcValue).str();
+               if (expectedType == BOOLEAN) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The boolean value " + srcStrVal + " cannot be "
+                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator); 
+               }
+            }
+            else if (srcValue instanceof XSBoolean) {
+               String srcStrVal = ((XSBoolean)srcValue).stringValue();
+               if (expectedType == BOOLEAN) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The boolean value " + srcStrVal + " cannot be "
+                                                                             + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator); 
+               } 
+            }
+            else if (srcValue instanceof XSDate) {
+               String srcStrVal = ((XSDate)srcValue).stringValue();
+               if (expectedType == XS_DATE) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The xs:date value " + srcStrVal + " cannot be "
+                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);   
+               } 
+            }
+            else if (srcValue instanceof XSDateTime) {
+               String srcStrVal = ((XSDateTime)srcValue).stringValue();
+               if (expectedType == XS_DATETIME) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The xs:dateTime value " + srcStrVal + " cannot be "
+                                                                                + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);     
+               } 
+            }
+            else if (srcValue instanceof XSTime) {
+               String srcStrVal = ((XSTime)srcValue).stringValue();
+               if (expectedType == XS_TIME) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The xs:time value " + srcStrVal + " cannot be "
+                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               }
+            }
+            else if (srcValue instanceof XSDuration) {
+               String srcStrVal = ((XSDuration)srcValue).stringValue();
+               if (expectedType == XS_DURATION) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The xs:duration value " + srcStrVal + " cannot be "
+                                                                                + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               } 
+            }
+            else if (srcValue instanceof XSDayTimeDuration) {
+               String srcStrVal = ((XSDayTimeDuration)srcValue).stringValue();
+               if (expectedType == XS_DAYTIME_DURATION) {
+                  result = srcValue; 
+               }
+               else {
+                  throw new TransformerException("XTTE0570 : The xs:dayTimeDuration value " + srcStrVal + " cannot be "
+                                                                                 + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               } 
+            }
+            else if (srcValue instanceof XSYearMonthDuration) {
+               String srcStrVal = ((XSYearMonthDuration)srcValue).stringValue();
+               if (expectedType == XS_YEARMONTH_DURATION) {
+                  result = srcValue; 
+               }
+               else {
+                   throw new TransformerException("XTTE0570 : The xs:yearMonthDuration value " + srcStrVal + " cannot be "
+                                                                                  + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               } 
+            }
+            else if (srcValue instanceof XSUntyped) {
+               String srcStrVal = ((XSUntyped)srcValue).stringValue();
+               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, xctxt);
+            }
+            else if (srcValue instanceof XSUntypedAtomic) {
+               String srcStrVal = ((XSUntypedAtomic)srcValue).stringValue();
+               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, xctxt);
+            }
+            else if (srcValue instanceof XNodeSet) {
+                XNodeSet xdmNodeSet = (XNodeSet)srcValue;
+                
+                int nodeSetLen = xdmNodeSet.getLength();
+                
+                if ((nodeSetLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
+                                                                                                     OccurenceIndicator.ZERO_OR_ONE))) {
+                    throw new TransformerException("XTTE0570 : A sequence of size " + nodeSetLen + ", cannot be cast to a type " 
+                                                                                                         + sequenceTypeXPathExprStr + ".", srcLocator);  
+                }
+                else { 
+                    ResultSequence convertedResultSeq = new ResultSequence();
+                    
+                    DTMIterator dtmIter = xdmNodeSet.iterRaw();
+                    
+                    int nextNodeDtmHandle;
+                           
+                    while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {               
+                       XNodeSet nodeSetItem = new XNodeSet(nextNodeDtmHandle, xctxt);
+                       String nodeStrVal = nodeSetItem.str();
+                       
+                       String sequenceTypeNewXPathExprStr = null;                    
+                       if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
+                                                                                           sequenceTypeXPathExprStr.endsWith(PLUS)) {
+                          sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
+                       }
+                       
+                       XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, xctxt);
+                       
+                       convertedResultSeq.add(xObject);
+                    }
+                    
+                    result = convertedResultSeq;
+                }
+            }
+            else if (srcValue instanceof ResultSequence) {
+                ResultSequence srcResultSeq = (ResultSequence)srcValue;
+                
+                int seqLen = srcResultSeq.size();
+                
+                if ((seqLen > 0) && (expectedType == EMPTY_SEQUENCE)) {
+                   throw new TransformerException("XTTE0570 : The sequence doesn't conform to an expected type empty-sequence(). "
+                                                                                               + "The supplied sequence has size " + seqLen + ".", srcLocator);  
+                }
+                else if ((seqLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
+                                                                                                 OccurenceIndicator.ZERO_OR_ONE))) {
+                    throw new TransformerException("XTTE0570 : A sequence of size " + seqLen + ", cannot be cast to a type " 
+                                                                                                                + sequenceTypeXPathExprStr + ".", srcLocator); 
+                }
+                else {
+                    String sequenceTypeNewXPathExprStr = null;                    
+                    if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
+                                                                                        sequenceTypeXPathExprStr.endsWith(PLUS)) {
+                       sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
+                    }
+                    
+                    ResultSequence convertedResultSeq = new ResultSequence();
+                    
+                    for (int idx = 0; idx < srcResultSeq.size(); idx++) {
+                       XObject seqItem = (XObject)(srcResultSeq.item(idx));
+                       XObject convertedSeqItem = convertXDMValueToAnotherType(seqItem, sequenceTypeNewXPathExprStr, xctxt);
+                       convertedResultSeq.add(convertedSeqItem);
+                    }
+                    
+                    result = convertedResultSeq; 
+                }
+            }
+        }
+        catch (TransformerException ex) {
+            throw new TransformerException(ex.getMessage(), srcLocator); 
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Convert a string value to an expected xdm type.
+     * 
+     * @throws TransformerException
+     */
+    private static XObject convertStringValueToAnExpectedType(String srcStrVal, int expectedType) throws TransformerException {
+        
+        XObject result = null;
+        
+        try {
+            if (expectedType == BOOLEAN) {
+               if ("0".equals(srcStrVal) || "false".equals(srcStrVal)) {
+                  result = new XSBoolean(false); 
+               }
+               else if ("1".equals(srcStrVal) || "true".equals(srcStrVal)) {
+                  result = new XSBoolean(true); 
+               }
+            }
+            else if (expectedType == XS_DATE) {
+               result = XSDate.parseDate(srcStrVal); 
+            }
+            else if (expectedType == XS_DATETIME) {
+               result = XSDateTime.parseDateTime(srcStrVal); 
+            }
+            else if (expectedType == XS_DURATION) {
+               result = XSDuration.parseDuration(srcStrVal); 
+            }
+            else if (expectedType == XS_DAYTIME_DURATION) {
+               result = XSDayTimeDuration.parseDayTimeDuration(srcStrVal); 
+            }
+            else if (expectedType == XS_YEARMONTH_DURATION) {
+               result = XSYearMonthDuration.parseYearMonthDuration(srcStrVal); 
+            }
+            else {
+               throw new TransformerException("XTTE0570 : The string value '" + srcStrVal + "' cannot be "
+                                                                                                  + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + "."); 
+            }
+        }
+        catch (Exception ex) {
+            throw new TransformerException("XTTE0570 : The string value '" + srcStrVal + "' cannot be cast to "
+                                                                                               + "a type " + getDataTypeNameFromIntValue(expectedType) + ".");
+        }
+        
+        return result;
+    }
+    
+    /**
+     * This method performs XPath numeric type conversions, and numeric type
+     * promotion as defined by XPath 3.1 spec (ref, https://www.w3.org/TR/xpath-31/#promotion).
+     */
+    private static XObject performXDMNumericTypeConversion(XSNumericType srcXsNumericType, 
+                                                                             int expectedType) throws TransformerException {
+        XObject result = null;
+        
+        String srcStrVal = srcXsNumericType.stringValue();
+        
+        try {
+            if (srcXsNumericType instanceof XSFloat) {           
+               if (expectedType == XS_FLOAT) {
+                  // The source and expected data types are same. Return the original value unchanged.
+                  result = srcXsNumericType; 
+               }
+               else if (expectedType == XS_DOUBLE) {
+                  result = new XSDouble(srcStrVal);
+               }
+            }
+            else if (srcXsNumericType instanceof XSDecimal) {           
+               if (expectedType == XS_DECIMAL) {
+                  // The source and expected data types are same. Return the original value unchanged.
+                  result = srcXsNumericType; 
+               }
+               else if (expectedType == XS_FLOAT) {
+                  result = new XSFloat(srcStrVal); 
+               }
+               else if (expectedType == XS_DOUBLE) {
+                  result = new XSDouble(srcStrVal); 
+               }
+            }
+            else if (expectedType == XS_DECIMAL) {
+               result = new XSDecimal(srcStrVal);  
+            }
+            else if (expectedType == XS_INTEGER) {
+               result = new XSInteger(srcStrVal); 
+            }
+            else if (expectedType == XS_LONG) {
+               result = new XSLong(srcStrVal); 
+            }
+            else if (expectedType == XS_INT) {
+               result = new XSInt(srcStrVal);
+            }
+            else if (expectedType == XS_DOUBLE) {
+               result = new XSDouble(srcStrVal); 
+            }
+            else if (expectedType == XS_FLOAT) {
+               result = new XSFloat(srcStrVal); 
+            }
+            else if ((srcXsNumericType.stringType()).equals(getDataTypeNameFromIntValue(expectedType))) {
+               // The source and expected data types are same. Return the original value unchanged.
+               result = srcXsNumericType;
+            }
+            else {
+               throw new TransformerException("XTTE0570 : The numeric value " + srcStrVal + " cannot be cast "
+                                                                                                 + "to a type " + getDataTypeNameFromIntValue(expectedType) + ".");  
+            }
+        }
+        catch (Exception ex) {
+            throw new TransformerException("XTTE0570 : The numeric value " + srcStrVal + " cannot be cast "
+                                                                                               + "to a type " + getDataTypeNameFromIntValue(expectedType) + ".");
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Given a primitive int value for an XDM data type, return the corresponding
+     * data type's name.
+     */
+    private static String getDataTypeNameFromIntValue(int sequenceType) {
+       
+       String dataTypeName = null;
+       
+       if (sequenceType == EMPTY_SEQUENCE) {
+          dataTypeName = "empty-sequence()";  
+       }
+       else if (sequenceType == BOOLEAN) {
+          dataTypeName = "xs:boolean"; 
+       }
+       else if (sequenceType == STRING) {
+          dataTypeName = "xs:string"; 
+       }
+       else if (sequenceType == XS_DATE) {
+          dataTypeName = "xs:date"; 
+       }
+       else if (sequenceType == XS_DATETIME) {
+          dataTypeName = "xs:dateTime";
+       }
+       else if (sequenceType == XS_TIME) {
+          dataTypeName = "xs:time"; 
+       }
+       else if (sequenceType == XS_DURATION) {
+          dataTypeName = "xs:duration"; 
+       }
+       else if (sequenceType == XS_DAYTIME_DURATION) {
+          dataTypeName = "xs:dayTimeDuration"; 
+       }
+       else if (sequenceType == XS_YEARMONTH_DURATION) {
+          dataTypeName = "xs:yearMonthDuration"; 
+       }
+       else if (sequenceType == XS_DECIMAL) {
+          dataTypeName = "xs:decimal";
+       }
+       else if (sequenceType == XS_INTEGER) {
+          dataTypeName = "xs:integer";
+       }
+       else if (sequenceType == XS_LONG) {
+          dataTypeName = "xs:long"; 
+       }
+       else if (sequenceType == XS_INT) {
+          dataTypeName = "xs:int"; 
+       }
+       else if (sequenceType == XS_DOUBLE) {
+          dataTypeName = "xs:double"; 
+       }
+       else if (sequenceType == XS_FLOAT) {
+          dataTypeName = "xs:float"; 
+       }
+       
+       return dataTypeName;       
+    }
+
+}
diff --git a/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
new file mode 100644
index 00000000..f70b3a16
--- /dev/null
+++ b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.composite;
+
+import java.util.Vector;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.XPathVisitor;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * An object of this class is, populated by an XPath parser
+ * to represent a particular XPath sequence type expression.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XPathSequenceTypeExpr extends Expression {
+
+    private static final long serialVersionUID = -7060682923984508436L;
+    
+    private int fSequenceType;
+    
+    private int fItemTypeOccurrenceIndicator;
+
+    @Override
+    public XObject execute(XPathContext xctxt) throws TransformerException {
+       SequenceTypeData sequenceTypeData = new SequenceTypeData();
+       
+       sequenceTypeData.setSequenceType(fSequenceType);
+       sequenceTypeData.setItemTypeOccurrenceIndicator(fItemTypeOccurrenceIndicator);
+       
+       return sequenceTypeData;
+    }
+
+    @Override
+    public void fixupVariables(Vector vars, int globalsSize) {
+       // NO OP  
+    }
+
+    @Override
+    public boolean deepEquals(Expression expr) {
+       // NO OP
+       return false;
+    }
+
+    public int getSequenceType() {
+        return fSequenceType;
+    }
+
+    public void setSequenceType(int sequenceType) {
+        this.fSequenceType = sequenceType;
+    }
+
+    public int getItemTypeOccurrenceIndicator() {
+        return fItemTypeOccurrenceIndicator;
+    }
+
+    public void setItemTypeOccurrenceIndicator(int itemTypeOccurrenceIndicator) {
+        this.fItemTypeOccurrenceIndicator = itemTypeOccurrenceIndicator;
+    }
+    
+    @Override
+    public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) {
+       // NO OP        
+    }
+
+}
diff --git a/src/org/apache/xpath/functions/FuncContainsToken.java b/src/org/apache/xpath/functions/FuncContainsToken.java
index a9fb644e..f337b420 100644
--- a/src/org/apache/xpath/functions/FuncContainsToken.java
+++ b/src/org/apache/xpath/functions/FuncContainsToken.java
@@ -69,8 +69,8 @@ public class FuncContainsToken extends FunctionMultiArgs {
         Expression arg2 = getArg2();
         
         if ((arg0 == null) || (arg1 == null)) {
-           // return an empty sequence, if first two mandatory arguments are not
-           // present within function call fn:contains-token. 
+           // If first two mandatory arguments are not present within function 
+           // call fn:contains-token, return an empty sequence. 
            return result; 
         }
         
@@ -133,7 +133,7 @@ public class FuncContainsToken extends FunctionMultiArgs {
            
            for (int idx1 = 0; idx1 < arg0StrList.size(); idx1++) {
               String strVal = arg0StrList.get(idx1);
-              // split this string at whitespace boundaries
+              // Split this string at whitespace boundaries
               String[] strPartsArr = strVal.split("\\s+");
               for (int idx2 = 0; idx2 < strPartsArr.length; idx2++) {
                  String strPart = strPartsArr[idx2];
diff --git a/src/org/apache/xpath/objects/XObject.java b/src/org/apache/xpath/objects/XObject.java
index 56218cee..c3d96e8e 100644
--- a/src/org/apache/xpath/objects/XObject.java
+++ b/src/org/apache/xpath/objects/XObject.java
@@ -215,6 +215,45 @@ public class XObject extends Expression implements Serializable, Cloneable
   
   /** Constant for XPath 3.1 sequence object type */
   public static final int CLASS_RESULT_SEQUENCE = 6;
+  
+  /** Constant for XPath 3.1 xs:untypedAtomic object type */
+  public static final int CLASS_XS_UNTYPED_ATOMIC = 7;
+  
+  /** Constant for XPath 3.1 xs:date object type */
+  public static final int CLASS_XS_DATE = 8;
+  
+  /** Constant for XPath 3.1 xs:dateTime object type */
+  public static final int CLASS_XS_DATETIME = 9;
+  
+  /** Constant for XPath 3.1 xs:time object type */
+  public static final int CLASS_XS_TIME = 10;
+  
+  /** Constant for XPath 3.1 xs:duration object type */
+  public static final int CLASS_XS_DURATION = 11;
+  
+  /** Constant for XPath 3.1 xs:dayTimeDuration object type */
+  public static final int CLASS_XS_DAYTIME_DURATION = 12;
+  
+  /** Constant for XPath 3.1 xs:yearMonthDuration object type */
+  public static final int CLASS_XS_YEARMONTH_DURATION = 13;
+  
+  /** Constant for XPath 3.1 xs:decimal object type */
+  public static final int CLASS_XS_DECIMAL = 14;
+  
+  /** Constant for XPath 3.1 xs:integer object type */
+  public static final int CLASS_XS_INTEGER = 15;
+  
+  /** Constant for XPath 3.1 xs:long object type */
+  public static final int CLASS_XS_LONG = 16;
+  
+  /** Constant for XPath 3.1 xs:int object type */
+  public static final int CLASS_XS_INT = 17;
+  
+  /** Constant for XPath 3.1 xs:double object type */
+  public static final int CLASS_XS_DOUBLE = 18;
+  
+  /** Constant for XPath 3.1 xs:float object type */
+  public static final int CLASS_XS_FLOAT = 19;
 
   /** Represents an unresolved variable type as an integer. */
   public static final int CLASS_UNRESOLVEDVARIABLE = 600;
diff --git a/src/org/apache/xpath/xs/types/XSBoolean.java b/src/org/apache/xpath/xs/types/XSBoolean.java
index 84fa2670..4dfcbd85 100644
--- a/src/org/apache/xpath/xs/types/XSBoolean.java
+++ b/src/org/apache/xpath/xs/types/XSBoolean.java
@@ -123,6 +123,10 @@ public class XSBoolean extends XSCtrType {
         return resultVal;  
     }
     
+    public int getType() {
+        return CLASS_BOOLEAN;
+    }
+    
     /*
      * Check whether, a string value represents a boolean 
      * 'false' value.
diff --git a/src/org/apache/xpath/xs/types/XSDate.java b/src/org/apache/xpath/xs/types/XSDate.java
index a34ca85d..90610de4 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -20,6 +20,8 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xpath.objects.ResultSequence;
 
 /**
@@ -73,7 +75,7 @@ public class XSDate extends XSCalendarType {
     public XSDate() {}
 
     @Override
-    public ResultSequence constructor(ResultSequence arg) {
+    public ResultSequence constructor(ResultSequence arg) throws TransformerException {
         ResultSequence resultSeq = new ResultSequence();
         
         if (arg.size() == 0) {
@@ -100,39 +102,55 @@ public class XSDate extends XSCalendarType {
      * @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);
+    public static XSDate parseDate(String strVal) throws TransformerException {
+        
+        XSDate result = null;
+        
+        try {
+            String dateStr = "";
+            String timeStr = "T00:00:00.0";
+    
+            int idx = strVal.indexOf('+', 1);
             if (idx == -1) {
-                return null;
+                idx = strVal.indexOf('-', 1);
+                if (idx == -1) {
+                    throw new TransformerException("XTTE0570 : The supplied string value '" + 
+                                                                         strVal + "' cannot be parsed to a xs:date value."); 
+                }
+                idx = strVal.indexOf('-', idx + 1);
+                if (idx == -1) {
+                    throw new TransformerException("XTTE0570 : The supplied string value '" + 
+                                                                         strVal + "' cannot be parsed to a xs:date value.");
+                }
+                idx = strVal.indexOf('-', idx + 1);
             }
-            idx = strVal.indexOf('-', idx + 1);
             if (idx == -1) {
-                return null;
+                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) {
+                result = new XSDate(dateTime.getCalendar(), dateTime.getTimezone());;
+            }
+            else {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + 
+                                                                                  strVal + "' cannot be parsed to a xs:date value."); 
             }
-            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;
+        catch (Exception ex) {
+            throw new TransformerException("XTTE0570 : The supplied string value '" + 
+                                                                                  strVal + "' cannot be parsed to a xs:date value."); 
         }
-
-        return new XSDate(dateTime.getCalendar(), dateTime.getTimezone());
+        
+        return result;
         
     }
     
@@ -296,11 +314,15 @@ public class XSDate extends XSCalendarType {
         this.isPopulatedFromFnCurrentDate = isPopulatedFromFnCurrentDate;
     }
     
+    public int getType() {
+        return CLASS_XS_DATE;
+    }
+    
     /*
      * Do a data type cast, of an XSAnyType argument passed to this method, to
      * an XSDate object.
      */
-    private XSDate castToDate(XSAnyType xsAnyType) {
+    private XSDate castToDate(XSAnyType xsAnyType) throws TransformerException {
         if (xsAnyType instanceof XSDate) {
             XSDate date = (XSDate) xsAnyType;
             return new XSDate(date.getCalendar(), date.getTimezone());
diff --git a/src/org/apache/xpath/xs/types/XSDateTime.java b/src/org/apache/xpath/xs/types/XSDateTime.java
index e601ccf2..294a6c1c 100644
--- a/src/org/apache/xpath/xs/types/XSDateTime.java
+++ b/src/org/apache/xpath/xs/types/XSDateTime.java
@@ -23,6 +23,8 @@ import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xpath.objects.ResultSequence;
 
 /**
@@ -382,99 +384,116 @@ public class XSDateTime extends XSCalendarType {
      * @return          the XSDateTime representation of the date and time (with an 
      *                  optional timezone value)
      */
-    public static XSDateTime parseDateTime(String strVal) {
+    public static XSDateTime parseDateTime(String strVal) throws TransformerException {
         
         XSDateTime xsDateTime = null;
 
-        int idx = strVal.indexOf('T');
-        if (idx == -1) {
-            return null;
-        }
-
-        String date = strVal.substring(0, idx);
-        String time = strVal.substring(idx + 1, strVal.length());
-        String timezone = null;
-
-        idx = time.indexOf('+');
-        if (idx == -1) {
-            idx = time.indexOf('-');
-        }
-        if (idx == -1) {
-            idx = time.indexOf('Z');
-        }
-        if (idx != -1) {
-            timezone = time.substring(idx, time.length());
-            time = time.substring(0, idx);
-        }
-
-        int d[] = parseDate(date);
-        if (d == null) {
-            return null;
-        }
-
-        TimeZone defaultTimezone = TimeZone.getDefault();
-        GregorianCalendar gregorianCalendarObj = new GregorianCalendar(
-                                                                 defaultTimezone);
-
-        int year = d[0];
-        if (year < 0) {
-            year *= -1;
-            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.BC);
-        } else {
-            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.AD);
-        }
-
-        gregorianCalendarObj.set(Calendar.DAY_OF_MONTH, 2);
-        gregorianCalendarObj.set(Calendar.MONTH, 2);
-
-        if (!setItem(gregorianCalendarObj, Calendar.YEAR, year)) {
-            return null;
-        }
-
-        if (!setItem(gregorianCalendarObj, Calendar.MONTH, d[1] - 1)) {
-            return null;
-        }
-
-        if (!setItem(gregorianCalendarObj, Calendar.DAY_OF_MONTH, d[2])) {
-            return null;
-        }
-
-        double t[] = parseTime(time);
-        if (t == null) {
-            return null;
-        }
-
-        if (!setItem(gregorianCalendarObj, Calendar.HOUR_OF_DAY, (int) t[0])) {
-            return null;
-        }
-
-        if (!setItem(gregorianCalendarObj, Calendar.MINUTE, (int) t[1])) {
-            return null;
-        }
-
-        if (!setItem(gregorianCalendarObj, Calendar.SECOND, (int) t[2])) {
-            return null;
-        }
-
-        double ms = t[2] - ((int) t[2]);
-        ms *= 1000;
-        if (!setItem(gregorianCalendarObj, Calendar.MILLISECOND, (int) ms)) {
-            return null;
-        }
-
-        int tz[] = null;
-        XSDuration timezoneVal = null;
-        if (timezone != null) {
-            tz = parseTimezone(timezone);
-
-            if (tz == null) {
-                return null;
+        try {
+            int idx = strVal.indexOf('T');
+            if (idx == -1) {
+               throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                  + "cannot be parsed to a xs:dateTime value.");
             }
-
-            timezoneVal = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
+    
+            String date = strVal.substring(0, idx);
+            String time = strVal.substring(idx + 1, strVal.length());
+            String timezone = null;
+    
+            idx = time.indexOf('+');
+            if (idx == -1) {
+                idx = time.indexOf('-');
+            }
+            if (idx == -1) {
+                idx = time.indexOf('Z');
+            }
+            if (idx != -1) {
+                timezone = time.substring(idx, time.length());
+                time = time.substring(0, idx);
+            }
+    
+            int d[] = parseDate(date);
+            if (d == null) {
+               throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                             + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            TimeZone defaultTimezone = TimeZone.getDefault();
+            GregorianCalendar gregorianCalendarObj = new GregorianCalendar(
+                                                                     defaultTimezone);
+    
+            int year = d[0];
+            if (year < 0) {
+                year *= -1;
+                gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.BC);
+            } else {
+                gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.AD);
+            }
+    
+            gregorianCalendarObj.set(Calendar.DAY_OF_MONTH, 2);
+            gregorianCalendarObj.set(Calendar.MONTH, 2);
+    
+            if (!setItem(gregorianCalendarObj, Calendar.YEAR, year)) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            if (!setItem(gregorianCalendarObj, Calendar.MONTH, d[1] - 1)) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            if (!setItem(gregorianCalendarObj, Calendar.DAY_OF_MONTH, d[2])) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            double t[] = parseTime(time);
+            if (t == null) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            if (!setItem(gregorianCalendarObj, Calendar.HOUR_OF_DAY, (int) t[0])) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            if (!setItem(gregorianCalendarObj, Calendar.MINUTE, (int) t[1])) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            if (!setItem(gregorianCalendarObj, Calendar.SECOND, (int) t[2])) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            double ms = t[2] - ((int) t[2]);
+            ms *= 1000;
+            if (!setItem(gregorianCalendarObj, Calendar.MILLISECOND, (int) ms)) {
+                throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:dateTime value.");
+            }
+    
+            int tz[] = null;
+            XSDuration timezoneVal = null;
+            if (timezone != null) {
+                tz = parseTimezone(timezone);
+    
+                if (tz == null) {
+                   throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                 + "cannot be parsed to a xs:dateTime value.");
+                }
+    
+                timezoneVal = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
+            }
+            
+            xsDateTime = new XSDateTime(gregorianCalendarObj, timezoneVal);
+        }
+        catch (Exception ex) {
+            throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                               + "cannot be parsed to a xs:dateTime value."); 
         }
-        
-        xsDateTime = new XSDateTime(gregorianCalendarObj, timezoneVal); 
 
         return xsDateTime;
     }
@@ -599,6 +618,10 @@ public class XSDateTime extends XSCalendarType {
         return returnVal;
     }
     
+    public int getType() {
+        return CLASS_XS_DATETIME;
+    }
+    
     /**
      * Set a particular field within an java.util.Calendar object.
      * 
diff --git a/src/org/apache/xpath/xs/types/XSDayTimeDuration.java b/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
index 625558ea..3c923c7f 100644
--- a/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
+++ b/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
@@ -77,8 +77,10 @@ public class XSDayTimeDuration extends XSDuration {
 	 * A method to construct an xdm sequence comprising a
 	 * xs:dayTimeDuration value, given input data as argument
 	 * to this method.
+	 * 
+	 * @throws TransformerException 
 	 */
-	public ResultSequence constructor(ResultSequence arg) {
+	public ResultSequence constructor(ResultSequence arg) throws TransformerException {
         ResultSequence resultSeq = new ResultSequence();
         
         if (arg.size() == 0) {
@@ -104,8 +106,10 @@ public class XSDayTimeDuration extends XSDuration {
 	 * @return               new XSDuration object, representing the 
 	 *                       supplied string.
 	 */
-	public static XSDuration parseDayTimeDuration(String strVal) {
-		boolean negative = false;
+	public static XSDuration parseDayTimeDuration(String strVal) throws TransformerException {
+		
+	    boolean isDurationNegative = false;
+		
 		int days = 0;
 		int hours = 0;
 		int minutes = 0;
@@ -115,13 +119,14 @@ public class XSDayTimeDuration extends XSDuration {
 		String tstr = null;
 
 		if (strVal.startsWith("-P")) {
-			negative = true;
+			isDurationNegative = true;
 			pstr = strVal.substring(2, strVal.length());
 		} else if (strVal.startsWith("P")) {
-			negative = false;
+			isDurationNegative = false;
 			pstr = strVal.substring(1, strVal.length());
 		} else {
-			return null;
+		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                          + "cannot be parsed to a xs:dayTimeDuration value.");
 		}
 
 		try {
@@ -132,7 +137,8 @@ public class XSDayTimeDuration extends XSDuration {
 				if (pstr.startsWith("T")) {
 					tstr = pstr.substring(1, pstr.length());
 				} else {
-					return null;
+				    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                  + "cannot be parsed to a xs:dayTimeDuration value.");
 				}
 			} else {
 				String digit = pstr.substring(0, index);
@@ -143,7 +149,8 @@ public class XSDayTimeDuration extends XSDuration {
 					tstr = tstr.substring(1, tstr.length());
 				} else {
 					if (tstr.length() > 0) {
-						return null;
+					   throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                     + "cannot be parsed to a xs:dayTimeDuration value.");
 					}
 					tstr = "";
 					actionStatus = true;
@@ -175,17 +182,19 @@ public class XSDayTimeDuration extends XSDuration {
 			}
 			if (actionStatus) {
 				if (tstr.length() != 0) {
-					return null;
+				    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                  + "cannot be parsed to a xs:dayTimeDuration value.");
 				}
 			} else {
-				return null;
+			    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                     + "cannot be parsed to a xs:dayTimeDuration value.");
 			}
-
-		} catch (NumberFormatException err) {
-			return null;
+		} catch (Exception ex) {
+		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                          + "cannot be parsed to a xs:dayTimeDuration value.");
 		}
 
-		return new XSDayTimeDuration(days, hours, minutes, seconds, negative);
+		return new XSDayTimeDuration(days, hours, minutes, seconds, isDurationNegative);
 	}
 
 	/**
@@ -309,13 +318,17 @@ public class XSDayTimeDuration extends XSDuration {
         
         return result;
     }
+    
+    public int getType() {
+        return CLASS_XS_DAYTIME_DURATION;
+    }
 	
 	/**
      * Do a data type cast, of a XSAnyType value to an XSDuration
      * value. 
+	 * @throws TransformerException 
      */
-	private XSDuration castToDayTimeDuration(XSAnyType xsAnyType) {
-        
+	private XSDuration castToDayTimeDuration(XSAnyType xsAnyType) throws TransformerException {        
 	    if (xsAnyType instanceof XSDuration) {
             XSDuration xsDuration = (XSDuration) xsAnyType;
             
diff --git a/src/org/apache/xpath/xs/types/XSDecimal.java b/src/org/apache/xpath/xs/types/XSDecimal.java
index e1cdb9f6..0bde3457 100644
--- a/src/org/apache/xpath/xs/types/XSDecimal.java
+++ b/src/org/apache/xpath/xs/types/XSDecimal.java
@@ -145,6 +145,10 @@ public class XSDecimal extends XSNumericType {
         return (_value.compareTo(xsDecimal.getValue()) == 1);
     }
     
+    public int getType() {
+        return CLASS_XS_DECIMAL;
+    }
+    
     /*
      * 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 2cc8fff2..455cb0f8 100644
--- a/src/org/apache/xpath/xs/types/XSDouble.java
+++ b/src/org/apache/xpath/xs/types/XSDouble.java
@@ -204,4 +204,8 @@ public class XSDouble extends XSNumericType {
         return doubleValue() > xsDouble.doubleValue(); 
     }
     
+    public int getType() {
+        return CLASS_XS_DOUBLE;
+    }
+    
 }
diff --git a/src/org/apache/xpath/xs/types/XSDuration.java b/src/org/apache/xpath/xs/types/XSDuration.java
index 81656f5f..88bff6ab 100644
--- a/src/org/apache/xpath/xs/types/XSDuration.java
+++ b/src/org/apache/xpath/xs/types/XSDuration.java
@@ -297,12 +297,14 @@ public class XSDuration extends XSCtrType {
 	/**
 	 * Construct a new XSDuration object, by parsing the supplied string.
 	 * 
-	 * @param str   string to be parsed
+	 * @param strVal   string to be parsed
 	 * 
 	 * @return      XSDuration object representing the duration of time supplied
 	 */
-	public static XSDuration parseDuration(String str) throws TransformerException {
-		boolean negative = false;
+	public static XSDuration parseDuration(String strVal) throws TransformerException {
+		
+	    boolean isDurationNegative = false;
+		
 		int years = 0;
 		int months = 0;
 		int days = 0;
@@ -313,14 +315,15 @@ public class XSDuration extends XSCtrType {
 		String pstr = "";
 		String tstr = "";
 
-		if (str.startsWith("-P")) {
-			negative = true;
-			pstr = str.substring(2, str.length());
-		} else if (str.startsWith("P")) {
-			negative = false;
-			pstr = str.substring(1, str.length());
+		if (strVal.startsWith("-P")) {
+			isDurationNegative = true;
+			pstr = strVal.substring(2, strVal.length());
+		} else if (strVal.startsWith("P")) {
+			isDurationNegative = false;
+			pstr = strVal.substring(1, strVal.length());
 		} else {
-			return null;
+		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+		                                                                                         + "cannot be parsed to a xs:duration value.");
 		}
 
 		try {
@@ -387,15 +390,16 @@ public class XSDuration extends XSCtrType {
 				isAction = true;
 			}
 			if (!isAction) {
-				return null;
+			    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                               + "cannot be parsed to a xs:duration value.");
 			}
 
-		} catch (NumberFormatException ex) {
-			throw new TransformerException("FORG0001 : The provided string, cannot be parsed "
-			                                                                   + "to a xs:duration value."); 
+		} catch (Exception ex) {
+		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                              + "cannot be parsed to a xs:duration value."); 
 		}
 
-		return new XSDuration(years, months, days, hours, minutes, seconds, negative);
+		return new XSDuration(years, months, days, hours, minutes, seconds, isDurationNegative);
 	}
 
 	/**
@@ -449,6 +453,10 @@ public class XSDuration extends XSCtrType {
        return val1 > val2;
     }
     
+    public int getType() {
+        return CLASS_XS_DURATION;
+    }
+    
     /**
      * Do a data type cast, of a XSAnyType value to an XSDuration
      * value.
diff --git a/src/org/apache/xpath/xs/types/XSFloat.java b/src/org/apache/xpath/xs/types/XSFloat.java
index fb935958..d584ad89 100644
--- a/src/org/apache/xpath/xs/types/XSFloat.java
+++ b/src/org/apache/xpath/xs/types/XSFloat.java
@@ -195,4 +195,8 @@ public class XSFloat extends XSNumericType {
 	    return floatValue() > xsFloat.floatValue(); 
     }
 	
+    public int getType() {
+        return CLASS_XS_FLOAT;
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInt.java b/src/org/apache/xpath/xs/types/XSInt.java
index 7f93a0ac..7d250dd1 100644
--- a/src/org/apache/xpath/xs/types/XSInt.java
+++ b/src/org/apache/xpath/xs/types/XSInt.java
@@ -106,4 +106,8 @@ public class XSInt extends XSLong {
 	    return _value.compareTo(xsInt.intValue()) > 0; 
     }
 	
+    public int getType() {
+        return CLASS_XS_INT;
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInteger.java b/src/org/apache/xpath/xs/types/XSInteger.java
index 48b8b420..a810bea5 100644
--- a/src/org/apache/xpath/xs/types/XSInteger.java
+++ b/src/org/apache/xpath/xs/types/XSInteger.java
@@ -144,6 +144,10 @@ public class XSInteger extends XSDecimal {
 	    return new XSInteger((intValue()).multiply(xsInteger.intValue()));   
 	}
 	
+    public int getType() {
+        return CLASS_XS_INTEGER;
+    }
+	
 	/*
      * Cast an object of type XSAnyType, to an object of type 
      * java.math.BigInteger.  
diff --git a/src/org/apache/xpath/xs/types/XSLong.java b/src/org/apache/xpath/xs/types/XSLong.java
index e1e7032d..c5f93538 100644
--- a/src/org/apache/xpath/xs/types/XSLong.java
+++ b/src/org/apache/xpath/xs/types/XSLong.java
@@ -104,5 +104,9 @@ public class XSLong extends XSInteger {
 	public boolean gt(XSLong xsLong) {
 	    return _value.compareTo(xsLong.intValue()) > 0; 
     }
+	
+    public int getType() {
+        return CLASS_XS_LONG;
+    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSString.java b/src/org/apache/xpath/xs/types/XSString.java
index 77b29ce5..3b82cdbb 100644
--- a/src/org/apache/xpath/xs/types/XSString.java
+++ b/src/org/apache/xpath/xs/types/XSString.java
@@ -123,5 +123,9 @@ public class XSString extends XSCtrType {
                                                                                                        fXctxt.getDefaultCollation());
         return (comparisonResult > 0);  
     }
+    
+    public int getType() {
+        return CLASS_STRING;
+    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSTime.java b/src/org/apache/xpath/xs/types/XSTime.java
index e5c46d5b..ab7d770c 100644
--- a/src/org/apache/xpath/xs/types/XSTime.java
+++ b/src/org/apache/xpath/xs/types/XSTime.java
@@ -186,5 +186,9 @@ public class XSTime extends XSCalendarType {
 
          return returnVal;
     }
+    
+    public int getType() {
+        return CLASS_XS_TIME;
+    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSUntyped.java b/src/org/apache/xpath/xs/types/XSUntyped.java
index c0f3257e..4b895979 100644
--- a/src/org/apache/xpath/xs/types/XSUntyped.java
+++ b/src/org/apache/xpath/xs/types/XSUntyped.java
@@ -33,7 +33,7 @@ public class XSUntyped extends XSAnyType {
 
     private static final long serialVersionUID = 6146147730252441632L;
     
-    private static final String XS_UNTYPED = "untyped";
+    private static final String XS_UNTYPED = "xs:untyped";
     
     private String _value;
     
diff --git a/src/org/apache/xpath/xs/types/XSUntypedAtomic.java b/src/org/apache/xpath/xs/types/XSUntypedAtomic.java
index 7ef347d1..d61bee2f 100644
--- a/src/org/apache/xpath/xs/types/XSUntypedAtomic.java
+++ b/src/org/apache/xpath/xs/types/XSUntypedAtomic.java
@@ -34,7 +34,7 @@ public class XSUntypedAtomic extends XSCtrType {
 
     private static final long serialVersionUID = 3034074443706977457L;
     
-    private static final String XS_UNTYPED_ATOMIC = "untypedAtomic";
+    private static final String XS_UNTYPED_ATOMIC = "xs:untypedAtomic";
     
     private String _value;
     
diff --git a/src/org/apache/xpath/xs/types/XSYearMonthDuration.java b/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
index f143b34e..5bf937ac 100644
--- a/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
+++ b/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
@@ -76,8 +76,9 @@ public class XSYearMonthDuration extends XSDuration {
      * @return           new XSYearMonthDuration object, representing the
      *                   duration of time supplied.
      */
-    public static XSDuration parseYearMonthDuration(String strVal) {
-        boolean negative = false;
+    public static XSDuration parseYearMonthDuration(String strVal) throws TransformerException {
+        
+        boolean isDurationNegative = false;
         
         int year = 0;
         int month = 0;
@@ -86,80 +87,97 @@ public class XSYearMonthDuration extends XSDuration {
 
         String digits = "";
         
-        for (int idx = 0; idx < strVal.length(); idx++) {
-            char charVal = strVal.charAt(idx);
-
-            switch (moveAheadIndication) {
-            case 0:
-                if (charVal == '-') {
-                   negative = true;
-                   moveAheadIndication = 4;
-                } else if (charVal == 'P') {
-                   moveAheadIndication = 5;
-                }
-                else {
-                   return null;
-                }
-                break;
-            case 4:
-                if (charVal == 'P') {
-                   moveAheadIndication = 5;
-                }
-                else {
-                   return null;
-                }
-                break;
-            case 5:
-                if ('0' <= charVal && charVal <= '9') {
-                   digits += charVal;
-                }
-                else if (charVal == 'Y') {
-                    if (digits.length() == 0) {
-                       return null;
+        try {
+            for (int idx = 0; idx < strVal.length(); idx++) {
+                char charVal = strVal.charAt(idx);
+    
+                switch (moveAheadIndication) {
+                case 0:
+                    if (charVal == '-') {
+                       isDurationNegative = true;
+                       moveAheadIndication = 4;
+                    } else if (charVal == 'P') {
+                       moveAheadIndication = 5;
                     }
-                    year = Integer.parseInt(digits);
-                    digits = "";
-                    moveAheadIndication = 6;
-                } else if (charVal == 'M') {
-                    if (digits.length() == 0) {
-                       return null;
+                    else {
+                       throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                          + "cannot be parsed to a xs:yearMonthDuration value.");
                     }
-                    month = Integer.parseInt(digits);
-                    moveAheadIndication = 7;
-                } else {
-                    return null;
-                }
-                break;
-            case 6:
-               if ('0' <= charVal && charVal <= '9') {
-                  digits += charVal;
-               }
-               else if (charVal == 'M') {
-                  if (digits.length() == 0) {
-                     return null;
-                  }
-                  month = Integer.parseInt(digits);
-                  moveAheadIndication = 7;
-                } else {
-                    return null;
+                    break;
+                case 4:
+                    if (charVal == 'P') {
+                       moveAheadIndication = 5;
+                    }
+                    else {
+                       throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                      + "cannot be parsed to a xs:yearMonthDuration value.");
+                    }
+                    break;
+                case 5:
+                    if ('0' <= charVal && charVal <= '9') {
+                       digits += charVal;
+                    }
+                    else if (charVal == 'Y') {
+                        if (digits.length() == 0) {
+                           throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                         + "cannot be parsed to a xs:yearMonthDuration value.");
+                        }
+                        year = Integer.parseInt(digits);
+                        digits = "";
+                        moveAheadIndication = 6;
+                    } else if (charVal == 'M') {
+                        if (digits.length() == 0) {
+                           throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                         + "cannot be parsed to a xs:yearMonthDuration value.");
+                        }
+                        month = Integer.parseInt(digits);
+                        moveAheadIndication = 7;
+                    } else {
+                        throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                      + "cannot be parsed to a xs:yearMonthDuration value.");
+                    }
+                    break;
+                case 6:
+                   if ('0' <= charVal && charVal <= '9') {
+                      digits += charVal;
+                   }
+                   else if (charVal == 'M') {
+                      if (digits.length() == 0) {
+                         throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                        + "cannot be parsed to a xs:yearMonthDuration value.");
+                      }
+                      month = Integer.parseInt(digits);
+                      moveAheadIndication = 7;
+                    } else {
+                        throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                      + "cannot be parsed to a xs:yearMonthDuration value.");
+                    }
+                    break;
+                case 7:
+                    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                  + "cannot be parsed to a xs:yearMonthDuration value.");
+                default:
+                    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                                  + "cannot be parsed to a xs:yearMonthDuration value.");
                 }
-                break;
-            case 7:
-               return null;
-            default:
-               return null;
             }
         }
+        catch (Exception ex) {
+           throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
+                                                                                         + "cannot be parsed to a xs:yearMonthDuration value."); 
+        }
 
-        return new XSYearMonthDuration(year, month, negative);
+        return new XSYearMonthDuration(year, month, isDurationNegative);
     }
 
     /**
      * A method to construct an xdm sequence comprising a
      * xs:yearMonthDuration value, given input data as argument
      * to this method.
+     * 
+     * @throws TransformerException 
      */
-	public ResultSequence constructor(ResultSequence arg) {
+	public ResultSequence constructor(ResultSequence arg) throws TransformerException {
         ResultSequence resultSeq = new ResultSequence();
         
         if (arg.size() == 0) {
@@ -378,11 +396,17 @@ public class XSYearMonthDuration extends XSDuration {
         return result; 
     }
     
+    public int getType() {
+        return CLASS_XS_YEARMONTH_DURATION;
+    }
+    
     /**
      * Do a data type cast, of a XSAnyType value to an XSDuration
-     * value. 
+     * value.
+     *  
+     * @throws TransformerException 
      */
-    private XSDuration castToYearMonthDuration(XSAnyType xsAnyType) {
+    private XSDuration castToYearMonthDuration(XSAnyType xsAnyType) throws TransformerException {
         if (xsAnyType instanceof XSDuration) {
            XSDuration xsDuration = (XSDuration) xsAnyType;
            
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 9153e9b6..1a6272a5 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -91,7 +91,8 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
                 FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
-                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class })
+                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class,
+                XslAttributeAsTests.class })
 public class AllXsl3Tests {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java b/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java
new file mode 100644
index 00000000..4b737931
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XslTestsErrorHandler;
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSLT test cases, to test the sequence type declaration
+ * attribute "as" within stylesheets.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XslAttributeAsTests extends XslTransformTestsUtil {
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+                                                                                                         + "xsl_attribute_as/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+                                                                                                         + "xsl_attribute_as/gold/";      
+
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslAttributeAsTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslAttributeAsTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslAttributeAsTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
+                                                                           new XslTestsErrorHandler());   
+    }
+
+}
diff --git a/tests/xsl_attribute_as/gold/test1.out b/tests/xsl_attribute_as/gold/test1.out
new file mode 100644
index 00000000..906155c5
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test1.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <info val="2005-10-12">
+    <lessThanCurrentDate/>
+  </info>
+  <info val="2501-10-12">
+    <currentDateOrAfter/>
+  </info>
+</result>
diff --git a/tests/xsl_attribute_as/gold/test2.out b/tests/xsl_attribute_as/gold/test2.out
new file mode 100644
index 00000000..ec66c00c
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test2.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>2007-10-05</one>
+  <two>2003-10-05</two>
+</result>
diff --git a/tests/xsl_attribute_as/gold/test3.out b/tests/xsl_attribute_as/gold/test3.out
new file mode 100644
index 00000000..80c0df0a
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test3.out
@@ -0,0 +1 @@
+<unused/>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test1.xsl b/tests/xsl_attribute_as/test1.xsl
new file mode 100644
index 00000000..2297f8ba
--- /dev/null
+++ b/tests/xsl_attribute_as/test1.xsl
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 -->                
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="('2005-10-12', '2501-10-12')" as="xs:date*"/>
+        
+    <xsl:template match="/">       
+       <result>
+	      <xsl:for-each select="$seq1">
+	         <xsl:variable name="currentDtVal" select="."/>
+	         <info val="{$currentDtVal}">
+	            <xsl:choose>
+	               <xsl:when test="$currentDtVal lt current-date()">
+	                  <lessThanCurrentDate/>
+	               </xsl:when>
+	               <xsl:otherwise>
+	                  <currentDateOrAfter/>
+	               </xsl:otherwise>
+	            </xsl:choose>
+	         </info>
+	      </xsl:for-each>
+       </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>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test1_a.xml b/tests/xsl_attribute_as/test1_a.xml
new file mode 100644
index 00000000..ae54f574
--- /dev/null
+++ b/tests/xsl_attribute_as/test1_a.xml
@@ -0,0 +1,7 @@
+<info>
+  <val>2005-10-05</val>
+  <val>2007-10-05</val>
+  <val>2005-10-05</val>
+  <val>2003-10-05</val>
+  <val>2005-10-05</val>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test2.xsl b/tests/xsl_attribute_as/test2.xsl
new file mode 100644
index 00000000..d33690c8
--- /dev/null
+++ b/tests/xsl_attribute_as/test2.xsl
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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_a.xml -->               
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="var1" select="/info/val" as="xs:date*"/>
+        
+    <xsl:template match="/">       
+       <result>
+          <one>
+             <xsl:value-of select="max($var1)"/>
+          </one>
+          <two>
+	         <xsl:value-of select="min($var1)"/>
+          </two>
+       </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>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test3.xsl b/tests/xsl_attribute_as/test3.xsl
new file mode 100644
index 00000000..99797a60
--- /dev/null
+++ b/tests/xsl_attribute_as/test3.xsl
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 -->                
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+         
+         This stylesheet produces an XSLT transformation error,
+         because the XPath 3.1 function conversion rules don't allow
+         xs:string values to be converted to numeric types (like
+         xs:integer as mentioned within this example).
+    -->
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="var1" select="'4'" as="xs:integer"/>
+        
+    <xsl:template match="/">       
+       <result>
+          <xsl:value-of select="$var1"/>
+       </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>
\ 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